##// END OF EJS Templates
dependencies: bumped test libraries.
marcink -
r3951:041016db default
parent child Browse files
Show More
@@ -0,0 +1,47 b''
1 import collections
2 # -*- coding: utf-8 -*-
3
4 # Copyright (C) 2010-2019 RhodeCode GmbH
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License, version 3
8 # (only), as published by the Free Software Foundation.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #
18 # This program is dual-licensed. If you wish to learn more about the
19 # RhodeCode Enterprise Edition, including its added features, Support services,
20 # and proprietary license terms, please see https://rhodecode.com/licenses/
21
22 import pytest
23
24 from rhodecode.lib import audit_logger
25
26
27 @pytest.mark.parametrize('store_type', [
28 'store_web',
29 'store_api'
30 ])
31 @pytest.mark.parametrize('action, kwargs', [
32 ('repo.edit', {
33 'user': audit_logger.UserWrap(username='test-audit-log', ip_addr='8.8.8.8'),
34 'action_data': {'data': {'hello': 'world'}}
35 }),
36 ('repo.edit', {
37 'user': audit_logger.UserWrap(username=u'marcinkuΕΌmiΕ„', ip_addr='8.8.8.8'),
38 'action_data': {'data': {'hello': u'Δ…Δ™ΕΌΔ…βˆ‘Δ™Δ«Β¨Β¨Δ·Β©'}}
39 }),
40 ('repo.edit', {
41 'user': audit_logger.UserWrap(username='marcinkuΕΌmiΕ„', ip_addr='8.8.8.8'),
42 'action_data': {'data': {'hello': 'Δ…Δ™ΕΌΔ…βˆ‘Δ™Δ«Β¨Β¨Δ·Β©'}}
43 }),
44 ])
45 def test_store_audit_log(app, store_type, action, kwargs):
46 store_action = getattr(audit_logger, store_type)
47 store_action(action, **kwargs)
@@ -1,2378 +1,2385 b''
1 # Generated by pip2nix 0.8.0.dev1
1 # Generated by pip2nix 0.8.0.dev1
2 # See https://github.com/johbo/pip2nix
2 # See https://github.com/johbo/pip2nix
3
3
4 { pkgs, fetchurl, fetchgit, fetchhg }:
4 { pkgs, fetchurl, fetchgit, fetchhg }:
5
5
6 self: super: {
6 self: super: {
7 "alembic" = super.buildPythonPackage {
7 "alembic" = super.buildPythonPackage {
8 name = "alembic-1.0.10";
8 name = "alembic-1.0.10";
9 doCheck = false;
9 doCheck = false;
10 propagatedBuildInputs = [
10 propagatedBuildInputs = [
11 self."sqlalchemy"
11 self."sqlalchemy"
12 self."mako"
12 self."mako"
13 self."python-editor"
13 self."python-editor"
14 self."python-dateutil"
14 self."python-dateutil"
15 ];
15 ];
16 src = fetchurl {
16 src = fetchurl {
17 url = "https://files.pythonhosted.org/packages/6e/8b/fa3bd058cccd5e9177fea4efa26bfb769228fdd3178436ad5e05830ef6ef/alembic-1.0.10.tar.gz";
17 url = "https://files.pythonhosted.org/packages/6e/8b/fa3bd058cccd5e9177fea4efa26bfb769228fdd3178436ad5e05830ef6ef/alembic-1.0.10.tar.gz";
18 sha256 = "1dwl0264r6ri2jyrjr68am04x538ab26xwy4crqjnnhm4alwm3c2";
18 sha256 = "1dwl0264r6ri2jyrjr68am04x538ab26xwy4crqjnnhm4alwm3c2";
19 };
19 };
20 meta = {
20 meta = {
21 license = [ pkgs.lib.licenses.mit ];
21 license = [ pkgs.lib.licenses.mit ];
22 };
22 };
23 };
23 };
24 "amqp" = super.buildPythonPackage {
24 "amqp" = super.buildPythonPackage {
25 name = "amqp-2.5.1";
25 name = "amqp-2.5.1";
26 doCheck = false;
26 doCheck = false;
27 propagatedBuildInputs = [
27 propagatedBuildInputs = [
28 self."vine"
28 self."vine"
29 ];
29 ];
30 src = fetchurl {
30 src = fetchurl {
31 url = "https://files.pythonhosted.org/packages/b5/f5/70e364a1f5fbafc742c098ad88a064b801b0d69cf56bfad13be2c08be4e2/amqp-2.5.1.tar.gz";
31 url = "https://files.pythonhosted.org/packages/b5/f5/70e364a1f5fbafc742c098ad88a064b801b0d69cf56bfad13be2c08be4e2/amqp-2.5.1.tar.gz";
32 sha256 = "0s2yxnnhhx9hww0n33yn22q6sgnbd6n2nw92050qv2qpc3i1ga8r";
32 sha256 = "0s2yxnnhhx9hww0n33yn22q6sgnbd6n2nw92050qv2qpc3i1ga8r";
33 };
33 };
34 meta = {
34 meta = {
35 license = [ pkgs.lib.licenses.bsdOriginal ];
35 license = [ pkgs.lib.licenses.bsdOriginal ];
36 };
36 };
37 };
37 };
38 "appenlight-client" = super.buildPythonPackage {
38 "appenlight-client" = super.buildPythonPackage {
39 name = "appenlight-client-0.6.26";
39 name = "appenlight-client-0.6.26";
40 doCheck = false;
40 doCheck = false;
41 propagatedBuildInputs = [
41 propagatedBuildInputs = [
42 self."webob"
42 self."webob"
43 self."requests"
43 self."requests"
44 self."six"
44 self."six"
45 ];
45 ];
46 src = fetchurl {
46 src = fetchurl {
47 url = "https://files.pythonhosted.org/packages/2e/56/418fc10379b96e795ee39a15e69a730c222818af04c3821fa354eaa859ec/appenlight_client-0.6.26.tar.gz";
47 url = "https://files.pythonhosted.org/packages/2e/56/418fc10379b96e795ee39a15e69a730c222818af04c3821fa354eaa859ec/appenlight_client-0.6.26.tar.gz";
48 sha256 = "0s9xw3sb8s3pk73k78nnq4jil3q4mk6bczfa1fmgfx61kdxl2712";
48 sha256 = "0s9xw3sb8s3pk73k78nnq4jil3q4mk6bczfa1fmgfx61kdxl2712";
49 };
49 };
50 meta = {
50 meta = {
51 license = [ pkgs.lib.licenses.bsdOriginal ];
51 license = [ pkgs.lib.licenses.bsdOriginal ];
52 };
52 };
53 };
53 };
54 "asn1crypto" = super.buildPythonPackage {
54 "asn1crypto" = super.buildPythonPackage {
55 name = "asn1crypto-0.24.0";
55 name = "asn1crypto-0.24.0";
56 doCheck = false;
56 doCheck = false;
57 src = fetchurl {
57 src = fetchurl {
58 url = "https://files.pythonhosted.org/packages/fc/f1/8db7daa71f414ddabfa056c4ef792e1461ff655c2ae2928a2b675bfed6b4/asn1crypto-0.24.0.tar.gz";
58 url = "https://files.pythonhosted.org/packages/fc/f1/8db7daa71f414ddabfa056c4ef792e1461ff655c2ae2928a2b675bfed6b4/asn1crypto-0.24.0.tar.gz";
59 sha256 = "0jaf8rf9dx1lf23xfv2cdd5h52f1qr3w8k63985bc35g3d220p4x";
59 sha256 = "0jaf8rf9dx1lf23xfv2cdd5h52f1qr3w8k63985bc35g3d220p4x";
60 };
60 };
61 meta = {
61 meta = {
62 license = [ pkgs.lib.licenses.mit ];
62 license = [ pkgs.lib.licenses.mit ];
63 };
63 };
64 };
64 };
65 "atomicwrites" = super.buildPythonPackage {
65 "atomicwrites" = super.buildPythonPackage {
66 name = "atomicwrites-1.2.1";
66 name = "atomicwrites-1.2.1";
67 doCheck = false;
67 doCheck = false;
68 src = fetchurl {
68 src = fetchurl {
69 url = "https://files.pythonhosted.org/packages/ac/ed/a311712ef6b4355035489f665e63e1a73f9eb371929e3c98e5efd451069e/atomicwrites-1.2.1.tar.gz";
69 url = "https://files.pythonhosted.org/packages/ac/ed/a311712ef6b4355035489f665e63e1a73f9eb371929e3c98e5efd451069e/atomicwrites-1.2.1.tar.gz";
70 sha256 = "1vmkbw9j0qammwxbxycrs39gvdg4lc2d4lk98kwf8ag2manyi6pc";
70 sha256 = "1vmkbw9j0qammwxbxycrs39gvdg4lc2d4lk98kwf8ag2manyi6pc";
71 };
71 };
72 meta = {
72 meta = {
73 license = [ pkgs.lib.licenses.mit ];
73 license = [ pkgs.lib.licenses.mit ];
74 };
74 };
75 };
75 };
76 "attrs" = super.buildPythonPackage {
76 "attrs" = super.buildPythonPackage {
77 name = "attrs-19.1.0";
77 name = "attrs-19.1.0";
78 doCheck = false;
78 doCheck = false;
79 src = fetchurl {
79 src = fetchurl {
80 url = "https://files.pythonhosted.org/packages/cc/d9/931a24cc5394f19383fbbe3e1147a0291276afa43a0dc3ed0d6cd9fda813/attrs-19.1.0.tar.gz";
80 url = "https://files.pythonhosted.org/packages/cc/d9/931a24cc5394f19383fbbe3e1147a0291276afa43a0dc3ed0d6cd9fda813/attrs-19.1.0.tar.gz";
81 sha256 = "16g33zr5f449lqc5wgvzpknxryfzrfsxcr6kpgxwn7l5fkv71f7h";
81 sha256 = "16g33zr5f449lqc5wgvzpknxryfzrfsxcr6kpgxwn7l5fkv71f7h";
82 };
82 };
83 meta = {
83 meta = {
84 license = [ pkgs.lib.licenses.mit ];
84 license = [ pkgs.lib.licenses.mit ];
85 };
85 };
86 };
86 };
87 "babel" = super.buildPythonPackage {
87 "babel" = super.buildPythonPackage {
88 name = "babel-1.3";
88 name = "babel-1.3";
89 doCheck = false;
89 doCheck = false;
90 propagatedBuildInputs = [
90 propagatedBuildInputs = [
91 self."pytz"
91 self."pytz"
92 ];
92 ];
93 src = fetchurl {
93 src = fetchurl {
94 url = "https://files.pythonhosted.org/packages/33/27/e3978243a03a76398c384c83f7ca879bc6e8f1511233a621fcada135606e/Babel-1.3.tar.gz";
94 url = "https://files.pythonhosted.org/packages/33/27/e3978243a03a76398c384c83f7ca879bc6e8f1511233a621fcada135606e/Babel-1.3.tar.gz";
95 sha256 = "0bnin777lc53nxd1hp3apq410jj5wx92n08h7h4izpl4f4sx00lz";
95 sha256 = "0bnin777lc53nxd1hp3apq410jj5wx92n08h7h4izpl4f4sx00lz";
96 };
96 };
97 meta = {
97 meta = {
98 license = [ pkgs.lib.licenses.bsdOriginal ];
98 license = [ pkgs.lib.licenses.bsdOriginal ];
99 };
99 };
100 };
100 };
101 "backports.shutil-get-terminal-size" = super.buildPythonPackage {
101 "backports.shutil-get-terminal-size" = super.buildPythonPackage {
102 name = "backports.shutil-get-terminal-size-1.0.0";
102 name = "backports.shutil-get-terminal-size-1.0.0";
103 doCheck = false;
103 doCheck = false;
104 src = fetchurl {
104 src = fetchurl {
105 url = "https://files.pythonhosted.org/packages/ec/9c/368086faa9c016efce5da3e0e13ba392c9db79e3ab740b763fe28620b18b/backports.shutil_get_terminal_size-1.0.0.tar.gz";
105 url = "https://files.pythonhosted.org/packages/ec/9c/368086faa9c016efce5da3e0e13ba392c9db79e3ab740b763fe28620b18b/backports.shutil_get_terminal_size-1.0.0.tar.gz";
106 sha256 = "107cmn7g3jnbkp826zlj8rrj19fam301qvaqf0f3905f5217lgki";
106 sha256 = "107cmn7g3jnbkp826zlj8rrj19fam301qvaqf0f3905f5217lgki";
107 };
107 };
108 meta = {
108 meta = {
109 license = [ pkgs.lib.licenses.mit ];
109 license = [ pkgs.lib.licenses.mit ];
110 };
110 };
111 };
111 };
112 "beaker" = super.buildPythonPackage {
112 "beaker" = super.buildPythonPackage {
113 name = "beaker-1.9.1";
113 name = "beaker-1.9.1";
114 doCheck = false;
114 doCheck = false;
115 propagatedBuildInputs = [
115 propagatedBuildInputs = [
116 self."funcsigs"
116 self."funcsigs"
117 ];
117 ];
118 src = fetchurl {
118 src = fetchurl {
119 url = "https://files.pythonhosted.org/packages/ca/14/a626188d0d0c7b55dd7cf1902046c2743bd392a7078bb53073e13280eb1e/Beaker-1.9.1.tar.gz";
119 url = "https://files.pythonhosted.org/packages/ca/14/a626188d0d0c7b55dd7cf1902046c2743bd392a7078bb53073e13280eb1e/Beaker-1.9.1.tar.gz";
120 sha256 = "08arsn61r255lhz6hcpn2lsiqpg30clla805ysx06wmbhvb6w9rj";
120 sha256 = "08arsn61r255lhz6hcpn2lsiqpg30clla805ysx06wmbhvb6w9rj";
121 };
121 };
122 meta = {
122 meta = {
123 license = [ pkgs.lib.licenses.bsdOriginal ];
123 license = [ pkgs.lib.licenses.bsdOriginal ];
124 };
124 };
125 };
125 };
126 "beautifulsoup4" = super.buildPythonPackage {
126 "beautifulsoup4" = super.buildPythonPackage {
127 name = "beautifulsoup4-4.6.3";
127 name = "beautifulsoup4-4.6.3";
128 doCheck = false;
128 doCheck = false;
129 src = fetchurl {
129 src = fetchurl {
130 url = "https://files.pythonhosted.org/packages/88/df/86bffad6309f74f3ff85ea69344a078fc30003270c8df6894fca7a3c72ff/beautifulsoup4-4.6.3.tar.gz";
130 url = "https://files.pythonhosted.org/packages/88/df/86bffad6309f74f3ff85ea69344a078fc30003270c8df6894fca7a3c72ff/beautifulsoup4-4.6.3.tar.gz";
131 sha256 = "041dhalzjciw6qyzzq7a2k4h1yvyk76xigp35hv5ibnn448ydy4h";
131 sha256 = "041dhalzjciw6qyzzq7a2k4h1yvyk76xigp35hv5ibnn448ydy4h";
132 };
132 };
133 meta = {
133 meta = {
134 license = [ pkgs.lib.licenses.mit ];
134 license = [ pkgs.lib.licenses.mit ];
135 };
135 };
136 };
136 };
137 "billiard" = super.buildPythonPackage {
137 "billiard" = super.buildPythonPackage {
138 name = "billiard-3.6.1.0";
138 name = "billiard-3.6.1.0";
139 doCheck = false;
139 doCheck = false;
140 src = fetchurl {
140 src = fetchurl {
141 url = "https://files.pythonhosted.org/packages/68/1d/2aea8fbb0b1e1260a8a2e77352de2983d36d7ac01207cf14c2b9c6cc860e/billiard-3.6.1.0.tar.gz";
141 url = "https://files.pythonhosted.org/packages/68/1d/2aea8fbb0b1e1260a8a2e77352de2983d36d7ac01207cf14c2b9c6cc860e/billiard-3.6.1.0.tar.gz";
142 sha256 = "09hzy3aqi7visy4vmf4xiish61n0rq5nd3iwjydydps8yrs9r05q";
142 sha256 = "09hzy3aqi7visy4vmf4xiish61n0rq5nd3iwjydydps8yrs9r05q";
143 };
143 };
144 meta = {
144 meta = {
145 license = [ pkgs.lib.licenses.bsdOriginal ];
145 license = [ pkgs.lib.licenses.bsdOriginal ];
146 };
146 };
147 };
147 };
148 "bleach" = super.buildPythonPackage {
148 "bleach" = super.buildPythonPackage {
149 name = "bleach-3.1.0";
149 name = "bleach-3.1.0";
150 doCheck = false;
150 doCheck = false;
151 propagatedBuildInputs = [
151 propagatedBuildInputs = [
152 self."six"
152 self."six"
153 self."webencodings"
153 self."webencodings"
154 ];
154 ];
155 src = fetchurl {
155 src = fetchurl {
156 url = "https://files.pythonhosted.org/packages/78/5a/0df03e8735cd9c75167528299c738702437589b9c71a849489d00ffa82e8/bleach-3.1.0.tar.gz";
156 url = "https://files.pythonhosted.org/packages/78/5a/0df03e8735cd9c75167528299c738702437589b9c71a849489d00ffa82e8/bleach-3.1.0.tar.gz";
157 sha256 = "1yhrgrhkln8bd6gn3imj69g1h4xqah9gaz9q26crqr6gmmvpzprz";
157 sha256 = "1yhrgrhkln8bd6gn3imj69g1h4xqah9gaz9q26crqr6gmmvpzprz";
158 };
158 };
159 meta = {
159 meta = {
160 license = [ pkgs.lib.licenses.asl20 ];
160 license = [ pkgs.lib.licenses.asl20 ];
161 };
161 };
162 };
162 };
163 "bumpversion" = super.buildPythonPackage {
163 "bumpversion" = super.buildPythonPackage {
164 name = "bumpversion-0.5.3";
164 name = "bumpversion-0.5.3";
165 doCheck = false;
165 doCheck = false;
166 src = fetchurl {
166 src = fetchurl {
167 url = "https://files.pythonhosted.org/packages/14/41/8c9da3549f8e00c84f0432c3a8cf8ed6898374714676aab91501d48760db/bumpversion-0.5.3.tar.gz";
167 url = "https://files.pythonhosted.org/packages/14/41/8c9da3549f8e00c84f0432c3a8cf8ed6898374714676aab91501d48760db/bumpversion-0.5.3.tar.gz";
168 sha256 = "0zn7694yfipxg35ikkfh7kvgl2fissha3dnqad2c5bvsvmrwhi37";
168 sha256 = "0zn7694yfipxg35ikkfh7kvgl2fissha3dnqad2c5bvsvmrwhi37";
169 };
169 };
170 meta = {
170 meta = {
171 license = [ pkgs.lib.licenses.mit ];
171 license = [ pkgs.lib.licenses.mit ];
172 };
172 };
173 };
173 };
174 "celery" = super.buildPythonPackage {
174 "celery" = super.buildPythonPackage {
175 name = "celery-4.3.0";
175 name = "celery-4.3.0";
176 doCheck = false;
176 doCheck = false;
177 propagatedBuildInputs = [
177 propagatedBuildInputs = [
178 self."pytz"
178 self."pytz"
179 self."billiard"
179 self."billiard"
180 self."kombu"
180 self."kombu"
181 self."vine"
181 self."vine"
182 ];
182 ];
183 src = fetchurl {
183 src = fetchurl {
184 url = "https://files.pythonhosted.org/packages/a2/4b/d020836f751617e907e84753a41c92231cd4b673ff991b8ee9da52361323/celery-4.3.0.tar.gz";
184 url = "https://files.pythonhosted.org/packages/a2/4b/d020836f751617e907e84753a41c92231cd4b673ff991b8ee9da52361323/celery-4.3.0.tar.gz";
185 sha256 = "1y8y0gbgkwimpxqnxq2rm5qz2vy01fvjiybnpm00y5rzd2m34iac";
185 sha256 = "1y8y0gbgkwimpxqnxq2rm5qz2vy01fvjiybnpm00y5rzd2m34iac";
186 };
186 };
187 meta = {
187 meta = {
188 license = [ pkgs.lib.licenses.bsdOriginal ];
188 license = [ pkgs.lib.licenses.bsdOriginal ];
189 };
189 };
190 };
190 };
191 "cffi" = super.buildPythonPackage {
191 "cffi" = super.buildPythonPackage {
192 name = "cffi-1.12.2";
192 name = "cffi-1.12.2";
193 doCheck = false;
193 doCheck = false;
194 propagatedBuildInputs = [
194 propagatedBuildInputs = [
195 self."pycparser"
195 self."pycparser"
196 ];
196 ];
197 src = fetchurl {
197 src = fetchurl {
198 url = "https://files.pythonhosted.org/packages/64/7c/27367b38e6cc3e1f49f193deb761fe75cda9f95da37b67b422e62281fcac/cffi-1.12.2.tar.gz";
198 url = "https://files.pythonhosted.org/packages/64/7c/27367b38e6cc3e1f49f193deb761fe75cda9f95da37b67b422e62281fcac/cffi-1.12.2.tar.gz";
199 sha256 = "19qfks2djya8vix95bmg3xzipjb8w9b8mbj4j5k2hqkc8j58f4z1";
199 sha256 = "19qfks2djya8vix95bmg3xzipjb8w9b8mbj4j5k2hqkc8j58f4z1";
200 };
200 };
201 meta = {
201 meta = {
202 license = [ pkgs.lib.licenses.mit ];
202 license = [ pkgs.lib.licenses.mit ];
203 };
203 };
204 };
204 };
205 "chameleon" = super.buildPythonPackage {
205 "chameleon" = super.buildPythonPackage {
206 name = "chameleon-2.24";
206 name = "chameleon-2.24";
207 doCheck = false;
207 doCheck = false;
208 src = fetchurl {
208 src = fetchurl {
209 url = "https://files.pythonhosted.org/packages/5a/9e/637379ffa13c5172b5c0e704833ffea6bf51cec7567f93fd6e903d53ed74/Chameleon-2.24.tar.gz";
209 url = "https://files.pythonhosted.org/packages/5a/9e/637379ffa13c5172b5c0e704833ffea6bf51cec7567f93fd6e903d53ed74/Chameleon-2.24.tar.gz";
210 sha256 = "0ykqr7syxfa6h9adjfnsv1gdsca2xzm22vmic8859n0f0j09abj5";
210 sha256 = "0ykqr7syxfa6h9adjfnsv1gdsca2xzm22vmic8859n0f0j09abj5";
211 };
211 };
212 meta = {
212 meta = {
213 license = [ { fullName = "BSD-like (http://repoze.org/license.html)"; } ];
213 license = [ { fullName = "BSD-like (http://repoze.org/license.html)"; } ];
214 };
214 };
215 };
215 };
216 "channelstream" = super.buildPythonPackage {
216 "channelstream" = super.buildPythonPackage {
217 name = "channelstream-0.5.2";
217 name = "channelstream-0.5.2";
218 doCheck = false;
218 doCheck = false;
219 propagatedBuildInputs = [
219 propagatedBuildInputs = [
220 self."gevent"
220 self."gevent"
221 self."ws4py"
221 self."ws4py"
222 self."pyramid"
222 self."pyramid"
223 self."pyramid-jinja2"
223 self."pyramid-jinja2"
224 self."itsdangerous"
224 self."itsdangerous"
225 self."requests"
225 self."requests"
226 self."six"
226 self."six"
227 ];
227 ];
228 src = fetchurl {
228 src = fetchurl {
229 url = "https://files.pythonhosted.org/packages/2b/31/29a8e085cf5bf97fa88e7b947adabfc581a18a3463adf77fb6dada34a65f/channelstream-0.5.2.tar.gz";
229 url = "https://files.pythonhosted.org/packages/2b/31/29a8e085cf5bf97fa88e7b947adabfc581a18a3463adf77fb6dada34a65f/channelstream-0.5.2.tar.gz";
230 sha256 = "1qbm4xdl5hfkja683x546bncg3rqq8qv79w1m1a1wd48cqqzb6rm";
230 sha256 = "1qbm4xdl5hfkja683x546bncg3rqq8qv79w1m1a1wd48cqqzb6rm";
231 };
231 };
232 meta = {
232 meta = {
233 license = [ pkgs.lib.licenses.bsdOriginal ];
233 license = [ pkgs.lib.licenses.bsdOriginal ];
234 };
234 };
235 };
235 };
236 "click" = super.buildPythonPackage {
236 "click" = super.buildPythonPackage {
237 name = "click-7.0";
237 name = "click-7.0";
238 doCheck = false;
238 doCheck = false;
239 src = fetchurl {
239 src = fetchurl {
240 url = "https://files.pythonhosted.org/packages/f8/5c/f60e9d8a1e77005f664b76ff8aeaee5bc05d0a91798afd7f53fc998dbc47/Click-7.0.tar.gz";
240 url = "https://files.pythonhosted.org/packages/f8/5c/f60e9d8a1e77005f664b76ff8aeaee5bc05d0a91798afd7f53fc998dbc47/Click-7.0.tar.gz";
241 sha256 = "1mzjixd4vjbjvzb6vylki9w1556a9qmdh35kzmq6cign46av952v";
241 sha256 = "1mzjixd4vjbjvzb6vylki9w1556a9qmdh35kzmq6cign46av952v";
242 };
242 };
243 meta = {
243 meta = {
244 license = [ pkgs.lib.licenses.bsdOriginal ];
244 license = [ pkgs.lib.licenses.bsdOriginal ];
245 };
245 };
246 };
246 };
247 "colander" = super.buildPythonPackage {
247 "colander" = super.buildPythonPackage {
248 name = "colander-1.7.0";
248 name = "colander-1.7.0";
249 doCheck = false;
249 doCheck = false;
250 propagatedBuildInputs = [
250 propagatedBuildInputs = [
251 self."translationstring"
251 self."translationstring"
252 self."iso8601"
252 self."iso8601"
253 self."enum34"
253 self."enum34"
254 ];
254 ];
255 src = fetchurl {
255 src = fetchurl {
256 url = "https://files.pythonhosted.org/packages/db/e4/74ab06f54211917b41865cafc987ce511e35503de48da9bfe9358a1bdc3e/colander-1.7.0.tar.gz";
256 url = "https://files.pythonhosted.org/packages/db/e4/74ab06f54211917b41865cafc987ce511e35503de48da9bfe9358a1bdc3e/colander-1.7.0.tar.gz";
257 sha256 = "1wl1bqab307lbbcjx81i28s3yl6dlm4rf15fxawkjb6j48x1cn6p";
257 sha256 = "1wl1bqab307lbbcjx81i28s3yl6dlm4rf15fxawkjb6j48x1cn6p";
258 };
258 };
259 meta = {
259 meta = {
260 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
260 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
261 };
261 };
262 };
262 };
263 "configobj" = super.buildPythonPackage {
263 "configobj" = super.buildPythonPackage {
264 name = "configobj-5.0.6";
264 name = "configobj-5.0.6";
265 doCheck = false;
265 doCheck = false;
266 propagatedBuildInputs = [
266 propagatedBuildInputs = [
267 self."six"
267 self."six"
268 ];
268 ];
269 src = fetchurl {
269 src = fetchurl {
270 url = "https://code.rhodecode.com/upstream/configobj/artifacts/download/0-012de99a-b1e1-4f64-a5c0-07a98a41b324.tar.gz?md5=6a513f51fe04b2c18cf84c1395a7c626";
270 url = "https://code.rhodecode.com/upstream/configobj/artifacts/download/0-012de99a-b1e1-4f64-a5c0-07a98a41b324.tar.gz?md5=6a513f51fe04b2c18cf84c1395a7c626";
271 sha256 = "0kqfrdfr14mw8yd8qwq14dv2xghpkjmd3yjsy8dfcbvpcc17xnxp";
271 sha256 = "0kqfrdfr14mw8yd8qwq14dv2xghpkjmd3yjsy8dfcbvpcc17xnxp";
272 };
272 };
273 meta = {
273 meta = {
274 license = [ pkgs.lib.licenses.bsdOriginal ];
274 license = [ pkgs.lib.licenses.bsdOriginal ];
275 };
275 };
276 };
276 };
277 "configparser" = super.buildPythonPackage {
277 "configparser" = super.buildPythonPackage {
278 name = "configparser-3.7.4";
278 name = "configparser-3.7.4";
279 doCheck = false;
279 doCheck = false;
280 src = fetchurl {
280 src = fetchurl {
281 url = "https://files.pythonhosted.org/packages/e2/1c/83fd53748d8245cb9a3399f705c251d3fc0ce7df04450aac1cfc49dd6a0f/configparser-3.7.4.tar.gz";
281 url = "https://files.pythonhosted.org/packages/e2/1c/83fd53748d8245cb9a3399f705c251d3fc0ce7df04450aac1cfc49dd6a0f/configparser-3.7.4.tar.gz";
282 sha256 = "0xac32886ihs2xg7w1gppcq2sgin5qsm8lqwijs5xifq9w0x0q6s";
282 sha256 = "0xac32886ihs2xg7w1gppcq2sgin5qsm8lqwijs5xifq9w0x0q6s";
283 };
283 };
284 meta = {
284 meta = {
285 license = [ pkgs.lib.licenses.mit ];
285 license = [ pkgs.lib.licenses.mit ];
286 };
286 };
287 };
287 };
288 "contextlib2" = super.buildPythonPackage {
288 "contextlib2" = super.buildPythonPackage {
289 name = "contextlib2-0.5.5";
289 name = "contextlib2-0.5.5";
290 doCheck = false;
290 doCheck = false;
291 src = fetchurl {
291 src = fetchurl {
292 url = "https://files.pythonhosted.org/packages/6e/db/41233498c210b03ab8b072c8ee49b1cd63b3b0c76f8ea0a0e5d02df06898/contextlib2-0.5.5.tar.gz";
292 url = "https://files.pythonhosted.org/packages/6e/db/41233498c210b03ab8b072c8ee49b1cd63b3b0c76f8ea0a0e5d02df06898/contextlib2-0.5.5.tar.gz";
293 sha256 = "0j6ad6lwwyc9kv71skj098v5l7x5biyj2hs4lc5x1kcixqcr97sh";
293 sha256 = "0j6ad6lwwyc9kv71skj098v5l7x5biyj2hs4lc5x1kcixqcr97sh";
294 };
294 };
295 meta = {
295 meta = {
296 license = [ pkgs.lib.licenses.psfl ];
296 license = [ pkgs.lib.licenses.psfl ];
297 };
297 };
298 };
298 };
299 "cov-core" = super.buildPythonPackage {
299 "cov-core" = super.buildPythonPackage {
300 name = "cov-core-1.15.0";
300 name = "cov-core-1.15.0";
301 doCheck = false;
301 doCheck = false;
302 propagatedBuildInputs = [
302 propagatedBuildInputs = [
303 self."coverage"
303 self."coverage"
304 ];
304 ];
305 src = fetchurl {
305 src = fetchurl {
306 url = "https://files.pythonhosted.org/packages/4b/87/13e75a47b4ba1be06f29f6d807ca99638bedc6b57fa491cd3de891ca2923/cov-core-1.15.0.tar.gz";
306 url = "https://files.pythonhosted.org/packages/4b/87/13e75a47b4ba1be06f29f6d807ca99638bedc6b57fa491cd3de891ca2923/cov-core-1.15.0.tar.gz";
307 sha256 = "0k3np9ymh06yv1ib96sb6wfsxjkqhmik8qfsn119vnhga9ywc52a";
307 sha256 = "0k3np9ymh06yv1ib96sb6wfsxjkqhmik8qfsn119vnhga9ywc52a";
308 };
308 };
309 meta = {
309 meta = {
310 license = [ pkgs.lib.licenses.mit ];
310 license = [ pkgs.lib.licenses.mit ];
311 };
311 };
312 };
312 };
313 "coverage" = super.buildPythonPackage {
313 "coverage" = super.buildPythonPackage {
314 name = "coverage-4.5.3";
314 name = "coverage-4.5.4";
315 doCheck = false;
315 doCheck = false;
316 src = fetchurl {
316 src = fetchurl {
317 url = "https://files.pythonhosted.org/packages/82/70/2280b5b29a0352519bb95ab0ef1ea942d40466ca71c53a2085bdeff7b0eb/coverage-4.5.3.tar.gz";
317 url = "https://files.pythonhosted.org/packages/85/d5/818d0e603685c4a613d56f065a721013e942088047ff1027a632948bdae6/coverage-4.5.4.tar.gz";
318 sha256 = "02f6m073qdispn96rc616hg0rnmw1pgqzw3bgxwiwza4zf9hirlx";
318 sha256 = "0p0j4di6h8k6ica7jwwj09azdcg4ycxq60i9qsskmsg94cd9yzg0";
319 };
319 };
320 meta = {
320 meta = {
321 license = [ pkgs.lib.licenses.asl20 ];
321 license = [ pkgs.lib.licenses.asl20 ];
322 };
322 };
323 };
323 };
324 "cryptography" = super.buildPythonPackage {
324 "cryptography" = super.buildPythonPackage {
325 name = "cryptography-2.6.1";
325 name = "cryptography-2.6.1";
326 doCheck = false;
326 doCheck = false;
327 propagatedBuildInputs = [
327 propagatedBuildInputs = [
328 self."asn1crypto"
328 self."asn1crypto"
329 self."six"
329 self."six"
330 self."cffi"
330 self."cffi"
331 self."enum34"
331 self."enum34"
332 self."ipaddress"
332 self."ipaddress"
333 ];
333 ];
334 src = fetchurl {
334 src = fetchurl {
335 url = "https://files.pythonhosted.org/packages/07/ca/bc827c5e55918ad223d59d299fff92f3563476c3b00d0a9157d9c0217449/cryptography-2.6.1.tar.gz";
335 url = "https://files.pythonhosted.org/packages/07/ca/bc827c5e55918ad223d59d299fff92f3563476c3b00d0a9157d9c0217449/cryptography-2.6.1.tar.gz";
336 sha256 = "19iwz5avym5zl6jrrrkym1rdaa9h61j20ph4cswsqgv8xg5j3j16";
336 sha256 = "19iwz5avym5zl6jrrrkym1rdaa9h61j20ph4cswsqgv8xg5j3j16";
337 };
337 };
338 meta = {
338 meta = {
339 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "BSD or Apache License, Version 2.0"; } pkgs.lib.licenses.asl20 ];
339 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "BSD or Apache License, Version 2.0"; } pkgs.lib.licenses.asl20 ];
340 };
340 };
341 };
341 };
342 "cssselect" = super.buildPythonPackage {
342 "cssselect" = super.buildPythonPackage {
343 name = "cssselect-1.0.3";
343 name = "cssselect-1.0.3";
344 doCheck = false;
344 doCheck = false;
345 src = fetchurl {
345 src = fetchurl {
346 url = "https://files.pythonhosted.org/packages/52/ea/f31e1d2e9eb130fda2a631e22eac369dc644e8807345fbed5113f2d6f92b/cssselect-1.0.3.tar.gz";
346 url = "https://files.pythonhosted.org/packages/52/ea/f31e1d2e9eb130fda2a631e22eac369dc644e8807345fbed5113f2d6f92b/cssselect-1.0.3.tar.gz";
347 sha256 = "011jqa2jhmydhi0iz4v1w3cr540z5zas8g2bw8brdw4s4b2qnv86";
347 sha256 = "011jqa2jhmydhi0iz4v1w3cr540z5zas8g2bw8brdw4s4b2qnv86";
348 };
348 };
349 meta = {
349 meta = {
350 license = [ pkgs.lib.licenses.bsdOriginal ];
350 license = [ pkgs.lib.licenses.bsdOriginal ];
351 };
351 };
352 };
352 };
353 "decorator" = super.buildPythonPackage {
353 "decorator" = super.buildPythonPackage {
354 name = "decorator-4.1.2";
354 name = "decorator-4.1.2";
355 doCheck = false;
355 doCheck = false;
356 src = fetchurl {
356 src = fetchurl {
357 url = "https://files.pythonhosted.org/packages/bb/e0/f6e41e9091e130bf16d4437dabbac3993908e4d6485ecbc985ef1352db94/decorator-4.1.2.tar.gz";
357 url = "https://files.pythonhosted.org/packages/bb/e0/f6e41e9091e130bf16d4437dabbac3993908e4d6485ecbc985ef1352db94/decorator-4.1.2.tar.gz";
358 sha256 = "1d8npb11kxyi36mrvjdpcjij76l5zfyrz2f820brf0l0rcw4vdkw";
358 sha256 = "1d8npb11kxyi36mrvjdpcjij76l5zfyrz2f820brf0l0rcw4vdkw";
359 };
359 };
360 meta = {
360 meta = {
361 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "new BSD License"; } ];
361 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "new BSD License"; } ];
362 };
362 };
363 };
363 };
364 "deform" = super.buildPythonPackage {
364 "deform" = super.buildPythonPackage {
365 name = "deform-2.0.7";
365 name = "deform-2.0.7";
366 doCheck = false;
366 doCheck = false;
367 propagatedBuildInputs = [
367 propagatedBuildInputs = [
368 self."chameleon"
368 self."chameleon"
369 self."colander"
369 self."colander"
370 self."iso8601"
370 self."iso8601"
371 self."peppercorn"
371 self."peppercorn"
372 self."translationstring"
372 self."translationstring"
373 self."zope.deprecation"
373 self."zope.deprecation"
374 ];
374 ];
375 src = fetchurl {
375 src = fetchurl {
376 url = "https://files.pythonhosted.org/packages/cf/a1/bc234527b8f181de9acd80e796483c00007658d1e32b7de78f1c2e004d9a/deform-2.0.7.tar.gz";
376 url = "https://files.pythonhosted.org/packages/cf/a1/bc234527b8f181de9acd80e796483c00007658d1e32b7de78f1c2e004d9a/deform-2.0.7.tar.gz";
377 sha256 = "0jnpi0zr2hjvbmiz6nm33yqv976dn9lf51vhlzqc0i75xcr9rwig";
377 sha256 = "0jnpi0zr2hjvbmiz6nm33yqv976dn9lf51vhlzqc0i75xcr9rwig";
378 };
378 };
379 meta = {
379 meta = {
380 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
380 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
381 };
381 };
382 };
382 };
383 "defusedxml" = super.buildPythonPackage {
383 "defusedxml" = super.buildPythonPackage {
384 name = "defusedxml-0.6.0";
384 name = "defusedxml-0.6.0";
385 doCheck = false;
385 doCheck = false;
386 src = fetchurl {
386 src = fetchurl {
387 url = "https://files.pythonhosted.org/packages/a4/5f/f8aa58ca0cf01cbcee728abc9d88bfeb74e95e6cb4334cfd5bed5673ea77/defusedxml-0.6.0.tar.gz";
387 url = "https://files.pythonhosted.org/packages/a4/5f/f8aa58ca0cf01cbcee728abc9d88bfeb74e95e6cb4334cfd5bed5673ea77/defusedxml-0.6.0.tar.gz";
388 sha256 = "1xbp8fivl3wlbyg2jrvs4lalaqv1xp9a9f29p75wdx2s2d6h717n";
388 sha256 = "1xbp8fivl3wlbyg2jrvs4lalaqv1xp9a9f29p75wdx2s2d6h717n";
389 };
389 };
390 meta = {
390 meta = {
391 license = [ pkgs.lib.licenses.psfl ];
391 license = [ pkgs.lib.licenses.psfl ];
392 };
392 };
393 };
393 };
394 "dm.xmlsec.binding" = super.buildPythonPackage {
394 "dm.xmlsec.binding" = super.buildPythonPackage {
395 name = "dm.xmlsec.binding-1.3.7";
395 name = "dm.xmlsec.binding-1.3.7";
396 doCheck = false;
396 doCheck = false;
397 propagatedBuildInputs = [
397 propagatedBuildInputs = [
398 self."setuptools"
398 self."setuptools"
399 self."lxml"
399 self."lxml"
400 ];
400 ];
401 src = fetchurl {
401 src = fetchurl {
402 url = "https://files.pythonhosted.org/packages/2c/9e/7651982d50252692991acdae614af821fd6c79bc8dcd598ad71d55be8fc7/dm.xmlsec.binding-1.3.7.tar.gz";
402 url = "https://files.pythonhosted.org/packages/2c/9e/7651982d50252692991acdae614af821fd6c79bc8dcd598ad71d55be8fc7/dm.xmlsec.binding-1.3.7.tar.gz";
403 sha256 = "03jjjscx1pz2nc0dwiw9nia02qbz1c6f0f9zkyr8fmvys2n5jkb3";
403 sha256 = "03jjjscx1pz2nc0dwiw9nia02qbz1c6f0f9zkyr8fmvys2n5jkb3";
404 };
404 };
405 meta = {
405 meta = {
406 license = [ pkgs.lib.licenses.bsdOriginal ];
406 license = [ pkgs.lib.licenses.bsdOriginal ];
407 };
407 };
408 };
408 };
409 "docutils" = super.buildPythonPackage {
409 "docutils" = super.buildPythonPackage {
410 name = "docutils-0.14";
410 name = "docutils-0.14";
411 doCheck = false;
411 doCheck = false;
412 src = fetchurl {
412 src = fetchurl {
413 url = "https://files.pythonhosted.org/packages/84/f4/5771e41fdf52aabebbadecc9381d11dea0fa34e4759b4071244fa094804c/docutils-0.14.tar.gz";
413 url = "https://files.pythonhosted.org/packages/84/f4/5771e41fdf52aabebbadecc9381d11dea0fa34e4759b4071244fa094804c/docutils-0.14.tar.gz";
414 sha256 = "0x22fs3pdmr42kvz6c654756wja305qv6cx1zbhwlagvxgr4xrji";
414 sha256 = "0x22fs3pdmr42kvz6c654756wja305qv6cx1zbhwlagvxgr4xrji";
415 };
415 };
416 meta = {
416 meta = {
417 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.publicDomain pkgs.lib.licenses.gpl1 { fullName = "public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)"; } pkgs.lib.licenses.psfl ];
417 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.publicDomain pkgs.lib.licenses.gpl1 { fullName = "public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)"; } pkgs.lib.licenses.psfl ];
418 };
418 };
419 };
419 };
420 "dogpile.cache" = super.buildPythonPackage {
420 "dogpile.cache" = super.buildPythonPackage {
421 name = "dogpile.cache-0.7.1";
421 name = "dogpile.cache-0.7.1";
422 doCheck = false;
422 doCheck = false;
423 propagatedBuildInputs = [
423 propagatedBuildInputs = [
424 self."decorator"
424 self."decorator"
425 ];
425 ];
426 src = fetchurl {
426 src = fetchurl {
427 url = "https://files.pythonhosted.org/packages/84/3e/dbf1cfc5228f1d3dca80ef714db2c5aaec5cd9efaf54d7e3daef6bc48b19/dogpile.cache-0.7.1.tar.gz";
427 url = "https://files.pythonhosted.org/packages/84/3e/dbf1cfc5228f1d3dca80ef714db2c5aaec5cd9efaf54d7e3daef6bc48b19/dogpile.cache-0.7.1.tar.gz";
428 sha256 = "0caazmrzhnfqb5yrp8myhw61ny637jj69wcngrpbvi31jlcpy6v9";
428 sha256 = "0caazmrzhnfqb5yrp8myhw61ny637jj69wcngrpbvi31jlcpy6v9";
429 };
429 };
430 meta = {
430 meta = {
431 license = [ pkgs.lib.licenses.bsdOriginal ];
431 license = [ pkgs.lib.licenses.bsdOriginal ];
432 };
432 };
433 };
433 };
434 "dogpile.core" = super.buildPythonPackage {
434 "dogpile.core" = super.buildPythonPackage {
435 name = "dogpile.core-0.4.1";
435 name = "dogpile.core-0.4.1";
436 doCheck = false;
436 doCheck = false;
437 src = fetchurl {
437 src = fetchurl {
438 url = "https://files.pythonhosted.org/packages/0e/77/e72abc04c22aedf874301861e5c1e761231c288b5de369c18be8f4b5c9bb/dogpile.core-0.4.1.tar.gz";
438 url = "https://files.pythonhosted.org/packages/0e/77/e72abc04c22aedf874301861e5c1e761231c288b5de369c18be8f4b5c9bb/dogpile.core-0.4.1.tar.gz";
439 sha256 = "0xpdvg4kr1isfkrh1rfsh7za4q5a5s6l2kf9wpvndbwf3aqjyrdy";
439 sha256 = "0xpdvg4kr1isfkrh1rfsh7za4q5a5s6l2kf9wpvndbwf3aqjyrdy";
440 };
440 };
441 meta = {
441 meta = {
442 license = [ pkgs.lib.licenses.bsdOriginal ];
442 license = [ pkgs.lib.licenses.bsdOriginal ];
443 };
443 };
444 };
444 };
445 "ecdsa" = super.buildPythonPackage {
445 "ecdsa" = super.buildPythonPackage {
446 name = "ecdsa-0.13.2";
446 name = "ecdsa-0.13.2";
447 doCheck = false;
447 doCheck = false;
448 src = fetchurl {
448 src = fetchurl {
449 url = "https://files.pythonhosted.org/packages/51/76/139bf6e9b7b6684d5891212cdbd9e0739f2bfc03f380a1a6ffa700f392ac/ecdsa-0.13.2.tar.gz";
449 url = "https://files.pythonhosted.org/packages/51/76/139bf6e9b7b6684d5891212cdbd9e0739f2bfc03f380a1a6ffa700f392ac/ecdsa-0.13.2.tar.gz";
450 sha256 = "116qaq7bh4lcynzi613960jhsnn19v0kmsqwahiwjfj14gx4y0sw";
450 sha256 = "116qaq7bh4lcynzi613960jhsnn19v0kmsqwahiwjfj14gx4y0sw";
451 };
451 };
452 meta = {
452 meta = {
453 license = [ pkgs.lib.licenses.mit ];
453 license = [ pkgs.lib.licenses.mit ];
454 };
454 };
455 };
455 };
456 "elasticsearch" = super.buildPythonPackage {
456 "elasticsearch" = super.buildPythonPackage {
457 name = "elasticsearch-6.3.1";
457 name = "elasticsearch-6.3.1";
458 doCheck = false;
458 doCheck = false;
459 propagatedBuildInputs = [
459 propagatedBuildInputs = [
460 self."urllib3"
460 self."urllib3"
461 ];
461 ];
462 src = fetchurl {
462 src = fetchurl {
463 url = "https://files.pythonhosted.org/packages/9d/ce/c4664e8380e379a9402ecfbaf158e56396da90d520daba21cfa840e0eb71/elasticsearch-6.3.1.tar.gz";
463 url = "https://files.pythonhosted.org/packages/9d/ce/c4664e8380e379a9402ecfbaf158e56396da90d520daba21cfa840e0eb71/elasticsearch-6.3.1.tar.gz";
464 sha256 = "12y93v0yn7a4xmf969239g8gb3l4cdkclfpbk1qc8hx5qkymrnma";
464 sha256 = "12y93v0yn7a4xmf969239g8gb3l4cdkclfpbk1qc8hx5qkymrnma";
465 };
465 };
466 meta = {
466 meta = {
467 license = [ pkgs.lib.licenses.asl20 ];
467 license = [ pkgs.lib.licenses.asl20 ];
468 };
468 };
469 };
469 };
470 "elasticsearch-dsl" = super.buildPythonPackage {
470 "elasticsearch-dsl" = super.buildPythonPackage {
471 name = "elasticsearch-dsl-6.3.1";
471 name = "elasticsearch-dsl-6.3.1";
472 doCheck = false;
472 doCheck = false;
473 propagatedBuildInputs = [
473 propagatedBuildInputs = [
474 self."six"
474 self."six"
475 self."python-dateutil"
475 self."python-dateutil"
476 self."elasticsearch"
476 self."elasticsearch"
477 self."ipaddress"
477 self."ipaddress"
478 ];
478 ];
479 src = fetchurl {
479 src = fetchurl {
480 url = "https://files.pythonhosted.org/packages/4c/0d/1549f50c591db6bb4e66cbcc8d34a6e537c3d89aa426b167c244fd46420a/elasticsearch-dsl-6.3.1.tar.gz";
480 url = "https://files.pythonhosted.org/packages/4c/0d/1549f50c591db6bb4e66cbcc8d34a6e537c3d89aa426b167c244fd46420a/elasticsearch-dsl-6.3.1.tar.gz";
481 sha256 = "1gh8a0shqi105k325hgwb9avrpdjh0mc6mxwfg9ba7g6lssb702z";
481 sha256 = "1gh8a0shqi105k325hgwb9avrpdjh0mc6mxwfg9ba7g6lssb702z";
482 };
482 };
483 meta = {
483 meta = {
484 license = [ pkgs.lib.licenses.asl20 ];
484 license = [ pkgs.lib.licenses.asl20 ];
485 };
485 };
486 };
486 };
487 "elasticsearch1" = super.buildPythonPackage {
487 "elasticsearch1" = super.buildPythonPackage {
488 name = "elasticsearch1-1.10.0";
488 name = "elasticsearch1-1.10.0";
489 doCheck = false;
489 doCheck = false;
490 propagatedBuildInputs = [
490 propagatedBuildInputs = [
491 self."urllib3"
491 self."urllib3"
492 ];
492 ];
493 src = fetchurl {
493 src = fetchurl {
494 url = "https://files.pythonhosted.org/packages/a6/eb/73e75f9681fa71e3157b8ee878534235d57f24ee64f0e77f8d995fb57076/elasticsearch1-1.10.0.tar.gz";
494 url = "https://files.pythonhosted.org/packages/a6/eb/73e75f9681fa71e3157b8ee878534235d57f24ee64f0e77f8d995fb57076/elasticsearch1-1.10.0.tar.gz";
495 sha256 = "0g89444kd5zwql4vbvyrmi2m6l6dcj6ga98j4hqxyyyz6z20aki2";
495 sha256 = "0g89444kd5zwql4vbvyrmi2m6l6dcj6ga98j4hqxyyyz6z20aki2";
496 };
496 };
497 meta = {
497 meta = {
498 license = [ pkgs.lib.licenses.asl20 ];
498 license = [ pkgs.lib.licenses.asl20 ];
499 };
499 };
500 };
500 };
501 "elasticsearch1-dsl" = super.buildPythonPackage {
501 "elasticsearch1-dsl" = super.buildPythonPackage {
502 name = "elasticsearch1-dsl-0.0.12";
502 name = "elasticsearch1-dsl-0.0.12";
503 doCheck = false;
503 doCheck = false;
504 propagatedBuildInputs = [
504 propagatedBuildInputs = [
505 self."six"
505 self."six"
506 self."python-dateutil"
506 self."python-dateutil"
507 self."elasticsearch1"
507 self."elasticsearch1"
508 ];
508 ];
509 src = fetchurl {
509 src = fetchurl {
510 url = "https://files.pythonhosted.org/packages/eb/9d/785342775cb10eddc9b8d7457d618a423b4f0b89d8b2b2d1bc27190d71db/elasticsearch1-dsl-0.0.12.tar.gz";
510 url = "https://files.pythonhosted.org/packages/eb/9d/785342775cb10eddc9b8d7457d618a423b4f0b89d8b2b2d1bc27190d71db/elasticsearch1-dsl-0.0.12.tar.gz";
511 sha256 = "0ig1ly39v93hba0z975wnhbmzwj28w6w1sqlr2g7cn5spp732bhk";
511 sha256 = "0ig1ly39v93hba0z975wnhbmzwj28w6w1sqlr2g7cn5spp732bhk";
512 };
512 };
513 meta = {
513 meta = {
514 license = [ pkgs.lib.licenses.asl20 ];
514 license = [ pkgs.lib.licenses.asl20 ];
515 };
515 };
516 };
516 };
517 "elasticsearch2" = super.buildPythonPackage {
517 "elasticsearch2" = super.buildPythonPackage {
518 name = "elasticsearch2-2.5.0";
518 name = "elasticsearch2-2.5.0";
519 doCheck = false;
519 doCheck = false;
520 propagatedBuildInputs = [
520 propagatedBuildInputs = [
521 self."urllib3"
521 self."urllib3"
522 ];
522 ];
523 src = fetchurl {
523 src = fetchurl {
524 url = "https://files.pythonhosted.org/packages/84/77/63cf63d4ba11d913b5278406f2a37b0712bec6fc85edfb6151a33eaeba25/elasticsearch2-2.5.0.tar.gz";
524 url = "https://files.pythonhosted.org/packages/84/77/63cf63d4ba11d913b5278406f2a37b0712bec6fc85edfb6151a33eaeba25/elasticsearch2-2.5.0.tar.gz";
525 sha256 = "0ky0q16lbvz022yv6q3pix7aamf026p1y994537ccjf0p0dxnbxr";
525 sha256 = "0ky0q16lbvz022yv6q3pix7aamf026p1y994537ccjf0p0dxnbxr";
526 };
526 };
527 meta = {
527 meta = {
528 license = [ pkgs.lib.licenses.asl20 ];
528 license = [ pkgs.lib.licenses.asl20 ];
529 };
529 };
530 };
530 };
531 "entrypoints" = super.buildPythonPackage {
531 "entrypoints" = super.buildPythonPackage {
532 name = "entrypoints-0.2.2";
532 name = "entrypoints-0.2.2";
533 doCheck = false;
533 doCheck = false;
534 propagatedBuildInputs = [
534 propagatedBuildInputs = [
535 self."configparser"
535 self."configparser"
536 ];
536 ];
537 src = fetchurl {
537 src = fetchurl {
538 url = "https://code.rhodecode.com/upstream/entrypoints/artifacts/download/0-8e9ee9e4-c4db-409c-b07e-81568fd1832d.tar.gz?md5=3a027b8ff1d257b91fe257de6c43357d";
538 url = "https://code.rhodecode.com/upstream/entrypoints/artifacts/download/0-8e9ee9e4-c4db-409c-b07e-81568fd1832d.tar.gz?md5=3a027b8ff1d257b91fe257de6c43357d";
539 sha256 = "0qih72n2myclanplqipqxpgpj9d2yhff1pz5d02zq1cfqyd173w5";
539 sha256 = "0qih72n2myclanplqipqxpgpj9d2yhff1pz5d02zq1cfqyd173w5";
540 };
540 };
541 meta = {
541 meta = {
542 license = [ pkgs.lib.licenses.mit ];
542 license = [ pkgs.lib.licenses.mit ];
543 };
543 };
544 };
544 };
545 "enum34" = super.buildPythonPackage {
545 "enum34" = super.buildPythonPackage {
546 name = "enum34-1.1.6";
546 name = "enum34-1.1.6";
547 doCheck = false;
547 doCheck = false;
548 src = fetchurl {
548 src = fetchurl {
549 url = "https://files.pythonhosted.org/packages/bf/3e/31d502c25302814a7c2f1d3959d2a3b3f78e509002ba91aea64993936876/enum34-1.1.6.tar.gz";
549 url = "https://files.pythonhosted.org/packages/bf/3e/31d502c25302814a7c2f1d3959d2a3b3f78e509002ba91aea64993936876/enum34-1.1.6.tar.gz";
550 sha256 = "1cgm5ng2gcfrkrm3hc22brl6chdmv67b9zvva9sfs7gn7dwc9n4a";
550 sha256 = "1cgm5ng2gcfrkrm3hc22brl6chdmv67b9zvva9sfs7gn7dwc9n4a";
551 };
551 };
552 meta = {
552 meta = {
553 license = [ pkgs.lib.licenses.bsdOriginal ];
553 license = [ pkgs.lib.licenses.bsdOriginal ];
554 };
554 };
555 };
555 };
556 "formencode" = super.buildPythonPackage {
556 "formencode" = super.buildPythonPackage {
557 name = "formencode-1.2.4";
557 name = "formencode-1.2.4";
558 doCheck = false;
558 doCheck = false;
559 src = fetchurl {
559 src = fetchurl {
560 url = "https://files.pythonhosted.org/packages/8e/59/0174271a6f004512e0201188593e6d319db139d14cb7490e488bbb078015/FormEncode-1.2.4.tar.gz";
560 url = "https://files.pythonhosted.org/packages/8e/59/0174271a6f004512e0201188593e6d319db139d14cb7490e488bbb078015/FormEncode-1.2.4.tar.gz";
561 sha256 = "1fgy04sdy4yry5xcjls3x3xy30dqwj58ycnkndim819jx0788w42";
561 sha256 = "1fgy04sdy4yry5xcjls3x3xy30dqwj58ycnkndim819jx0788w42";
562 };
562 };
563 meta = {
563 meta = {
564 license = [ pkgs.lib.licenses.psfl ];
564 license = [ pkgs.lib.licenses.psfl ];
565 };
565 };
566 };
566 };
567 "funcsigs" = super.buildPythonPackage {
567 "funcsigs" = super.buildPythonPackage {
568 name = "funcsigs-1.0.2";
568 name = "funcsigs-1.0.2";
569 doCheck = false;
569 doCheck = false;
570 src = fetchurl {
570 src = fetchurl {
571 url = "https://files.pythonhosted.org/packages/94/4a/db842e7a0545de1cdb0439bb80e6e42dfe82aaeaadd4072f2263a4fbed23/funcsigs-1.0.2.tar.gz";
571 url = "https://files.pythonhosted.org/packages/94/4a/db842e7a0545de1cdb0439bb80e6e42dfe82aaeaadd4072f2263a4fbed23/funcsigs-1.0.2.tar.gz";
572 sha256 = "0l4g5818ffyfmfs1a924811azhjj8ax9xd1cffr1mzd3ycn0zfx7";
572 sha256 = "0l4g5818ffyfmfs1a924811azhjj8ax9xd1cffr1mzd3ycn0zfx7";
573 };
573 };
574 meta = {
574 meta = {
575 license = [ { fullName = "ASL"; } pkgs.lib.licenses.asl20 ];
575 license = [ { fullName = "ASL"; } pkgs.lib.licenses.asl20 ];
576 };
576 };
577 };
577 };
578 "functools32" = super.buildPythonPackage {
578 "functools32" = super.buildPythonPackage {
579 name = "functools32-3.2.3.post2";
579 name = "functools32-3.2.3.post2";
580 doCheck = false;
580 doCheck = false;
581 src = fetchurl {
581 src = fetchurl {
582 url = "https://files.pythonhosted.org/packages/c5/60/6ac26ad05857c601308d8fb9e87fa36d0ebf889423f47c3502ef034365db/functools32-3.2.3-2.tar.gz";
582 url = "https://files.pythonhosted.org/packages/c5/60/6ac26ad05857c601308d8fb9e87fa36d0ebf889423f47c3502ef034365db/functools32-3.2.3-2.tar.gz";
583 sha256 = "0v8ya0b58x47wp216n1zamimv4iw57cxz3xxhzix52jkw3xks9gn";
583 sha256 = "0v8ya0b58x47wp216n1zamimv4iw57cxz3xxhzix52jkw3xks9gn";
584 };
584 };
585 meta = {
585 meta = {
586 license = [ pkgs.lib.licenses.psfl ];
586 license = [ pkgs.lib.licenses.psfl ];
587 };
587 };
588 };
588 };
589 "future" = super.buildPythonPackage {
589 "future" = super.buildPythonPackage {
590 name = "future-0.14.3";
590 name = "future-0.14.3";
591 doCheck = false;
591 doCheck = false;
592 src = fetchurl {
592 src = fetchurl {
593 url = "https://files.pythonhosted.org/packages/83/80/8ef3a11a15f8eaafafa0937b20c1b3f73527e69ab6b3fa1cf94a5a96aabb/future-0.14.3.tar.gz";
593 url = "https://files.pythonhosted.org/packages/83/80/8ef3a11a15f8eaafafa0937b20c1b3f73527e69ab6b3fa1cf94a5a96aabb/future-0.14.3.tar.gz";
594 sha256 = "1savk7jx7hal032f522c5ajhh8fra6gmnadrj9adv5qxi18pv1b2";
594 sha256 = "1savk7jx7hal032f522c5ajhh8fra6gmnadrj9adv5qxi18pv1b2";
595 };
595 };
596 meta = {
596 meta = {
597 license = [ { fullName = "OSI Approved"; } pkgs.lib.licenses.mit ];
597 license = [ { fullName = "OSI Approved"; } pkgs.lib.licenses.mit ];
598 };
598 };
599 };
599 };
600 "futures" = super.buildPythonPackage {
600 "futures" = super.buildPythonPackage {
601 name = "futures-3.0.2";
601 name = "futures-3.0.2";
602 doCheck = false;
602 doCheck = false;
603 src = fetchurl {
603 src = fetchurl {
604 url = "https://files.pythonhosted.org/packages/f8/e7/fc0fcbeb9193ba2d4de00b065e7fd5aecd0679e93ce95a07322b2b1434f4/futures-3.0.2.tar.gz";
604 url = "https://files.pythonhosted.org/packages/f8/e7/fc0fcbeb9193ba2d4de00b065e7fd5aecd0679e93ce95a07322b2b1434f4/futures-3.0.2.tar.gz";
605 sha256 = "0mz2pbgxbc2nbib1szifi07whjbfs4r02pv2z390z7p410awjgyw";
605 sha256 = "0mz2pbgxbc2nbib1szifi07whjbfs4r02pv2z390z7p410awjgyw";
606 };
606 };
607 meta = {
607 meta = {
608 license = [ pkgs.lib.licenses.bsdOriginal ];
608 license = [ pkgs.lib.licenses.bsdOriginal ];
609 };
609 };
610 };
610 };
611 "gevent" = super.buildPythonPackage {
611 "gevent" = super.buildPythonPackage {
612 name = "gevent-1.4.0";
612 name = "gevent-1.4.0";
613 doCheck = false;
613 doCheck = false;
614 propagatedBuildInputs = [
614 propagatedBuildInputs = [
615 self."greenlet"
615 self."greenlet"
616 ];
616 ];
617 src = fetchurl {
617 src = fetchurl {
618 url = "https://files.pythonhosted.org/packages/ed/27/6c49b70808f569b66ec7fac2e78f076e9b204db9cf5768740cff3d5a07ae/gevent-1.4.0.tar.gz";
618 url = "https://files.pythonhosted.org/packages/ed/27/6c49b70808f569b66ec7fac2e78f076e9b204db9cf5768740cff3d5a07ae/gevent-1.4.0.tar.gz";
619 sha256 = "1lchr4akw2jkm5v4kz7bdm4wv3knkfhbfn9vkkz4s5yrkcxzmdqy";
619 sha256 = "1lchr4akw2jkm5v4kz7bdm4wv3knkfhbfn9vkkz4s5yrkcxzmdqy";
620 };
620 };
621 meta = {
621 meta = {
622 license = [ pkgs.lib.licenses.mit ];
622 license = [ pkgs.lib.licenses.mit ];
623 };
623 };
624 };
624 };
625 "gnureadline" = super.buildPythonPackage {
625 "gnureadline" = super.buildPythonPackage {
626 name = "gnureadline-6.3.8";
626 name = "gnureadline-6.3.8";
627 doCheck = false;
627 doCheck = false;
628 src = fetchurl {
628 src = fetchurl {
629 url = "https://files.pythonhosted.org/packages/50/64/86085c823cd78f9df9d8e33dce0baa71618016f8860460b82cf6610e1eb3/gnureadline-6.3.8.tar.gz";
629 url = "https://files.pythonhosted.org/packages/50/64/86085c823cd78f9df9d8e33dce0baa71618016f8860460b82cf6610e1eb3/gnureadline-6.3.8.tar.gz";
630 sha256 = "0ddhj98x2nv45iz4aadk4b9m0b1kpsn1xhcbypn5cd556knhiqjq";
630 sha256 = "0ddhj98x2nv45iz4aadk4b9m0b1kpsn1xhcbypn5cd556knhiqjq";
631 };
631 };
632 meta = {
632 meta = {
633 license = [ { fullName = "GNU General Public License v3 (GPLv3)"; } pkgs.lib.licenses.gpl1 ];
633 license = [ { fullName = "GNU General Public License v3 (GPLv3)"; } pkgs.lib.licenses.gpl1 ];
634 };
634 };
635 };
635 };
636 "gprof2dot" = super.buildPythonPackage {
636 "gprof2dot" = super.buildPythonPackage {
637 name = "gprof2dot-2017.9.19";
637 name = "gprof2dot-2017.9.19";
638 doCheck = false;
638 doCheck = false;
639 src = fetchurl {
639 src = fetchurl {
640 url = "https://files.pythonhosted.org/packages/9d/36/f977122502979f3dfb50704979c9ed70e6b620787942b089bf1af15f5aba/gprof2dot-2017.9.19.tar.gz";
640 url = "https://files.pythonhosted.org/packages/9d/36/f977122502979f3dfb50704979c9ed70e6b620787942b089bf1af15f5aba/gprof2dot-2017.9.19.tar.gz";
641 sha256 = "17ih23ld2nzgc3xwgbay911l6lh96jp1zshmskm17n1gg2i7mg6f";
641 sha256 = "17ih23ld2nzgc3xwgbay911l6lh96jp1zshmskm17n1gg2i7mg6f";
642 };
642 };
643 meta = {
643 meta = {
644 license = [ { fullName = "GNU Lesser General Public License v3 or later (LGPLv3+)"; } { fullName = "LGPL"; } ];
644 license = [ { fullName = "GNU Lesser General Public License v3 or later (LGPLv3+)"; } { fullName = "LGPL"; } ];
645 };
645 };
646 };
646 };
647 "greenlet" = super.buildPythonPackage {
647 "greenlet" = super.buildPythonPackage {
648 name = "greenlet-0.4.15";
648 name = "greenlet-0.4.15";
649 doCheck = false;
649 doCheck = false;
650 src = fetchurl {
650 src = fetchurl {
651 url = "https://files.pythonhosted.org/packages/f8/e8/b30ae23b45f69aa3f024b46064c0ac8e5fcb4f22ace0dca8d6f9c8bbe5e7/greenlet-0.4.15.tar.gz";
651 url = "https://files.pythonhosted.org/packages/f8/e8/b30ae23b45f69aa3f024b46064c0ac8e5fcb4f22ace0dca8d6f9c8bbe5e7/greenlet-0.4.15.tar.gz";
652 sha256 = "1g4g1wwc472ds89zmqlpyan3fbnzpa8qm48z3z1y6mlk44z485ll";
652 sha256 = "1g4g1wwc472ds89zmqlpyan3fbnzpa8qm48z3z1y6mlk44z485ll";
653 };
653 };
654 meta = {
654 meta = {
655 license = [ pkgs.lib.licenses.mit ];
655 license = [ pkgs.lib.licenses.mit ];
656 };
656 };
657 };
657 };
658 "gunicorn" = super.buildPythonPackage {
658 "gunicorn" = super.buildPythonPackage {
659 name = "gunicorn-19.9.0";
659 name = "gunicorn-19.9.0";
660 doCheck = false;
660 doCheck = false;
661 src = fetchurl {
661 src = fetchurl {
662 url = "https://files.pythonhosted.org/packages/47/52/68ba8e5e8ba251e54006a49441f7ccabca83b6bef5aedacb4890596c7911/gunicorn-19.9.0.tar.gz";
662 url = "https://files.pythonhosted.org/packages/47/52/68ba8e5e8ba251e54006a49441f7ccabca83b6bef5aedacb4890596c7911/gunicorn-19.9.0.tar.gz";
663 sha256 = "1wzlf4xmn6qjirh5w81l6i6kqjnab1n1qqkh7zsj1yb6gh4n49ps";
663 sha256 = "1wzlf4xmn6qjirh5w81l6i6kqjnab1n1qqkh7zsj1yb6gh4n49ps";
664 };
664 };
665 meta = {
665 meta = {
666 license = [ pkgs.lib.licenses.mit ];
666 license = [ pkgs.lib.licenses.mit ];
667 };
667 };
668 };
668 };
669 "hupper" = super.buildPythonPackage {
669 "hupper" = super.buildPythonPackage {
670 name = "hupper-1.6.1";
670 name = "hupper-1.6.1";
671 doCheck = false;
671 doCheck = false;
672 src = fetchurl {
672 src = fetchurl {
673 url = "https://files.pythonhosted.org/packages/85/d9/e005d357b11249c5d70ddf5b7adab2e4c0da4e8b0531ff146917a04fe6c0/hupper-1.6.1.tar.gz";
673 url = "https://files.pythonhosted.org/packages/85/d9/e005d357b11249c5d70ddf5b7adab2e4c0da4e8b0531ff146917a04fe6c0/hupper-1.6.1.tar.gz";
674 sha256 = "0d3cvkc8ssgwk54wvhbifj56ry97qi10pfzwfk8vwzzcikbfp3zy";
674 sha256 = "0d3cvkc8ssgwk54wvhbifj56ry97qi10pfzwfk8vwzzcikbfp3zy";
675 };
675 };
676 meta = {
676 meta = {
677 license = [ pkgs.lib.licenses.mit ];
677 license = [ pkgs.lib.licenses.mit ];
678 };
678 };
679 };
679 };
680 "importlib-metadata" = super.buildPythonPackage {
680 "importlib-metadata" = super.buildPythonPackage {
681 name = "importlib-metadata-0.20";
681 name = "importlib-metadata-0.20";
682 doCheck = false;
682 doCheck = false;
683 propagatedBuildInputs = [
683 propagatedBuildInputs = [
684 self."zipp"
684 self."zipp"
685 self."contextlib2"
685 self."contextlib2"
686 self."configparser"
686 self."configparser"
687 self."pathlib2"
687 self."pathlib2"
688 ];
688 ];
689 src = fetchurl {
689 src = fetchurl {
690 url = "https://files.pythonhosted.org/packages/05/41/7d339dd7b507e97f67be812fdf29c4ad991ddd34b1ed0f3c54e8f1c4e0b3/importlib_metadata-0.20.tar.gz";
690 url = "https://files.pythonhosted.org/packages/05/41/7d339dd7b507e97f67be812fdf29c4ad991ddd34b1ed0f3c54e8f1c4e0b3/importlib_metadata-0.20.tar.gz";
691 sha256 = "13bshj8i98l9gxi6df4xbw1262phmawgr527as20brblwf93a55p";
691 sha256 = "13bshj8i98l9gxi6df4xbw1262phmawgr527as20brblwf93a55p";
692 };
692 };
693 meta = {
693 meta = {
694 license = [ pkgs.lib.licenses.asl20 ];
694 license = [ pkgs.lib.licenses.asl20 ];
695 };
695 };
696 };
696 };
697 "infrae.cache" = super.buildPythonPackage {
697 "infrae.cache" = super.buildPythonPackage {
698 name = "infrae.cache-1.0.1";
698 name = "infrae.cache-1.0.1";
699 doCheck = false;
699 doCheck = false;
700 propagatedBuildInputs = [
700 propagatedBuildInputs = [
701 self."beaker"
701 self."beaker"
702 self."repoze.lru"
702 self."repoze.lru"
703 ];
703 ];
704 src = fetchurl {
704 src = fetchurl {
705 url = "https://files.pythonhosted.org/packages/bb/f0/e7d5e984cf6592fd2807dc7bc44a93f9d18e04e6a61f87fdfb2622422d74/infrae.cache-1.0.1.tar.gz";
705 url = "https://files.pythonhosted.org/packages/bb/f0/e7d5e984cf6592fd2807dc7bc44a93f9d18e04e6a61f87fdfb2622422d74/infrae.cache-1.0.1.tar.gz";
706 sha256 = "1dvqsjn8vw253wz9d1pz17j79mf4bs53dvp2qxck2qdp1am1njw4";
706 sha256 = "1dvqsjn8vw253wz9d1pz17j79mf4bs53dvp2qxck2qdp1am1njw4";
707 };
707 };
708 meta = {
708 meta = {
709 license = [ pkgs.lib.licenses.zpl21 ];
709 license = [ pkgs.lib.licenses.zpl21 ];
710 };
710 };
711 };
711 };
712 "invoke" = super.buildPythonPackage {
712 "invoke" = super.buildPythonPackage {
713 name = "invoke-0.13.0";
713 name = "invoke-0.13.0";
714 doCheck = false;
714 doCheck = false;
715 src = fetchurl {
715 src = fetchurl {
716 url = "https://files.pythonhosted.org/packages/47/bf/d07ef52fa1ac645468858bbac7cb95b246a972a045e821493d17d89c81be/invoke-0.13.0.tar.gz";
716 url = "https://files.pythonhosted.org/packages/47/bf/d07ef52fa1ac645468858bbac7cb95b246a972a045e821493d17d89c81be/invoke-0.13.0.tar.gz";
717 sha256 = "0794vhgxfmkh0vzkkg5cfv1w82g3jc3xr18wim29far9qpx9468s";
717 sha256 = "0794vhgxfmkh0vzkkg5cfv1w82g3jc3xr18wim29far9qpx9468s";
718 };
718 };
719 meta = {
719 meta = {
720 license = [ pkgs.lib.licenses.bsdOriginal ];
720 license = [ pkgs.lib.licenses.bsdOriginal ];
721 };
721 };
722 };
722 };
723 "ipaddress" = super.buildPythonPackage {
723 "ipaddress" = super.buildPythonPackage {
724 name = "ipaddress-1.0.22";
724 name = "ipaddress-1.0.22";
725 doCheck = false;
725 doCheck = false;
726 src = fetchurl {
726 src = fetchurl {
727 url = "https://files.pythonhosted.org/packages/97/8d/77b8cedcfbf93676148518036c6b1ce7f8e14bf07e95d7fd4ddcb8cc052f/ipaddress-1.0.22.tar.gz";
727 url = "https://files.pythonhosted.org/packages/97/8d/77b8cedcfbf93676148518036c6b1ce7f8e14bf07e95d7fd4ddcb8cc052f/ipaddress-1.0.22.tar.gz";
728 sha256 = "0b570bm6xqpjwqis15pvdy6lyvvzfndjvkynilcddjj5x98wfimi";
728 sha256 = "0b570bm6xqpjwqis15pvdy6lyvvzfndjvkynilcddjj5x98wfimi";
729 };
729 };
730 meta = {
730 meta = {
731 license = [ pkgs.lib.licenses.psfl ];
731 license = [ pkgs.lib.licenses.psfl ];
732 };
732 };
733 };
733 };
734 "ipdb" = super.buildPythonPackage {
734 "ipdb" = super.buildPythonPackage {
735 name = "ipdb-0.12";
735 name = "ipdb-0.12";
736 doCheck = false;
736 doCheck = false;
737 propagatedBuildInputs = [
737 propagatedBuildInputs = [
738 self."setuptools"
738 self."setuptools"
739 self."ipython"
739 self."ipython"
740 ];
740 ];
741 src = fetchurl {
741 src = fetchurl {
742 url = "https://files.pythonhosted.org/packages/6d/43/c3c2e866a8803e196d6209595020a4a6db1a3c5d07c01455669497ae23d0/ipdb-0.12.tar.gz";
742 url = "https://files.pythonhosted.org/packages/6d/43/c3c2e866a8803e196d6209595020a4a6db1a3c5d07c01455669497ae23d0/ipdb-0.12.tar.gz";
743 sha256 = "1khr2n7xfy8hg65kj1bsrjq9g7656pp0ybfa8abpbzpdawji3qnw";
743 sha256 = "1khr2n7xfy8hg65kj1bsrjq9g7656pp0ybfa8abpbzpdawji3qnw";
744 };
744 };
745 meta = {
745 meta = {
746 license = [ pkgs.lib.licenses.bsdOriginal ];
746 license = [ pkgs.lib.licenses.bsdOriginal ];
747 };
747 };
748 };
748 };
749 "ipython" = super.buildPythonPackage {
749 "ipython" = super.buildPythonPackage {
750 name = "ipython-5.1.0";
750 name = "ipython-5.1.0";
751 doCheck = false;
751 doCheck = false;
752 propagatedBuildInputs = [
752 propagatedBuildInputs = [
753 self."setuptools"
753 self."setuptools"
754 self."decorator"
754 self."decorator"
755 self."pickleshare"
755 self."pickleshare"
756 self."simplegeneric"
756 self."simplegeneric"
757 self."traitlets"
757 self."traitlets"
758 self."prompt-toolkit"
758 self."prompt-toolkit"
759 self."pygments"
759 self."pygments"
760 self."pexpect"
760 self."pexpect"
761 self."backports.shutil-get-terminal-size"
761 self."backports.shutil-get-terminal-size"
762 self."pathlib2"
762 self."pathlib2"
763 self."pexpect"
763 self."pexpect"
764 ];
764 ];
765 src = fetchurl {
765 src = fetchurl {
766 url = "https://files.pythonhosted.org/packages/89/63/a9292f7cd9d0090a0f995e1167f3f17d5889dcbc9a175261719c513b9848/ipython-5.1.0.tar.gz";
766 url = "https://files.pythonhosted.org/packages/89/63/a9292f7cd9d0090a0f995e1167f3f17d5889dcbc9a175261719c513b9848/ipython-5.1.0.tar.gz";
767 sha256 = "0qdrf6aj9kvjczd5chj1my8y2iq09am9l8bb2a1334a52d76kx3y";
767 sha256 = "0qdrf6aj9kvjczd5chj1my8y2iq09am9l8bb2a1334a52d76kx3y";
768 };
768 };
769 meta = {
769 meta = {
770 license = [ pkgs.lib.licenses.bsdOriginal ];
770 license = [ pkgs.lib.licenses.bsdOriginal ];
771 };
771 };
772 };
772 };
773 "ipython-genutils" = super.buildPythonPackage {
773 "ipython-genutils" = super.buildPythonPackage {
774 name = "ipython-genutils-0.2.0";
774 name = "ipython-genutils-0.2.0";
775 doCheck = false;
775 doCheck = false;
776 src = fetchurl {
776 src = fetchurl {
777 url = "https://files.pythonhosted.org/packages/e8/69/fbeffffc05236398ebfcfb512b6d2511c622871dca1746361006da310399/ipython_genutils-0.2.0.tar.gz";
777 url = "https://files.pythonhosted.org/packages/e8/69/fbeffffc05236398ebfcfb512b6d2511c622871dca1746361006da310399/ipython_genutils-0.2.0.tar.gz";
778 sha256 = "1a4bc9y8hnvq6cp08qs4mckgm6i6ajpndp4g496rvvzcfmp12bpb";
778 sha256 = "1a4bc9y8hnvq6cp08qs4mckgm6i6ajpndp4g496rvvzcfmp12bpb";
779 };
779 };
780 meta = {
780 meta = {
781 license = [ pkgs.lib.licenses.bsdOriginal ];
781 license = [ pkgs.lib.licenses.bsdOriginal ];
782 };
782 };
783 };
783 };
784 "iso8601" = super.buildPythonPackage {
784 "iso8601" = super.buildPythonPackage {
785 name = "iso8601-0.1.12";
785 name = "iso8601-0.1.12";
786 doCheck = false;
786 doCheck = false;
787 src = fetchurl {
787 src = fetchurl {
788 url = "https://files.pythonhosted.org/packages/45/13/3db24895497345fb44c4248c08b16da34a9eb02643cea2754b21b5ed08b0/iso8601-0.1.12.tar.gz";
788 url = "https://files.pythonhosted.org/packages/45/13/3db24895497345fb44c4248c08b16da34a9eb02643cea2754b21b5ed08b0/iso8601-0.1.12.tar.gz";
789 sha256 = "10nyvvnrhw2w3p09v1ica4lgj6f4g9j3kkfx17qmraiq3w7b5i29";
789 sha256 = "10nyvvnrhw2w3p09v1ica4lgj6f4g9j3kkfx17qmraiq3w7b5i29";
790 };
790 };
791 meta = {
791 meta = {
792 license = [ pkgs.lib.licenses.mit ];
792 license = [ pkgs.lib.licenses.mit ];
793 };
793 };
794 };
794 };
795 "isodate" = super.buildPythonPackage {
795 "isodate" = super.buildPythonPackage {
796 name = "isodate-0.6.0";
796 name = "isodate-0.6.0";
797 doCheck = false;
797 doCheck = false;
798 propagatedBuildInputs = [
798 propagatedBuildInputs = [
799 self."six"
799 self."six"
800 ];
800 ];
801 src = fetchurl {
801 src = fetchurl {
802 url = "https://files.pythonhosted.org/packages/b1/80/fb8c13a4cd38eb5021dc3741a9e588e4d1de88d895c1910c6fc8a08b7a70/isodate-0.6.0.tar.gz";
802 url = "https://files.pythonhosted.org/packages/b1/80/fb8c13a4cd38eb5021dc3741a9e588e4d1de88d895c1910c6fc8a08b7a70/isodate-0.6.0.tar.gz";
803 sha256 = "1n7jkz68kk5pwni540pr5zdh99bf6ywydk1p5pdrqisrawylldif";
803 sha256 = "1n7jkz68kk5pwni540pr5zdh99bf6ywydk1p5pdrqisrawylldif";
804 };
804 };
805 meta = {
805 meta = {
806 license = [ pkgs.lib.licenses.bsdOriginal ];
806 license = [ pkgs.lib.licenses.bsdOriginal ];
807 };
807 };
808 };
808 };
809 "itsdangerous" = super.buildPythonPackage {
809 "itsdangerous" = super.buildPythonPackage {
810 name = "itsdangerous-0.24";
810 name = "itsdangerous-0.24";
811 doCheck = false;
811 doCheck = false;
812 src = fetchurl {
812 src = fetchurl {
813 url = "https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz";
813 url = "https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz";
814 sha256 = "06856q6x675ly542ig0plbqcyab6ksfzijlyf1hzhgg3sgwgrcyb";
814 sha256 = "06856q6x675ly542ig0plbqcyab6ksfzijlyf1hzhgg3sgwgrcyb";
815 };
815 };
816 meta = {
816 meta = {
817 license = [ pkgs.lib.licenses.bsdOriginal ];
817 license = [ pkgs.lib.licenses.bsdOriginal ];
818 };
818 };
819 };
819 };
820 "jinja2" = super.buildPythonPackage {
820 "jinja2" = super.buildPythonPackage {
821 name = "jinja2-2.9.6";
821 name = "jinja2-2.9.6";
822 doCheck = false;
822 doCheck = false;
823 propagatedBuildInputs = [
823 propagatedBuildInputs = [
824 self."markupsafe"
824 self."markupsafe"
825 ];
825 ];
826 src = fetchurl {
826 src = fetchurl {
827 url = "https://files.pythonhosted.org/packages/90/61/f820ff0076a2599dd39406dcb858ecb239438c02ce706c8e91131ab9c7f1/Jinja2-2.9.6.tar.gz";
827 url = "https://files.pythonhosted.org/packages/90/61/f820ff0076a2599dd39406dcb858ecb239438c02ce706c8e91131ab9c7f1/Jinja2-2.9.6.tar.gz";
828 sha256 = "1zzrkywhziqffrzks14kzixz7nd4yh2vc0fb04a68vfd2ai03anx";
828 sha256 = "1zzrkywhziqffrzks14kzixz7nd4yh2vc0fb04a68vfd2ai03anx";
829 };
829 };
830 meta = {
830 meta = {
831 license = [ pkgs.lib.licenses.bsdOriginal ];
831 license = [ pkgs.lib.licenses.bsdOriginal ];
832 };
832 };
833 };
833 };
834 "jsonschema" = super.buildPythonPackage {
834 "jsonschema" = super.buildPythonPackage {
835 name = "jsonschema-2.6.0";
835 name = "jsonschema-2.6.0";
836 doCheck = false;
836 doCheck = false;
837 propagatedBuildInputs = [
837 propagatedBuildInputs = [
838 self."functools32"
838 self."functools32"
839 ];
839 ];
840 src = fetchurl {
840 src = fetchurl {
841 url = "https://files.pythonhosted.org/packages/58/b9/171dbb07e18c6346090a37f03c7e74410a1a56123f847efed59af260a298/jsonschema-2.6.0.tar.gz";
841 url = "https://files.pythonhosted.org/packages/58/b9/171dbb07e18c6346090a37f03c7e74410a1a56123f847efed59af260a298/jsonschema-2.6.0.tar.gz";
842 sha256 = "00kf3zmpp9ya4sydffpifn0j0mzm342a2vzh82p6r0vh10cg7xbg";
842 sha256 = "00kf3zmpp9ya4sydffpifn0j0mzm342a2vzh82p6r0vh10cg7xbg";
843 };
843 };
844 meta = {
844 meta = {
845 license = [ pkgs.lib.licenses.mit ];
845 license = [ pkgs.lib.licenses.mit ];
846 };
846 };
847 };
847 };
848 "jupyter-client" = super.buildPythonPackage {
848 "jupyter-client" = super.buildPythonPackage {
849 name = "jupyter-client-5.0.0";
849 name = "jupyter-client-5.0.0";
850 doCheck = false;
850 doCheck = false;
851 propagatedBuildInputs = [
851 propagatedBuildInputs = [
852 self."traitlets"
852 self."traitlets"
853 self."jupyter-core"
853 self."jupyter-core"
854 self."pyzmq"
854 self."pyzmq"
855 self."python-dateutil"
855 self."python-dateutil"
856 ];
856 ];
857 src = fetchurl {
857 src = fetchurl {
858 url = "https://files.pythonhosted.org/packages/e5/6f/65412ed462202b90134b7e761b0b7e7f949e07a549c1755475333727b3d0/jupyter_client-5.0.0.tar.gz";
858 url = "https://files.pythonhosted.org/packages/e5/6f/65412ed462202b90134b7e761b0b7e7f949e07a549c1755475333727b3d0/jupyter_client-5.0.0.tar.gz";
859 sha256 = "0nxw4rqk4wsjhc87gjqd7pv89cb9dnimcfnmcmp85bmrvv1gjri7";
859 sha256 = "0nxw4rqk4wsjhc87gjqd7pv89cb9dnimcfnmcmp85bmrvv1gjri7";
860 };
860 };
861 meta = {
861 meta = {
862 license = [ pkgs.lib.licenses.bsdOriginal ];
862 license = [ pkgs.lib.licenses.bsdOriginal ];
863 };
863 };
864 };
864 };
865 "jupyter-core" = super.buildPythonPackage {
865 "jupyter-core" = super.buildPythonPackage {
866 name = "jupyter-core-4.5.0";
866 name = "jupyter-core-4.5.0";
867 doCheck = false;
867 doCheck = false;
868 propagatedBuildInputs = [
868 propagatedBuildInputs = [
869 self."traitlets"
869 self."traitlets"
870 ];
870 ];
871 src = fetchurl {
871 src = fetchurl {
872 url = "https://files.pythonhosted.org/packages/4a/de/ff4ca734656d17ebe0450807b59d728f45277e2e7f4b82bc9aae6cb82961/jupyter_core-4.5.0.tar.gz";
872 url = "https://files.pythonhosted.org/packages/4a/de/ff4ca734656d17ebe0450807b59d728f45277e2e7f4b82bc9aae6cb82961/jupyter_core-4.5.0.tar.gz";
873 sha256 = "1xr4pbghwk5hayn5wwnhb7z95380r45p79gf5if5pi1akwg7qvic";
873 sha256 = "1xr4pbghwk5hayn5wwnhb7z95380r45p79gf5if5pi1akwg7qvic";
874 };
874 };
875 meta = {
875 meta = {
876 license = [ pkgs.lib.licenses.bsdOriginal ];
876 license = [ pkgs.lib.licenses.bsdOriginal ];
877 };
877 };
878 };
878 };
879 "kombu" = super.buildPythonPackage {
879 "kombu" = super.buildPythonPackage {
880 name = "kombu-4.6.4";
880 name = "kombu-4.6.4";
881 doCheck = false;
881 doCheck = false;
882 propagatedBuildInputs = [
882 propagatedBuildInputs = [
883 self."amqp"
883 self."amqp"
884 self."importlib-metadata"
884 self."importlib-metadata"
885 ];
885 ];
886 src = fetchurl {
886 src = fetchurl {
887 url = "https://files.pythonhosted.org/packages/52/f2/5a64fc850b0533d2daf09a523406e51e85a8b2a4a2bc87a922a8906ba2aa/kombu-4.6.4.tar.gz";
887 url = "https://files.pythonhosted.org/packages/52/f2/5a64fc850b0533d2daf09a523406e51e85a8b2a4a2bc87a922a8906ba2aa/kombu-4.6.4.tar.gz";
888 sha256 = "16w02mvkxchz7041yia4h8xmqavci88szk18ynxvw4chzcnk3w75";
888 sha256 = "16w02mvkxchz7041yia4h8xmqavci88szk18ynxvw4chzcnk3w75";
889 };
889 };
890 meta = {
890 meta = {
891 license = [ pkgs.lib.licenses.bsdOriginal ];
891 license = [ pkgs.lib.licenses.bsdOriginal ];
892 };
892 };
893 };
893 };
894 "lxml" = super.buildPythonPackage {
894 "lxml" = super.buildPythonPackage {
895 name = "lxml-4.2.5";
895 name = "lxml-4.2.5";
896 doCheck = false;
896 doCheck = false;
897 src = fetchurl {
897 src = fetchurl {
898 url = "https://files.pythonhosted.org/packages/4b/20/ddf5eb3bd5c57582d2b4652b4bbcf8da301bdfe5d805cb94e805f4d7464d/lxml-4.2.5.tar.gz";
898 url = "https://files.pythonhosted.org/packages/4b/20/ddf5eb3bd5c57582d2b4652b4bbcf8da301bdfe5d805cb94e805f4d7464d/lxml-4.2.5.tar.gz";
899 sha256 = "0zw0y9hs0nflxhl9cs6ipwwh53szi3w2x06wl0k9cylyqac0cwin";
899 sha256 = "0zw0y9hs0nflxhl9cs6ipwwh53szi3w2x06wl0k9cylyqac0cwin";
900 };
900 };
901 meta = {
901 meta = {
902 license = [ pkgs.lib.licenses.bsdOriginal ];
902 license = [ pkgs.lib.licenses.bsdOriginal ];
903 };
903 };
904 };
904 };
905 "mako" = super.buildPythonPackage {
905 "mako" = super.buildPythonPackage {
906 name = "mako-1.0.7";
906 name = "mako-1.0.7";
907 doCheck = false;
907 doCheck = false;
908 propagatedBuildInputs = [
908 propagatedBuildInputs = [
909 self."markupsafe"
909 self."markupsafe"
910 ];
910 ];
911 src = fetchurl {
911 src = fetchurl {
912 url = "https://files.pythonhosted.org/packages/eb/f3/67579bb486517c0d49547f9697e36582cd19dafb5df9e687ed8e22de57fa/Mako-1.0.7.tar.gz";
912 url = "https://files.pythonhosted.org/packages/eb/f3/67579bb486517c0d49547f9697e36582cd19dafb5df9e687ed8e22de57fa/Mako-1.0.7.tar.gz";
913 sha256 = "1bi5gnr8r8dva06qpyx4kgjc6spm2k1y908183nbbaylggjzs0jf";
913 sha256 = "1bi5gnr8r8dva06qpyx4kgjc6spm2k1y908183nbbaylggjzs0jf";
914 };
914 };
915 meta = {
915 meta = {
916 license = [ pkgs.lib.licenses.mit ];
916 license = [ pkgs.lib.licenses.mit ];
917 };
917 };
918 };
918 };
919 "markdown" = super.buildPythonPackage {
919 "markdown" = super.buildPythonPackage {
920 name = "markdown-2.6.11";
920 name = "markdown-2.6.11";
921 doCheck = false;
921 doCheck = false;
922 src = fetchurl {
922 src = fetchurl {
923 url = "https://files.pythonhosted.org/packages/b3/73/fc5c850f44af5889192dff783b7b0d8f3fe8d30b65c8e3f78f8f0265fecf/Markdown-2.6.11.tar.gz";
923 url = "https://files.pythonhosted.org/packages/b3/73/fc5c850f44af5889192dff783b7b0d8f3fe8d30b65c8e3f78f8f0265fecf/Markdown-2.6.11.tar.gz";
924 sha256 = "108g80ryzykh8bj0i7jfp71510wrcixdi771lf2asyghgyf8cmm8";
924 sha256 = "108g80ryzykh8bj0i7jfp71510wrcixdi771lf2asyghgyf8cmm8";
925 };
925 };
926 meta = {
926 meta = {
927 license = [ pkgs.lib.licenses.bsdOriginal ];
927 license = [ pkgs.lib.licenses.bsdOriginal ];
928 };
928 };
929 };
929 };
930 "markupsafe" = super.buildPythonPackage {
930 "markupsafe" = super.buildPythonPackage {
931 name = "markupsafe-1.1.0";
931 name = "markupsafe-1.1.0";
932 doCheck = false;
932 doCheck = false;
933 src = fetchurl {
933 src = fetchurl {
934 url = "https://files.pythonhosted.org/packages/ac/7e/1b4c2e05809a4414ebce0892fe1e32c14ace86ca7d50c70f00979ca9b3a3/MarkupSafe-1.1.0.tar.gz";
934 url = "https://files.pythonhosted.org/packages/ac/7e/1b4c2e05809a4414ebce0892fe1e32c14ace86ca7d50c70f00979ca9b3a3/MarkupSafe-1.1.0.tar.gz";
935 sha256 = "1lxirjypbdd3l9jl4vliilhfnhy7c7f2vlldqg1b0i74khn375sf";
935 sha256 = "1lxirjypbdd3l9jl4vliilhfnhy7c7f2vlldqg1b0i74khn375sf";
936 };
936 };
937 meta = {
937 meta = {
938 license = [ pkgs.lib.licenses.bsdOriginal ];
938 license = [ pkgs.lib.licenses.bsdOriginal ];
939 };
939 };
940 };
940 };
941 "meld3" = super.buildPythonPackage {
941 "meld3" = super.buildPythonPackage {
942 name = "meld3-2.0.0";
942 name = "meld3-2.0.0";
943 doCheck = false;
943 doCheck = false;
944 src = fetchurl {
944 src = fetchurl {
945 url = "https://files.pythonhosted.org/packages/00/3b/023446ddc1bf0b519c369cbe88269c30c6a64bd10af4817c73f560c302f7/meld3-2.0.0.tar.gz";
945 url = "https://files.pythonhosted.org/packages/00/3b/023446ddc1bf0b519c369cbe88269c30c6a64bd10af4817c73f560c302f7/meld3-2.0.0.tar.gz";
946 sha256 = "1fbyafwi0d54394hkmp65nf6vk0qm4kipf5z60pdp4244rvadz8y";
946 sha256 = "1fbyafwi0d54394hkmp65nf6vk0qm4kipf5z60pdp4244rvadz8y";
947 };
947 };
948 meta = {
948 meta = {
949 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
949 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
950 };
950 };
951 };
951 };
952 "mistune" = super.buildPythonPackage {
952 "mistune" = super.buildPythonPackage {
953 name = "mistune-0.8.4";
953 name = "mistune-0.8.4";
954 doCheck = false;
954 doCheck = false;
955 src = fetchurl {
955 src = fetchurl {
956 url = "https://files.pythonhosted.org/packages/2d/a4/509f6e7783ddd35482feda27bc7f72e65b5e7dc910eca4ab2164daf9c577/mistune-0.8.4.tar.gz";
956 url = "https://files.pythonhosted.org/packages/2d/a4/509f6e7783ddd35482feda27bc7f72e65b5e7dc910eca4ab2164daf9c577/mistune-0.8.4.tar.gz";
957 sha256 = "0vkmsh0x480rni51lhyvigfdf06b9247z868pk3bal1wnnfl58sr";
957 sha256 = "0vkmsh0x480rni51lhyvigfdf06b9247z868pk3bal1wnnfl58sr";
958 };
958 };
959 meta = {
959 meta = {
960 license = [ pkgs.lib.licenses.bsdOriginal ];
960 license = [ pkgs.lib.licenses.bsdOriginal ];
961 };
961 };
962 };
962 };
963 "mock" = super.buildPythonPackage {
963 "mock" = super.buildPythonPackage {
964 name = "mock-1.0.1";
964 name = "mock-3.0.5";
965 doCheck = false;
965 doCheck = false;
966 propagatedBuildInputs = [
967 self."six"
968 self."funcsigs"
969 ];
966 src = fetchurl {
970 src = fetchurl {
967 url = "https://files.pythonhosted.org/packages/a2/52/7edcd94f0afb721a2d559a5b9aae8af4f8f2c79bc63fdbe8a8a6c9b23bbe/mock-1.0.1.tar.gz";
971 url = "https://files.pythonhosted.org/packages/2e/ab/4fe657d78b270aa6a32f027849513b829b41b0f28d9d8d7f8c3d29ea559a/mock-3.0.5.tar.gz";
968 sha256 = "0kzlsbki6q0awf89rc287f3aj8x431lrajf160a70z0ikhnxsfdq";
972 sha256 = "1hrp6j0yrx2xzylfv02qa8kph661m6yq4p0mc8fnimch9j4psrc3";
969 };
973 };
970 meta = {
974 meta = {
971 license = [ pkgs.lib.licenses.bsdOriginal ];
975 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "OSI Approved :: BSD License"; } ];
972 };
976 };
973 };
977 };
974 "more-itertools" = super.buildPythonPackage {
978 "more-itertools" = super.buildPythonPackage {
975 name = "more-itertools-5.0.0";
979 name = "more-itertools-5.0.0";
976 doCheck = false;
980 doCheck = false;
977 propagatedBuildInputs = [
981 propagatedBuildInputs = [
978 self."six"
982 self."six"
979 ];
983 ];
980 src = fetchurl {
984 src = fetchurl {
981 url = "https://files.pythonhosted.org/packages/dd/26/30fc0d541d9fdf55faf5ba4b0fd68f81d5bd2447579224820ad525934178/more-itertools-5.0.0.tar.gz";
985 url = "https://files.pythonhosted.org/packages/dd/26/30fc0d541d9fdf55faf5ba4b0fd68f81d5bd2447579224820ad525934178/more-itertools-5.0.0.tar.gz";
982 sha256 = "1r12cm6mcdwdzz7d47a6g4l437xsvapdlgyhqay3i2nrlv03da9q";
986 sha256 = "1r12cm6mcdwdzz7d47a6g4l437xsvapdlgyhqay3i2nrlv03da9q";
983 };
987 };
984 meta = {
988 meta = {
985 license = [ pkgs.lib.licenses.mit ];
989 license = [ pkgs.lib.licenses.mit ];
986 };
990 };
987 };
991 };
988 "msgpack-python" = super.buildPythonPackage {
992 "msgpack-python" = super.buildPythonPackage {
989 name = "msgpack-python-0.5.6";
993 name = "msgpack-python-0.5.6";
990 doCheck = false;
994 doCheck = false;
991 src = fetchurl {
995 src = fetchurl {
992 url = "https://files.pythonhosted.org/packages/8a/20/6eca772d1a5830336f84aca1d8198e5a3f4715cd1c7fc36d3cc7f7185091/msgpack-python-0.5.6.tar.gz";
996 url = "https://files.pythonhosted.org/packages/8a/20/6eca772d1a5830336f84aca1d8198e5a3f4715cd1c7fc36d3cc7f7185091/msgpack-python-0.5.6.tar.gz";
993 sha256 = "16wh8qgybmfh4pjp8vfv78mdlkxfmcasg78lzlnm6nslsfkci31p";
997 sha256 = "16wh8qgybmfh4pjp8vfv78mdlkxfmcasg78lzlnm6nslsfkci31p";
994 };
998 };
995 meta = {
999 meta = {
996 license = [ pkgs.lib.licenses.asl20 ];
1000 license = [ pkgs.lib.licenses.asl20 ];
997 };
1001 };
998 };
1002 };
999 "mysql-python" = super.buildPythonPackage {
1003 "mysql-python" = super.buildPythonPackage {
1000 name = "mysql-python-1.2.5";
1004 name = "mysql-python-1.2.5";
1001 doCheck = false;
1005 doCheck = false;
1002 src = fetchurl {
1006 src = fetchurl {
1003 url = "https://files.pythonhosted.org/packages/a5/e9/51b544da85a36a68debe7a7091f068d802fc515a3a202652828c73453cad/MySQL-python-1.2.5.zip";
1007 url = "https://files.pythonhosted.org/packages/a5/e9/51b544da85a36a68debe7a7091f068d802fc515a3a202652828c73453cad/MySQL-python-1.2.5.zip";
1004 sha256 = "0x0c2jg0bb3pp84njaqiic050qkyd7ymwhfvhipnimg58yv40441";
1008 sha256 = "0x0c2jg0bb3pp84njaqiic050qkyd7ymwhfvhipnimg58yv40441";
1005 };
1009 };
1006 meta = {
1010 meta = {
1007 license = [ pkgs.lib.licenses.gpl1 ];
1011 license = [ pkgs.lib.licenses.gpl1 ];
1008 };
1012 };
1009 };
1013 };
1010 "nbconvert" = super.buildPythonPackage {
1014 "nbconvert" = super.buildPythonPackage {
1011 name = "nbconvert-5.3.1";
1015 name = "nbconvert-5.3.1";
1012 doCheck = false;
1016 doCheck = false;
1013 propagatedBuildInputs = [
1017 propagatedBuildInputs = [
1014 self."mistune"
1018 self."mistune"
1015 self."jinja2"
1019 self."jinja2"
1016 self."pygments"
1020 self."pygments"
1017 self."traitlets"
1021 self."traitlets"
1018 self."jupyter-core"
1022 self."jupyter-core"
1019 self."nbformat"
1023 self."nbformat"
1020 self."entrypoints"
1024 self."entrypoints"
1021 self."bleach"
1025 self."bleach"
1022 self."pandocfilters"
1026 self."pandocfilters"
1023 self."testpath"
1027 self."testpath"
1024 ];
1028 ];
1025 src = fetchurl {
1029 src = fetchurl {
1026 url = "https://files.pythonhosted.org/packages/b9/a4/d0a0938ad6f5eeb4dea4e73d255c617ef94b0b2849d51194c9bbdb838412/nbconvert-5.3.1.tar.gz";
1030 url = "https://files.pythonhosted.org/packages/b9/a4/d0a0938ad6f5eeb4dea4e73d255c617ef94b0b2849d51194c9bbdb838412/nbconvert-5.3.1.tar.gz";
1027 sha256 = "1f9dkvpx186xjm4xab0qbph588mncp4vqk3fmxrsnqs43mks9c8j";
1031 sha256 = "1f9dkvpx186xjm4xab0qbph588mncp4vqk3fmxrsnqs43mks9c8j";
1028 };
1032 };
1029 meta = {
1033 meta = {
1030 license = [ pkgs.lib.licenses.bsdOriginal ];
1034 license = [ pkgs.lib.licenses.bsdOriginal ];
1031 };
1035 };
1032 };
1036 };
1033 "nbformat" = super.buildPythonPackage {
1037 "nbformat" = super.buildPythonPackage {
1034 name = "nbformat-4.4.0";
1038 name = "nbformat-4.4.0";
1035 doCheck = false;
1039 doCheck = false;
1036 propagatedBuildInputs = [
1040 propagatedBuildInputs = [
1037 self."ipython-genutils"
1041 self."ipython-genutils"
1038 self."traitlets"
1042 self."traitlets"
1039 self."jsonschema"
1043 self."jsonschema"
1040 self."jupyter-core"
1044 self."jupyter-core"
1041 ];
1045 ];
1042 src = fetchurl {
1046 src = fetchurl {
1043 url = "https://files.pythonhosted.org/packages/6e/0e/160754f7ae3e984863f585a3743b0ed1702043a81245907c8fae2d537155/nbformat-4.4.0.tar.gz";
1047 url = "https://files.pythonhosted.org/packages/6e/0e/160754f7ae3e984863f585a3743b0ed1702043a81245907c8fae2d537155/nbformat-4.4.0.tar.gz";
1044 sha256 = "00nlf08h8yc4q73nphfvfhxrcnilaqanb8z0mdy6nxk0vzq4wjgp";
1048 sha256 = "00nlf08h8yc4q73nphfvfhxrcnilaqanb8z0mdy6nxk0vzq4wjgp";
1045 };
1049 };
1046 meta = {
1050 meta = {
1047 license = [ pkgs.lib.licenses.bsdOriginal ];
1051 license = [ pkgs.lib.licenses.bsdOriginal ];
1048 };
1052 };
1049 };
1053 };
1050 "packaging" = super.buildPythonPackage {
1054 "packaging" = super.buildPythonPackage {
1051 name = "packaging-15.2";
1055 name = "packaging-15.2";
1052 doCheck = false;
1056 doCheck = false;
1053 src = fetchurl {
1057 src = fetchurl {
1054 url = "https://files.pythonhosted.org/packages/24/c4/185da1304f07047dc9e0c46c31db75c0351bd73458ac3efad7da3dbcfbe1/packaging-15.2.tar.gz";
1058 url = "https://files.pythonhosted.org/packages/24/c4/185da1304f07047dc9e0c46c31db75c0351bd73458ac3efad7da3dbcfbe1/packaging-15.2.tar.gz";
1055 sha256 = "1zn60w84bxvw6wypffka18ca66pa1k2cfrq3cq8fnsfja5m3k4ng";
1059 sha256 = "1zn60w84bxvw6wypffka18ca66pa1k2cfrq3cq8fnsfja5m3k4ng";
1056 };
1060 };
1057 meta = {
1061 meta = {
1058 license = [ pkgs.lib.licenses.asl20 ];
1062 license = [ pkgs.lib.licenses.asl20 ];
1059 };
1063 };
1060 };
1064 };
1061 "pandocfilters" = super.buildPythonPackage {
1065 "pandocfilters" = super.buildPythonPackage {
1062 name = "pandocfilters-1.4.2";
1066 name = "pandocfilters-1.4.2";
1063 doCheck = false;
1067 doCheck = false;
1064 src = fetchurl {
1068 src = fetchurl {
1065 url = "https://files.pythonhosted.org/packages/4c/ea/236e2584af67bb6df960832731a6e5325fd4441de001767da328c33368ce/pandocfilters-1.4.2.tar.gz";
1069 url = "https://files.pythonhosted.org/packages/4c/ea/236e2584af67bb6df960832731a6e5325fd4441de001767da328c33368ce/pandocfilters-1.4.2.tar.gz";
1066 sha256 = "1a8d9b7s48gmq9zj0pmbyv2sivn5i7m6mybgpkk4jm5vd7hp1pdk";
1070 sha256 = "1a8d9b7s48gmq9zj0pmbyv2sivn5i7m6mybgpkk4jm5vd7hp1pdk";
1067 };
1071 };
1068 meta = {
1072 meta = {
1069 license = [ pkgs.lib.licenses.bsdOriginal ];
1073 license = [ pkgs.lib.licenses.bsdOriginal ];
1070 };
1074 };
1071 };
1075 };
1072 "paste" = super.buildPythonPackage {
1076 "paste" = super.buildPythonPackage {
1073 name = "paste-3.0.8";
1077 name = "paste-3.0.8";
1074 doCheck = false;
1078 doCheck = false;
1075 propagatedBuildInputs = [
1079 propagatedBuildInputs = [
1076 self."six"
1080 self."six"
1077 ];
1081 ];
1078 src = fetchurl {
1082 src = fetchurl {
1079 url = "https://files.pythonhosted.org/packages/66/65/e3acf1663438483c1f6ced0b6c6f3b90da9f0faacb0a6e2aa0f3f9f4b235/Paste-3.0.8.tar.gz";
1083 url = "https://files.pythonhosted.org/packages/66/65/e3acf1663438483c1f6ced0b6c6f3b90da9f0faacb0a6e2aa0f3f9f4b235/Paste-3.0.8.tar.gz";
1080 sha256 = "05w1sh6ky4d7pmdb8nv82n13w22jcn3qsagg5ih3hjmbws9kkwf4";
1084 sha256 = "05w1sh6ky4d7pmdb8nv82n13w22jcn3qsagg5ih3hjmbws9kkwf4";
1081 };
1085 };
1082 meta = {
1086 meta = {
1083 license = [ pkgs.lib.licenses.mit ];
1087 license = [ pkgs.lib.licenses.mit ];
1084 };
1088 };
1085 };
1089 };
1086 "pastedeploy" = super.buildPythonPackage {
1090 "pastedeploy" = super.buildPythonPackage {
1087 name = "pastedeploy-2.0.1";
1091 name = "pastedeploy-2.0.1";
1088 doCheck = false;
1092 doCheck = false;
1089 src = fetchurl {
1093 src = fetchurl {
1090 url = "https://files.pythonhosted.org/packages/19/a0/5623701df7e2478a68a1b685d1a84518024eef994cde7e4da8449a31616f/PasteDeploy-2.0.1.tar.gz";
1094 url = "https://files.pythonhosted.org/packages/19/a0/5623701df7e2478a68a1b685d1a84518024eef994cde7e4da8449a31616f/PasteDeploy-2.0.1.tar.gz";
1091 sha256 = "02imfbbx1mi2h546f3sr37m47dk9qizaqhzzlhx8bkzxa6fzn8yl";
1095 sha256 = "02imfbbx1mi2h546f3sr37m47dk9qizaqhzzlhx8bkzxa6fzn8yl";
1092 };
1096 };
1093 meta = {
1097 meta = {
1094 license = [ pkgs.lib.licenses.mit ];
1098 license = [ pkgs.lib.licenses.mit ];
1095 };
1099 };
1096 };
1100 };
1097 "pastescript" = super.buildPythonPackage {
1101 "pastescript" = super.buildPythonPackage {
1098 name = "pastescript-3.1.0";
1102 name = "pastescript-3.1.0";
1099 doCheck = false;
1103 doCheck = false;
1100 propagatedBuildInputs = [
1104 propagatedBuildInputs = [
1101 self."paste"
1105 self."paste"
1102 self."pastedeploy"
1106 self."pastedeploy"
1103 self."six"
1107 self."six"
1104 ];
1108 ];
1105 src = fetchurl {
1109 src = fetchurl {
1106 url = "https://files.pythonhosted.org/packages/9e/1d/14db1c283eb21a5d36b6ba1114c13b709629711e64acab653d9994fe346f/PasteScript-3.1.0.tar.gz";
1110 url = "https://files.pythonhosted.org/packages/9e/1d/14db1c283eb21a5d36b6ba1114c13b709629711e64acab653d9994fe346f/PasteScript-3.1.0.tar.gz";
1107 sha256 = "02qcxjjr32ks7a6d4f533wl34ysc7yhwlrfcyqwqbzr52250v4fs";
1111 sha256 = "02qcxjjr32ks7a6d4f533wl34ysc7yhwlrfcyqwqbzr52250v4fs";
1108 };
1112 };
1109 meta = {
1113 meta = {
1110 license = [ pkgs.lib.licenses.mit ];
1114 license = [ pkgs.lib.licenses.mit ];
1111 };
1115 };
1112 };
1116 };
1113 "pathlib2" = super.buildPythonPackage {
1117 "pathlib2" = super.buildPythonPackage {
1114 name = "pathlib2-2.3.4";
1118 name = "pathlib2-2.3.4";
1115 doCheck = false;
1119 doCheck = false;
1116 propagatedBuildInputs = [
1120 propagatedBuildInputs = [
1117 self."six"
1121 self."six"
1118 self."scandir"
1122 self."scandir"
1119 ];
1123 ];
1120 src = fetchurl {
1124 src = fetchurl {
1121 url = "https://files.pythonhosted.org/packages/b5/f4/9c7cc726ece2498b6c8b62d3262aa43f59039b953fe23c9964ac5e18d40b/pathlib2-2.3.4.tar.gz";
1125 url = "https://files.pythonhosted.org/packages/b5/f4/9c7cc726ece2498b6c8b62d3262aa43f59039b953fe23c9964ac5e18d40b/pathlib2-2.3.4.tar.gz";
1122 sha256 = "1y0f9rkm1924zrc5dn4bwxlhgdkbml82lkcc28l5rgmr7d918q24";
1126 sha256 = "1y0f9rkm1924zrc5dn4bwxlhgdkbml82lkcc28l5rgmr7d918q24";
1123 };
1127 };
1124 meta = {
1128 meta = {
1125 license = [ pkgs.lib.licenses.mit ];
1129 license = [ pkgs.lib.licenses.mit ];
1126 };
1130 };
1127 };
1131 };
1128 "peppercorn" = super.buildPythonPackage {
1132 "peppercorn" = super.buildPythonPackage {
1129 name = "peppercorn-0.6";
1133 name = "peppercorn-0.6";
1130 doCheck = false;
1134 doCheck = false;
1131 src = fetchurl {
1135 src = fetchurl {
1132 url = "https://files.pythonhosted.org/packages/e4/77/93085de7108cdf1a0b092ff443872a8f9442c736d7ddebdf2f27627935f4/peppercorn-0.6.tar.gz";
1136 url = "https://files.pythonhosted.org/packages/e4/77/93085de7108cdf1a0b092ff443872a8f9442c736d7ddebdf2f27627935f4/peppercorn-0.6.tar.gz";
1133 sha256 = "1ip4bfwcpwkq9hz2dai14k2cyabvwrnvcvrcmzxmqm04g8fnimwn";
1137 sha256 = "1ip4bfwcpwkq9hz2dai14k2cyabvwrnvcvrcmzxmqm04g8fnimwn";
1134 };
1138 };
1135 meta = {
1139 meta = {
1136 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1140 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1137 };
1141 };
1138 };
1142 };
1139 "pexpect" = super.buildPythonPackage {
1143 "pexpect" = super.buildPythonPackage {
1140 name = "pexpect-4.7.0";
1144 name = "pexpect-4.7.0";
1141 doCheck = false;
1145 doCheck = false;
1142 propagatedBuildInputs = [
1146 propagatedBuildInputs = [
1143 self."ptyprocess"
1147 self."ptyprocess"
1144 ];
1148 ];
1145 src = fetchurl {
1149 src = fetchurl {
1146 url = "https://files.pythonhosted.org/packages/1c/b1/362a0d4235496cb42c33d1d8732b5e2c607b0129ad5fdd76f5a583b9fcb3/pexpect-4.7.0.tar.gz";
1150 url = "https://files.pythonhosted.org/packages/1c/b1/362a0d4235496cb42c33d1d8732b5e2c607b0129ad5fdd76f5a583b9fcb3/pexpect-4.7.0.tar.gz";
1147 sha256 = "1sv2rri15zwhds85a4kamwh9pj49qcxv7m4miyr4jfpfwv81yb4y";
1151 sha256 = "1sv2rri15zwhds85a4kamwh9pj49qcxv7m4miyr4jfpfwv81yb4y";
1148 };
1152 };
1149 meta = {
1153 meta = {
1150 license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ];
1154 license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ];
1151 };
1155 };
1152 };
1156 };
1153 "pickleshare" = super.buildPythonPackage {
1157 "pickleshare" = super.buildPythonPackage {
1154 name = "pickleshare-0.7.5";
1158 name = "pickleshare-0.7.5";
1155 doCheck = false;
1159 doCheck = false;
1156 propagatedBuildInputs = [
1160 propagatedBuildInputs = [
1157 self."pathlib2"
1161 self."pathlib2"
1158 ];
1162 ];
1159 src = fetchurl {
1163 src = fetchurl {
1160 url = "https://files.pythonhosted.org/packages/d8/b6/df3c1c9b616e9c0edbc4fbab6ddd09df9535849c64ba51fcb6531c32d4d8/pickleshare-0.7.5.tar.gz";
1164 url = "https://files.pythonhosted.org/packages/d8/b6/df3c1c9b616e9c0edbc4fbab6ddd09df9535849c64ba51fcb6531c32d4d8/pickleshare-0.7.5.tar.gz";
1161 sha256 = "1jmghg3c53yp1i8cm6pcrm280ayi8621rwyav9fac7awjr3kss47";
1165 sha256 = "1jmghg3c53yp1i8cm6pcrm280ayi8621rwyav9fac7awjr3kss47";
1162 };
1166 };
1163 meta = {
1167 meta = {
1164 license = [ pkgs.lib.licenses.mit ];
1168 license = [ pkgs.lib.licenses.mit ];
1165 };
1169 };
1166 };
1170 };
1167 "plaster" = super.buildPythonPackage {
1171 "plaster" = super.buildPythonPackage {
1168 name = "plaster-1.0";
1172 name = "plaster-1.0";
1169 doCheck = false;
1173 doCheck = false;
1170 propagatedBuildInputs = [
1174 propagatedBuildInputs = [
1171 self."setuptools"
1175 self."setuptools"
1172 ];
1176 ];
1173 src = fetchurl {
1177 src = fetchurl {
1174 url = "https://files.pythonhosted.org/packages/37/e1/56d04382d718d32751017d32f351214384e529b794084eee20bb52405563/plaster-1.0.tar.gz";
1178 url = "https://files.pythonhosted.org/packages/37/e1/56d04382d718d32751017d32f351214384e529b794084eee20bb52405563/plaster-1.0.tar.gz";
1175 sha256 = "1hy8k0nv2mxq94y5aysk6hjk9ryb4bsd13g83m60hcyzxz3wflc3";
1179 sha256 = "1hy8k0nv2mxq94y5aysk6hjk9ryb4bsd13g83m60hcyzxz3wflc3";
1176 };
1180 };
1177 meta = {
1181 meta = {
1178 license = [ pkgs.lib.licenses.mit ];
1182 license = [ pkgs.lib.licenses.mit ];
1179 };
1183 };
1180 };
1184 };
1181 "plaster-pastedeploy" = super.buildPythonPackage {
1185 "plaster-pastedeploy" = super.buildPythonPackage {
1182 name = "plaster-pastedeploy-0.7";
1186 name = "plaster-pastedeploy-0.7";
1183 doCheck = false;
1187 doCheck = false;
1184 propagatedBuildInputs = [
1188 propagatedBuildInputs = [
1185 self."pastedeploy"
1189 self."pastedeploy"
1186 self."plaster"
1190 self."plaster"
1187 ];
1191 ];
1188 src = fetchurl {
1192 src = fetchurl {
1189 url = "https://files.pythonhosted.org/packages/99/69/2d3bc33091249266a1bd3cf24499e40ab31d54dffb4a7d76fe647950b98c/plaster_pastedeploy-0.7.tar.gz";
1193 url = "https://files.pythonhosted.org/packages/99/69/2d3bc33091249266a1bd3cf24499e40ab31d54dffb4a7d76fe647950b98c/plaster_pastedeploy-0.7.tar.gz";
1190 sha256 = "1zg7gcsvc1kzay1ry5p699rg2qavfsxqwl17mqxzr0gzw6j9679r";
1194 sha256 = "1zg7gcsvc1kzay1ry5p699rg2qavfsxqwl17mqxzr0gzw6j9679r";
1191 };
1195 };
1192 meta = {
1196 meta = {
1193 license = [ pkgs.lib.licenses.mit ];
1197 license = [ pkgs.lib.licenses.mit ];
1194 };
1198 };
1195 };
1199 };
1196 "pluggy" = super.buildPythonPackage {
1200 "pluggy" = super.buildPythonPackage {
1197 name = "pluggy-0.11.0";
1201 name = "pluggy-0.11.0";
1198 doCheck = false;
1202 doCheck = false;
1199 src = fetchurl {
1203 src = fetchurl {
1200 url = "https://files.pythonhosted.org/packages/0d/a1/862ab336e8128fde20981d2c1aa8506693412daf5083b1911d539412676b/pluggy-0.11.0.tar.gz";
1204 url = "https://files.pythonhosted.org/packages/0d/a1/862ab336e8128fde20981d2c1aa8506693412daf5083b1911d539412676b/pluggy-0.11.0.tar.gz";
1201 sha256 = "10511a54dvafw1jrk75mrhml53c7b7w4yaw7241696lc2hfvr895";
1205 sha256 = "10511a54dvafw1jrk75mrhml53c7b7w4yaw7241696lc2hfvr895";
1202 };
1206 };
1203 meta = {
1207 meta = {
1204 license = [ pkgs.lib.licenses.mit ];
1208 license = [ pkgs.lib.licenses.mit ];
1205 };
1209 };
1206 };
1210 };
1207 "prompt-toolkit" = super.buildPythonPackage {
1211 "prompt-toolkit" = super.buildPythonPackage {
1208 name = "prompt-toolkit-1.0.16";
1212 name = "prompt-toolkit-1.0.16";
1209 doCheck = false;
1213 doCheck = false;
1210 propagatedBuildInputs = [
1214 propagatedBuildInputs = [
1211 self."six"
1215 self."six"
1212 self."wcwidth"
1216 self."wcwidth"
1213 ];
1217 ];
1214 src = fetchurl {
1218 src = fetchurl {
1215 url = "https://files.pythonhosted.org/packages/f1/03/bb36771dc9fa7553ac4bdc639a9ecdf6fda0ff4176faf940d97e3c16e41d/prompt_toolkit-1.0.16.tar.gz";
1219 url = "https://files.pythonhosted.org/packages/f1/03/bb36771dc9fa7553ac4bdc639a9ecdf6fda0ff4176faf940d97e3c16e41d/prompt_toolkit-1.0.16.tar.gz";
1216 sha256 = "1d65hm6nf0cbq0q0121m60zzy4s1fpg9fn761s1yxf08dridvkn1";
1220 sha256 = "1d65hm6nf0cbq0q0121m60zzy4s1fpg9fn761s1yxf08dridvkn1";
1217 };
1221 };
1218 meta = {
1222 meta = {
1219 license = [ pkgs.lib.licenses.bsdOriginal ];
1223 license = [ pkgs.lib.licenses.bsdOriginal ];
1220 };
1224 };
1221 };
1225 };
1222 "psutil" = super.buildPythonPackage {
1226 "psutil" = super.buildPythonPackage {
1223 name = "psutil-5.6.3";
1227 name = "psutil-5.6.3";
1224 doCheck = false;
1228 doCheck = false;
1225 src = fetchurl {
1229 src = fetchurl {
1226 url = "https://files.pythonhosted.org/packages/1c/ca/5b8c1fe032a458c2c4bcbe509d1401dca9dda35c7fc46b36bb81c2834740/psutil-5.6.3.tar.gz";
1230 url = "https://files.pythonhosted.org/packages/1c/ca/5b8c1fe032a458c2c4bcbe509d1401dca9dda35c7fc46b36bb81c2834740/psutil-5.6.3.tar.gz";
1227 sha256 = "1wv31zly44qj0rp2acg58xbnc7bf6ffyadasq093l455q30qafl6";
1231 sha256 = "1wv31zly44qj0rp2acg58xbnc7bf6ffyadasq093l455q30qafl6";
1228 };
1232 };
1229 meta = {
1233 meta = {
1230 license = [ pkgs.lib.licenses.bsdOriginal ];
1234 license = [ pkgs.lib.licenses.bsdOriginal ];
1231 };
1235 };
1232 };
1236 };
1233 "psycopg2" = super.buildPythonPackage {
1237 "psycopg2" = super.buildPythonPackage {
1234 name = "psycopg2-2.8.3";
1238 name = "psycopg2-2.8.3";
1235 doCheck = false;
1239 doCheck = false;
1236 src = fetchurl {
1240 src = fetchurl {
1237 url = "https://files.pythonhosted.org/packages/5c/1c/6997288da181277a0c29bc39a5f9143ff20b8c99f2a7d059cfb55163e165/psycopg2-2.8.3.tar.gz";
1241 url = "https://files.pythonhosted.org/packages/5c/1c/6997288da181277a0c29bc39a5f9143ff20b8c99f2a7d059cfb55163e165/psycopg2-2.8.3.tar.gz";
1238 sha256 = "0ms4kx0p5n281l89awccix4d05ybmdngnjjpi9jbzd0rhf1nwyl9";
1242 sha256 = "0ms4kx0p5n281l89awccix4d05ybmdngnjjpi9jbzd0rhf1nwyl9";
1239 };
1243 };
1240 meta = {
1244 meta = {
1241 license = [ pkgs.lib.licenses.zpl21 { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "LGPL with exceptions or ZPL"; } ];
1245 license = [ pkgs.lib.licenses.zpl21 { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "LGPL with exceptions or ZPL"; } ];
1242 };
1246 };
1243 };
1247 };
1244 "ptyprocess" = super.buildPythonPackage {
1248 "ptyprocess" = super.buildPythonPackage {
1245 name = "ptyprocess-0.6.0";
1249 name = "ptyprocess-0.6.0";
1246 doCheck = false;
1250 doCheck = false;
1247 src = fetchurl {
1251 src = fetchurl {
1248 url = "https://files.pythonhosted.org/packages/7d/2d/e4b8733cf79b7309d84c9081a4ab558c89d8c89da5961bf4ddb050ca1ce0/ptyprocess-0.6.0.tar.gz";
1252 url = "https://files.pythonhosted.org/packages/7d/2d/e4b8733cf79b7309d84c9081a4ab558c89d8c89da5961bf4ddb050ca1ce0/ptyprocess-0.6.0.tar.gz";
1249 sha256 = "1h4lcd3w5nrxnsk436ar7fwkiy5rfn5wj2xwy9l0r4mdqnf2jgwj";
1253 sha256 = "1h4lcd3w5nrxnsk436ar7fwkiy5rfn5wj2xwy9l0r4mdqnf2jgwj";
1250 };
1254 };
1251 meta = {
1255 meta = {
1252 license = [ ];
1256 license = [ ];
1253 };
1257 };
1254 };
1258 };
1255 "py" = super.buildPythonPackage {
1259 "py" = super.buildPythonPackage {
1256 name = "py-1.6.0";
1260 name = "py-1.8.0";
1257 doCheck = false;
1261 doCheck = false;
1258 src = fetchurl {
1262 src = fetchurl {
1259 url = "https://files.pythonhosted.org/packages/4f/38/5f427d1eedae73063ce4da680d2bae72014995f9fdeaa57809df61c968cd/py-1.6.0.tar.gz";
1263 url = "https://files.pythonhosted.org/packages/f1/5a/87ca5909f400a2de1561f1648883af74345fe96349f34f737cdfc94eba8c/py-1.8.0.tar.gz";
1260 sha256 = "1wcs3zv9wl5m5x7p16avqj2gsrviyb23yvc3pr330isqs0sh98q6";
1264 sha256 = "0lsy1gajva083pzc7csj1cvbmminb7b4l6a0prdzyb3fd829nqyw";
1261 };
1265 };
1262 meta = {
1266 meta = {
1263 license = [ pkgs.lib.licenses.mit ];
1267 license = [ pkgs.lib.licenses.mit ];
1264 };
1268 };
1265 };
1269 };
1266 "py-bcrypt" = super.buildPythonPackage {
1270 "py-bcrypt" = super.buildPythonPackage {
1267 name = "py-bcrypt-0.4";
1271 name = "py-bcrypt-0.4";
1268 doCheck = false;
1272 doCheck = false;
1269 src = fetchurl {
1273 src = fetchurl {
1270 url = "https://files.pythonhosted.org/packages/68/b1/1c3068c5c4d2e35c48b38dcc865301ebfdf45f54507086ac65ced1fd3b3d/py-bcrypt-0.4.tar.gz";
1274 url = "https://files.pythonhosted.org/packages/68/b1/1c3068c5c4d2e35c48b38dcc865301ebfdf45f54507086ac65ced1fd3b3d/py-bcrypt-0.4.tar.gz";
1271 sha256 = "0y6smdggwi5s72v6p1nn53dg6w05hna3d264cq6kas0lap73p8az";
1275 sha256 = "0y6smdggwi5s72v6p1nn53dg6w05hna3d264cq6kas0lap73p8az";
1272 };
1276 };
1273 meta = {
1277 meta = {
1274 license = [ pkgs.lib.licenses.bsdOriginal ];
1278 license = [ pkgs.lib.licenses.bsdOriginal ];
1275 };
1279 };
1276 };
1280 };
1277 "py-gfm" = super.buildPythonPackage {
1281 "py-gfm" = super.buildPythonPackage {
1278 name = "py-gfm-0.1.4";
1282 name = "py-gfm-0.1.4";
1279 doCheck = false;
1283 doCheck = false;
1280 propagatedBuildInputs = [
1284 propagatedBuildInputs = [
1281 self."setuptools"
1285 self."setuptools"
1282 self."markdown"
1286 self."markdown"
1283 ];
1287 ];
1284 src = fetchurl {
1288 src = fetchurl {
1285 url = "https://files.pythonhosted.org/packages/06/ee/004a03a1d92bb386dae44f6dd087db541bc5093374f1637d4d4ae5596cc2/py-gfm-0.1.4.tar.gz";
1289 url = "https://files.pythonhosted.org/packages/06/ee/004a03a1d92bb386dae44f6dd087db541bc5093374f1637d4d4ae5596cc2/py-gfm-0.1.4.tar.gz";
1286 sha256 = "0zip06g2isivx8fzgqd4n9qzsa22c25jas1rsb7m2rnjg72m0rzg";
1290 sha256 = "0zip06g2isivx8fzgqd4n9qzsa22c25jas1rsb7m2rnjg72m0rzg";
1287 };
1291 };
1288 meta = {
1292 meta = {
1289 license = [ pkgs.lib.licenses.bsdOriginal ];
1293 license = [ pkgs.lib.licenses.bsdOriginal ];
1290 };
1294 };
1291 };
1295 };
1292 "pyasn1" = super.buildPythonPackage {
1296 "pyasn1" = super.buildPythonPackage {
1293 name = "pyasn1-0.4.7";
1297 name = "pyasn1-0.4.7";
1294 doCheck = false;
1298 doCheck = false;
1295 src = fetchurl {
1299 src = fetchurl {
1296 url = "https://files.pythonhosted.org/packages/ca/f8/2a60a2c88a97558bdd289b6dc9eb75b00bd90ff34155d681ba6dbbcb46b2/pyasn1-0.4.7.tar.gz";
1300 url = "https://files.pythonhosted.org/packages/ca/f8/2a60a2c88a97558bdd289b6dc9eb75b00bd90ff34155d681ba6dbbcb46b2/pyasn1-0.4.7.tar.gz";
1297 sha256 = "0146ryp4g09ycy8p3l2vigmgfg42n4gb8whgg8cysrhxr9b56jd9";
1301 sha256 = "0146ryp4g09ycy8p3l2vigmgfg42n4gb8whgg8cysrhxr9b56jd9";
1298 };
1302 };
1299 meta = {
1303 meta = {
1300 license = [ pkgs.lib.licenses.bsdOriginal ];
1304 license = [ pkgs.lib.licenses.bsdOriginal ];
1301 };
1305 };
1302 };
1306 };
1303 "pyasn1-modules" = super.buildPythonPackage {
1307 "pyasn1-modules" = super.buildPythonPackage {
1304 name = "pyasn1-modules-0.2.6";
1308 name = "pyasn1-modules-0.2.6";
1305 doCheck = false;
1309 doCheck = false;
1306 propagatedBuildInputs = [
1310 propagatedBuildInputs = [
1307 self."pyasn1"
1311 self."pyasn1"
1308 ];
1312 ];
1309 src = fetchurl {
1313 src = fetchurl {
1310 url = "https://files.pythonhosted.org/packages/f1/a9/a1ef72a0e43feff643cf0130a08123dea76205e7a0dda37e3efb5f054a31/pyasn1-modules-0.2.6.tar.gz";
1314 url = "https://files.pythonhosted.org/packages/f1/a9/a1ef72a0e43feff643cf0130a08123dea76205e7a0dda37e3efb5f054a31/pyasn1-modules-0.2.6.tar.gz";
1311 sha256 = "08hph9j1r018drnrny29l7dl2q0cin78csswrhwrh8jmq61pmha3";
1315 sha256 = "08hph9j1r018drnrny29l7dl2q0cin78csswrhwrh8jmq61pmha3";
1312 };
1316 };
1313 meta = {
1317 meta = {
1314 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ];
1318 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ];
1315 };
1319 };
1316 };
1320 };
1317 "pycparser" = super.buildPythonPackage {
1321 "pycparser" = super.buildPythonPackage {
1318 name = "pycparser-2.19";
1322 name = "pycparser-2.19";
1319 doCheck = false;
1323 doCheck = false;
1320 src = fetchurl {
1324 src = fetchurl {
1321 url = "https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz";
1325 url = "https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz";
1322 sha256 = "1cr5dcj9628lkz1qlwq3fv97c25363qppkmcayqvd05dpy573259";
1326 sha256 = "1cr5dcj9628lkz1qlwq3fv97c25363qppkmcayqvd05dpy573259";
1323 };
1327 };
1324 meta = {
1328 meta = {
1325 license = [ pkgs.lib.licenses.bsdOriginal ];
1329 license = [ pkgs.lib.licenses.bsdOriginal ];
1326 };
1330 };
1327 };
1331 };
1328 "pycrypto" = super.buildPythonPackage {
1332 "pycrypto" = super.buildPythonPackage {
1329 name = "pycrypto-2.6.1";
1333 name = "pycrypto-2.6.1";
1330 doCheck = false;
1334 doCheck = false;
1331 src = fetchurl {
1335 src = fetchurl {
1332 url = "https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz";
1336 url = "https://files.pythonhosted.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz";
1333 sha256 = "0g0ayql5b9mkjam8hym6zyg6bv77lbh66rv1fyvgqb17kfc1xkpj";
1337 sha256 = "0g0ayql5b9mkjam8hym6zyg6bv77lbh66rv1fyvgqb17kfc1xkpj";
1334 };
1338 };
1335 meta = {
1339 meta = {
1336 license = [ pkgs.lib.licenses.publicDomain ];
1340 license = [ pkgs.lib.licenses.publicDomain ];
1337 };
1341 };
1338 };
1342 };
1339 "pycurl" = super.buildPythonPackage {
1343 "pycurl" = super.buildPythonPackage {
1340 name = "pycurl-7.43.0.3";
1344 name = "pycurl-7.43.0.3";
1341 doCheck = false;
1345 doCheck = false;
1342 src = fetchurl {
1346 src = fetchurl {
1343 url = "https://files.pythonhosted.org/packages/ac/b3/0f3979633b7890bab6098d84c84467030b807a1e2b31f5d30103af5a71ca/pycurl-7.43.0.3.tar.gz";
1347 url = "https://files.pythonhosted.org/packages/ac/b3/0f3979633b7890bab6098d84c84467030b807a1e2b31f5d30103af5a71ca/pycurl-7.43.0.3.tar.gz";
1344 sha256 = "13nsvqhvnmnvfk75s8iynqsgszyv06cjp4drd3psi7zpbh63623g";
1348 sha256 = "13nsvqhvnmnvfk75s8iynqsgszyv06cjp4drd3psi7zpbh63623g";
1345 };
1349 };
1346 meta = {
1350 meta = {
1347 license = [ pkgs.lib.licenses.mit { fullName = "LGPL/MIT"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ];
1351 license = [ pkgs.lib.licenses.mit { fullName = "LGPL/MIT"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ];
1348 };
1352 };
1349 };
1353 };
1350 "pygments" = super.buildPythonPackage {
1354 "pygments" = super.buildPythonPackage {
1351 name = "pygments-2.4.2";
1355 name = "pygments-2.4.2";
1352 doCheck = false;
1356 doCheck = false;
1353 src = fetchurl {
1357 src = fetchurl {
1354 url = "https://files.pythonhosted.org/packages/7e/ae/26808275fc76bf2832deb10d3a3ed3107bc4de01b85dcccbe525f2cd6d1e/Pygments-2.4.2.tar.gz";
1358 url = "https://files.pythonhosted.org/packages/7e/ae/26808275fc76bf2832deb10d3a3ed3107bc4de01b85dcccbe525f2cd6d1e/Pygments-2.4.2.tar.gz";
1355 sha256 = "15v2sqm5g12bqa0c7wikfh9ck2nl97ayizy1hpqhmws5gqalq748";
1359 sha256 = "15v2sqm5g12bqa0c7wikfh9ck2nl97ayizy1hpqhmws5gqalq748";
1356 };
1360 };
1357 meta = {
1361 meta = {
1358 license = [ pkgs.lib.licenses.bsdOriginal ];
1362 license = [ pkgs.lib.licenses.bsdOriginal ];
1359 };
1363 };
1360 };
1364 };
1361 "pymysql" = super.buildPythonPackage {
1365 "pymysql" = super.buildPythonPackage {
1362 name = "pymysql-0.8.1";
1366 name = "pymysql-0.8.1";
1363 doCheck = false;
1367 doCheck = false;
1364 src = fetchurl {
1368 src = fetchurl {
1365 url = "https://files.pythonhosted.org/packages/44/39/6bcb83cae0095a31b6be4511707fdf2009d3e29903a55a0494d3a9a2fac0/PyMySQL-0.8.1.tar.gz";
1369 url = "https://files.pythonhosted.org/packages/44/39/6bcb83cae0095a31b6be4511707fdf2009d3e29903a55a0494d3a9a2fac0/PyMySQL-0.8.1.tar.gz";
1366 sha256 = "0a96crz55bw4h6myh833skrli7b0ck89m3x673y2z2ryy7zrpq9l";
1370 sha256 = "0a96crz55bw4h6myh833skrli7b0ck89m3x673y2z2ryy7zrpq9l";
1367 };
1371 };
1368 meta = {
1372 meta = {
1369 license = [ pkgs.lib.licenses.mit ];
1373 license = [ pkgs.lib.licenses.mit ];
1370 };
1374 };
1371 };
1375 };
1372 "pyotp" = super.buildPythonPackage {
1376 "pyotp" = super.buildPythonPackage {
1373 name = "pyotp-2.2.7";
1377 name = "pyotp-2.2.7";
1374 doCheck = false;
1378 doCheck = false;
1375 src = fetchurl {
1379 src = fetchurl {
1376 url = "https://files.pythonhosted.org/packages/b1/ab/477cda97b6ca7baced5106471cb1ac1fe698d1b035983b9f8ee3422989eb/pyotp-2.2.7.tar.gz";
1380 url = "https://files.pythonhosted.org/packages/b1/ab/477cda97b6ca7baced5106471cb1ac1fe698d1b035983b9f8ee3422989eb/pyotp-2.2.7.tar.gz";
1377 sha256 = "00p69nw431f0s2ilg0hnd77p1l22m06p9rq4f8zfapmavnmzw3xy";
1381 sha256 = "00p69nw431f0s2ilg0hnd77p1l22m06p9rq4f8zfapmavnmzw3xy";
1378 };
1382 };
1379 meta = {
1383 meta = {
1380 license = [ pkgs.lib.licenses.mit ];
1384 license = [ pkgs.lib.licenses.mit ];
1381 };
1385 };
1382 };
1386 };
1383 "pyparsing" = super.buildPythonPackage {
1387 "pyparsing" = super.buildPythonPackage {
1384 name = "pyparsing-2.3.0";
1388 name = "pyparsing-2.3.0";
1385 doCheck = false;
1389 doCheck = false;
1386 src = fetchurl {
1390 src = fetchurl {
1387 url = "https://files.pythonhosted.org/packages/d0/09/3e6a5eeb6e04467b737d55f8bba15247ac0876f98fae659e58cd744430c6/pyparsing-2.3.0.tar.gz";
1391 url = "https://files.pythonhosted.org/packages/d0/09/3e6a5eeb6e04467b737d55f8bba15247ac0876f98fae659e58cd744430c6/pyparsing-2.3.0.tar.gz";
1388 sha256 = "14k5v7n3xqw8kzf42x06bzp184spnlkya2dpjyflax6l3yrallzk";
1392 sha256 = "14k5v7n3xqw8kzf42x06bzp184spnlkya2dpjyflax6l3yrallzk";
1389 };
1393 };
1390 meta = {
1394 meta = {
1391 license = [ pkgs.lib.licenses.mit ];
1395 license = [ pkgs.lib.licenses.mit ];
1392 };
1396 };
1393 };
1397 };
1394 "pyramid" = super.buildPythonPackage {
1398 "pyramid" = super.buildPythonPackage {
1395 name = "pyramid-1.10.4";
1399 name = "pyramid-1.10.4";
1396 doCheck = false;
1400 doCheck = false;
1397 propagatedBuildInputs = [
1401 propagatedBuildInputs = [
1398 self."hupper"
1402 self."hupper"
1399 self."plaster"
1403 self."plaster"
1400 self."plaster-pastedeploy"
1404 self."plaster-pastedeploy"
1401 self."setuptools"
1405 self."setuptools"
1402 self."translationstring"
1406 self."translationstring"
1403 self."venusian"
1407 self."venusian"
1404 self."webob"
1408 self."webob"
1405 self."zope.deprecation"
1409 self."zope.deprecation"
1406 self."zope.interface"
1410 self."zope.interface"
1407 self."repoze.lru"
1411 self."repoze.lru"
1408 ];
1412 ];
1409 src = fetchurl {
1413 src = fetchurl {
1410 url = "https://files.pythonhosted.org/packages/c2/43/1ae701c9c6bb3a434358e678a5e72c96e8aa55cf4cb1d2fa2041b5dd38b7/pyramid-1.10.4.tar.gz";
1414 url = "https://files.pythonhosted.org/packages/c2/43/1ae701c9c6bb3a434358e678a5e72c96e8aa55cf4cb1d2fa2041b5dd38b7/pyramid-1.10.4.tar.gz";
1411 sha256 = "0rkxs1ajycg2zh1c94xlmls56mx5m161sn8112skj0amza6cn36q";
1415 sha256 = "0rkxs1ajycg2zh1c94xlmls56mx5m161sn8112skj0amza6cn36q";
1412 };
1416 };
1413 meta = {
1417 meta = {
1414 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1418 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1415 };
1419 };
1416 };
1420 };
1417 "pyramid-debugtoolbar" = super.buildPythonPackage {
1421 "pyramid-debugtoolbar" = super.buildPythonPackage {
1418 name = "pyramid-debugtoolbar-4.5";
1422 name = "pyramid-debugtoolbar-4.5";
1419 doCheck = false;
1423 doCheck = false;
1420 propagatedBuildInputs = [
1424 propagatedBuildInputs = [
1421 self."pyramid"
1425 self."pyramid"
1422 self."pyramid-mako"
1426 self."pyramid-mako"
1423 self."repoze.lru"
1427 self."repoze.lru"
1424 self."pygments"
1428 self."pygments"
1425 self."ipaddress"
1429 self."ipaddress"
1426 ];
1430 ];
1427 src = fetchurl {
1431 src = fetchurl {
1428 url = "https://files.pythonhosted.org/packages/14/28/1f240239af340d19ee271ac62958158c79edb01a44ad8c9885508dd003d2/pyramid_debugtoolbar-4.5.tar.gz";
1432 url = "https://files.pythonhosted.org/packages/14/28/1f240239af340d19ee271ac62958158c79edb01a44ad8c9885508dd003d2/pyramid_debugtoolbar-4.5.tar.gz";
1429 sha256 = "0x2p3409pnx66n6dx5vc0mk2r1cp1ydr8mp120w44r9pwcngbibl";
1433 sha256 = "0x2p3409pnx66n6dx5vc0mk2r1cp1ydr8mp120w44r9pwcngbibl";
1430 };
1434 };
1431 meta = {
1435 meta = {
1432 license = [ { fullName = "Repoze Public License"; } pkgs.lib.licenses.bsdOriginal ];
1436 license = [ { fullName = "Repoze Public License"; } pkgs.lib.licenses.bsdOriginal ];
1433 };
1437 };
1434 };
1438 };
1435 "pyramid-jinja2" = super.buildPythonPackage {
1439 "pyramid-jinja2" = super.buildPythonPackage {
1436 name = "pyramid-jinja2-2.7";
1440 name = "pyramid-jinja2-2.7";
1437 doCheck = false;
1441 doCheck = false;
1438 propagatedBuildInputs = [
1442 propagatedBuildInputs = [
1439 self."pyramid"
1443 self."pyramid"
1440 self."zope.deprecation"
1444 self."zope.deprecation"
1441 self."jinja2"
1445 self."jinja2"
1442 self."markupsafe"
1446 self."markupsafe"
1443 ];
1447 ];
1444 src = fetchurl {
1448 src = fetchurl {
1445 url = "https://files.pythonhosted.org/packages/d8/80/d60a7233823de22ce77bd864a8a83736a1fe8b49884b08303a2e68b2c853/pyramid_jinja2-2.7.tar.gz";
1449 url = "https://files.pythonhosted.org/packages/d8/80/d60a7233823de22ce77bd864a8a83736a1fe8b49884b08303a2e68b2c853/pyramid_jinja2-2.7.tar.gz";
1446 sha256 = "1sz5s0pp5jqhf4w22w9527yz8hgdi4mhr6apd6vw1gm5clghh8aw";
1450 sha256 = "1sz5s0pp5jqhf4w22w9527yz8hgdi4mhr6apd6vw1gm5clghh8aw";
1447 };
1451 };
1448 meta = {
1452 meta = {
1449 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1453 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1450 };
1454 };
1451 };
1455 };
1452 "pyramid-mailer" = super.buildPythonPackage {
1456 "pyramid-mailer" = super.buildPythonPackage {
1453 name = "pyramid-mailer-0.15.1";
1457 name = "pyramid-mailer-0.15.1";
1454 doCheck = false;
1458 doCheck = false;
1455 propagatedBuildInputs = [
1459 propagatedBuildInputs = [
1456 self."pyramid"
1460 self."pyramid"
1457 self."repoze.sendmail"
1461 self."repoze.sendmail"
1458 self."transaction"
1462 self."transaction"
1459 ];
1463 ];
1460 src = fetchurl {
1464 src = fetchurl {
1461 url = "https://files.pythonhosted.org/packages/a0/f2/6febf5459dff4d7e653314d575469ad2e11b9d2af2c3606360e1c67202f2/pyramid_mailer-0.15.1.tar.gz";
1465 url = "https://files.pythonhosted.org/packages/a0/f2/6febf5459dff4d7e653314d575469ad2e11b9d2af2c3606360e1c67202f2/pyramid_mailer-0.15.1.tar.gz";
1462 sha256 = "16vg8jb203jgb7b0hd6wllfqvp542qh2ry1gjai2m6qpv5agy2pc";
1466 sha256 = "16vg8jb203jgb7b0hd6wllfqvp542qh2ry1gjai2m6qpv5agy2pc";
1463 };
1467 };
1464 meta = {
1468 meta = {
1465 license = [ pkgs.lib.licenses.bsdOriginal ];
1469 license = [ pkgs.lib.licenses.bsdOriginal ];
1466 };
1470 };
1467 };
1471 };
1468 "pyramid-mako" = super.buildPythonPackage {
1472 "pyramid-mako" = super.buildPythonPackage {
1469 name = "pyramid-mako-1.0.2";
1473 name = "pyramid-mako-1.0.2";
1470 doCheck = false;
1474 doCheck = false;
1471 propagatedBuildInputs = [
1475 propagatedBuildInputs = [
1472 self."pyramid"
1476 self."pyramid"
1473 self."mako"
1477 self."mako"
1474 ];
1478 ];
1475 src = fetchurl {
1479 src = fetchurl {
1476 url = "https://files.pythonhosted.org/packages/f1/92/7e69bcf09676d286a71cb3bbb887b16595b96f9ba7adbdc239ffdd4b1eb9/pyramid_mako-1.0.2.tar.gz";
1480 url = "https://files.pythonhosted.org/packages/f1/92/7e69bcf09676d286a71cb3bbb887b16595b96f9ba7adbdc239ffdd4b1eb9/pyramid_mako-1.0.2.tar.gz";
1477 sha256 = "18gk2vliq8z4acblsl6yzgbvnr9rlxjlcqir47km7kvlk1xri83d";
1481 sha256 = "18gk2vliq8z4acblsl6yzgbvnr9rlxjlcqir47km7kvlk1xri83d";
1478 };
1482 };
1479 meta = {
1483 meta = {
1480 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1484 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1481 };
1485 };
1482 };
1486 };
1483 "pysqlite" = super.buildPythonPackage {
1487 "pysqlite" = super.buildPythonPackage {
1484 name = "pysqlite-2.8.3";
1488 name = "pysqlite-2.8.3";
1485 doCheck = false;
1489 doCheck = false;
1486 src = fetchurl {
1490 src = fetchurl {
1487 url = "https://files.pythonhosted.org/packages/42/02/981b6703e3c83c5b25a829c6e77aad059f9481b0bbacb47e6e8ca12bd731/pysqlite-2.8.3.tar.gz";
1491 url = "https://files.pythonhosted.org/packages/42/02/981b6703e3c83c5b25a829c6e77aad059f9481b0bbacb47e6e8ca12bd731/pysqlite-2.8.3.tar.gz";
1488 sha256 = "1424gwq9sil2ffmnizk60q36vydkv8rxs6m7xs987kz8cdc37lqp";
1492 sha256 = "1424gwq9sil2ffmnizk60q36vydkv8rxs6m7xs987kz8cdc37lqp";
1489 };
1493 };
1490 meta = {
1494 meta = {
1491 license = [ { fullName = "zlib/libpng License"; } { fullName = "zlib/libpng license"; } ];
1495 license = [ { fullName = "zlib/libpng License"; } { fullName = "zlib/libpng license"; } ];
1492 };
1496 };
1493 };
1497 };
1494 "pytest" = super.buildPythonPackage {
1498 "pytest" = super.buildPythonPackage {
1495 name = "pytest-3.8.2";
1499 name = "pytest-4.6.5";
1496 doCheck = false;
1500 doCheck = false;
1497 propagatedBuildInputs = [
1501 propagatedBuildInputs = [
1498 self."py"
1502 self."py"
1499 self."six"
1503 self."six"
1500 self."setuptools"
1504 self."packaging"
1501 self."attrs"
1505 self."attrs"
1502 self."more-itertools"
1503 self."atomicwrites"
1506 self."atomicwrites"
1504 self."pluggy"
1507 self."pluggy"
1508 self."importlib-metadata"
1509 self."wcwidth"
1505 self."funcsigs"
1510 self."funcsigs"
1506 self."pathlib2"
1511 self."pathlib2"
1512 self."more-itertools"
1507 ];
1513 ];
1508 src = fetchurl {
1514 src = fetchurl {
1509 url = "https://files.pythonhosted.org/packages/5f/d2/7f77f406ac505abda02ab4afb50d06ebf304f6ea42fca34f8f37529106b2/pytest-3.8.2.tar.gz";
1515 url = "https://files.pythonhosted.org/packages/2a/c6/1d1f32f6a5009900521b12e6560fb6b7245b0d4bc3fb771acd63d10e30e1/pytest-4.6.5.tar.gz";
1510 sha256 = "18nrwzn61kph2y6gxwfz9ms68rfvr9d4vcffsxng9p7jk9z18clk";
1516 sha256 = "0iykwwfp4h181nd7rsihh2120b0rkawlw7rvbl19sgfspncr3hwg";
1511 };
1517 };
1512 meta = {
1518 meta = {
1513 license = [ pkgs.lib.licenses.mit ];
1519 license = [ pkgs.lib.licenses.mit ];
1514 };
1520 };
1515 };
1521 };
1516 "pytest-cov" = super.buildPythonPackage {
1522 "pytest-cov" = super.buildPythonPackage {
1517 name = "pytest-cov-2.6.0";
1523 name = "pytest-cov-2.7.1";
1518 doCheck = false;
1524 doCheck = false;
1519 propagatedBuildInputs = [
1525 propagatedBuildInputs = [
1520 self."pytest"
1526 self."pytest"
1521 self."coverage"
1527 self."coverage"
1522 ];
1528 ];
1523 src = fetchurl {
1529 src = fetchurl {
1524 url = "https://files.pythonhosted.org/packages/d9/e2/58f90a316fbd94dd50bf5c826a23f3f5d079fb3cc448c1e9f0e3c33a3d2a/pytest-cov-2.6.0.tar.gz";
1530 url = "https://files.pythonhosted.org/packages/bb/0f/3db7ff86801883b21d5353b258c994b1b8e2abbc804e2273b8d0fd19004b/pytest-cov-2.7.1.tar.gz";
1525 sha256 = "0qnpp9y3ygx4jk4pf5ad71fh2skbvnr6gl54m7rg5qysnx4g0q73";
1531 sha256 = "0filvmmyqm715azsl09ql8hy2x7h286n6d8z5x42a1wpvvys83p0";
1526 };
1532 };
1527 meta = {
1533 meta = {
1528 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.mit ];
1534 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.mit ];
1529 };
1535 };
1530 };
1536 };
1531 "pytest-profiling" = super.buildPythonPackage {
1537 "pytest-profiling" = super.buildPythonPackage {
1532 name = "pytest-profiling-1.3.0";
1538 name = "pytest-profiling-1.7.0";
1533 doCheck = false;
1539 doCheck = false;
1534 propagatedBuildInputs = [
1540 propagatedBuildInputs = [
1535 self."six"
1541 self."six"
1536 self."pytest"
1542 self."pytest"
1537 self."gprof2dot"
1543 self."gprof2dot"
1538 ];
1544 ];
1539 src = fetchurl {
1545 src = fetchurl {
1540 url = "https://files.pythonhosted.org/packages/f5/34/4626126e041a51ef50a80d0619519b18d20aef249aac25b0d0fdd47e57ee/pytest-profiling-1.3.0.tar.gz";
1546 url = "https://files.pythonhosted.org/packages/39/70/22a4b33739f07f1732a63e33bbfbf68e0fa58cfba9d200e76d01921eddbf/pytest-profiling-1.7.0.tar.gz";
1541 sha256 = "08r5afx5z22yvpmsnl91l4amsy1yxn8qsmm61mhp06mz8zjs51kb";
1547 sha256 = "0abz9gi26jpcfdzgsvwad91555lpgdc8kbymicmms8k2fqa8z4wk";
1542 };
1548 };
1543 meta = {
1549 meta = {
1544 license = [ pkgs.lib.licenses.mit ];
1550 license = [ pkgs.lib.licenses.mit ];
1545 };
1551 };
1546 };
1552 };
1547 "pytest-runner" = super.buildPythonPackage {
1553 "pytest-runner" = super.buildPythonPackage {
1548 name = "pytest-runner-4.2";
1554 name = "pytest-runner-5.1";
1549 doCheck = false;
1555 doCheck = false;
1550 src = fetchurl {
1556 src = fetchurl {
1551 url = "https://files.pythonhosted.org/packages/9e/b7/fe6e8f87f9a756fd06722216f1b6698ccba4d269eac6329d9f0c441d0f93/pytest-runner-4.2.tar.gz";
1557 url = "https://files.pythonhosted.org/packages/d9/6d/4b41a74b31720e25abd4799be72d54811da4b4d0233e38b75864dcc1f7ad/pytest-runner-5.1.tar.gz";
1552 sha256 = "1gkpyphawxz38ni1gdq1fmwyqcg02m7ypzqvv46z06crwdxi2gyj";
1558 sha256 = "0ykfcnpp8c22winj63qzc07l5axwlc9ikl8vn05sc32gv3417815";
1553 };
1559 };
1554 meta = {
1560 meta = {
1555 license = [ pkgs.lib.licenses.mit ];
1561 license = [ pkgs.lib.licenses.mit ];
1556 };
1562 };
1557 };
1563 };
1558 "pytest-sugar" = super.buildPythonPackage {
1564 "pytest-sugar" = super.buildPythonPackage {
1559 name = "pytest-sugar-0.9.1";
1565 name = "pytest-sugar-0.9.2";
1560 doCheck = false;
1566 doCheck = false;
1561 propagatedBuildInputs = [
1567 propagatedBuildInputs = [
1562 self."pytest"
1568 self."pytest"
1563 self."termcolor"
1569 self."termcolor"
1570 self."packaging"
1564 ];
1571 ];
1565 src = fetchurl {
1572 src = fetchurl {
1566 url = "https://files.pythonhosted.org/packages/3e/6a/a3f909083079d03bde11d06ab23088886bbe25f2c97fbe4bb865e2bf05bc/pytest-sugar-0.9.1.tar.gz";
1573 url = "https://files.pythonhosted.org/packages/55/59/f02f78d1c80f7e03e23177f60624c8106d4f23d124c921df103f65692464/pytest-sugar-0.9.2.tar.gz";
1567 sha256 = "0b4av40dv30727m54v211r0nzwjp2ajkjgxix6j484qjmwpw935b";
1574 sha256 = "1asq7yc4g8bx2sn7yy974mhc9ywvaihasjab4inkirdwn9s7mn7w";
1568 };
1575 };
1569 meta = {
1576 meta = {
1570 license = [ pkgs.lib.licenses.bsdOriginal ];
1577 license = [ pkgs.lib.licenses.bsdOriginal ];
1571 };
1578 };
1572 };
1579 };
1573 "pytest-timeout" = super.buildPythonPackage {
1580 "pytest-timeout" = super.buildPythonPackage {
1574 name = "pytest-timeout-1.3.2";
1581 name = "pytest-timeout-1.3.3";
1575 doCheck = false;
1582 doCheck = false;
1576 propagatedBuildInputs = [
1583 propagatedBuildInputs = [
1577 self."pytest"
1584 self."pytest"
1578 ];
1585 ];
1579 src = fetchurl {
1586 src = fetchurl {
1580 url = "https://files.pythonhosted.org/packages/8c/3e/1b6a319d12ae7baa3acb7c18ff2c8630a09471a0319d43535c683b4d03eb/pytest-timeout-1.3.2.tar.gz";
1587 url = "https://files.pythonhosted.org/packages/13/48/7a166eaa29c1dca6cc253e3ba5773ff2e4aa4f567c1ea3905808e95ac5c1/pytest-timeout-1.3.3.tar.gz";
1581 sha256 = "09wnmzvnls2mnsdz7x3c3sk2zdp6jl4dryvyj5i8hqz16q2zq5qi";
1588 sha256 = "1cczcjhw4xx5sjkhxlhc5c1bkr7x6fcyx12wrnvwfckshdvblc2a";
1582 };
1589 };
1583 meta = {
1590 meta = {
1584 license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ];
1591 license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ];
1585 };
1592 };
1586 };
1593 };
1587 "python-dateutil" = super.buildPythonPackage {
1594 "python-dateutil" = super.buildPythonPackage {
1588 name = "python-dateutil-2.8.0";
1595 name = "python-dateutil-2.8.0";
1589 doCheck = false;
1596 doCheck = false;
1590 propagatedBuildInputs = [
1597 propagatedBuildInputs = [
1591 self."six"
1598 self."six"
1592 ];
1599 ];
1593 src = fetchurl {
1600 src = fetchurl {
1594 url = "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz";
1601 url = "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz";
1595 sha256 = "17nsfhy4xdz1khrfxa61vd7pmvd5z0wa3zb6v4gb4kfnykv0b668";
1602 sha256 = "17nsfhy4xdz1khrfxa61vd7pmvd5z0wa3zb6v4gb4kfnykv0b668";
1596 };
1603 };
1597 meta = {
1604 meta = {
1598 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.asl20 { fullName = "Dual License"; } ];
1605 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.asl20 { fullName = "Dual License"; } ];
1599 };
1606 };
1600 };
1607 };
1601 "python-editor" = super.buildPythonPackage {
1608 "python-editor" = super.buildPythonPackage {
1602 name = "python-editor-1.0.4";
1609 name = "python-editor-1.0.4";
1603 doCheck = false;
1610 doCheck = false;
1604 src = fetchurl {
1611 src = fetchurl {
1605 url = "https://files.pythonhosted.org/packages/0a/85/78f4a216d28343a67b7397c99825cff336330893f00601443f7c7b2f2234/python-editor-1.0.4.tar.gz";
1612 url = "https://files.pythonhosted.org/packages/0a/85/78f4a216d28343a67b7397c99825cff336330893f00601443f7c7b2f2234/python-editor-1.0.4.tar.gz";
1606 sha256 = "0yrjh8w72ivqxi4i7xsg5b1vz15x8fg51xra7c3bgfyxqnyadzai";
1613 sha256 = "0yrjh8w72ivqxi4i7xsg5b1vz15x8fg51xra7c3bgfyxqnyadzai";
1607 };
1614 };
1608 meta = {
1615 meta = {
1609 license = [ pkgs.lib.licenses.asl20 { fullName = "Apache"; } ];
1616 license = [ pkgs.lib.licenses.asl20 { fullName = "Apache"; } ];
1610 };
1617 };
1611 };
1618 };
1612 "python-ldap" = super.buildPythonPackage {
1619 "python-ldap" = super.buildPythonPackage {
1613 name = "python-ldap-3.1.0";
1620 name = "python-ldap-3.1.0";
1614 doCheck = false;
1621 doCheck = false;
1615 propagatedBuildInputs = [
1622 propagatedBuildInputs = [
1616 self."pyasn1"
1623 self."pyasn1"
1617 self."pyasn1-modules"
1624 self."pyasn1-modules"
1618 ];
1625 ];
1619 src = fetchurl {
1626 src = fetchurl {
1620 url = "https://files.pythonhosted.org/packages/7f/1c/28d721dff2fcd2fef9d55b40df63a00be26ec8a11e8c6fc612ae642f9cfd/python-ldap-3.1.0.tar.gz";
1627 url = "https://files.pythonhosted.org/packages/7f/1c/28d721dff2fcd2fef9d55b40df63a00be26ec8a11e8c6fc612ae642f9cfd/python-ldap-3.1.0.tar.gz";
1621 sha256 = "1i97nwfnraylyn0myxlf3vciicrf5h6fymrcff9c00k581wmx5s1";
1628 sha256 = "1i97nwfnraylyn0myxlf3vciicrf5h6fymrcff9c00k581wmx5s1";
1622 };
1629 };
1623 meta = {
1630 meta = {
1624 license = [ pkgs.lib.licenses.psfl ];
1631 license = [ pkgs.lib.licenses.psfl ];
1625 };
1632 };
1626 };
1633 };
1627 "python-memcached" = super.buildPythonPackage {
1634 "python-memcached" = super.buildPythonPackage {
1628 name = "python-memcached-1.59";
1635 name = "python-memcached-1.59";
1629 doCheck = false;
1636 doCheck = false;
1630 propagatedBuildInputs = [
1637 propagatedBuildInputs = [
1631 self."six"
1638 self."six"
1632 ];
1639 ];
1633 src = fetchurl {
1640 src = fetchurl {
1634 url = "https://files.pythonhosted.org/packages/90/59/5faf6e3cd8a568dd4f737ddae4f2e54204fd8c51f90bf8df99aca6c22318/python-memcached-1.59.tar.gz";
1641 url = "https://files.pythonhosted.org/packages/90/59/5faf6e3cd8a568dd4f737ddae4f2e54204fd8c51f90bf8df99aca6c22318/python-memcached-1.59.tar.gz";
1635 sha256 = "0kvyapavbirk2x3n1jx4yb9nyigrj1s3x15nm3qhpvhkpqvqdqm2";
1642 sha256 = "0kvyapavbirk2x3n1jx4yb9nyigrj1s3x15nm3qhpvhkpqvqdqm2";
1636 };
1643 };
1637 meta = {
1644 meta = {
1638 license = [ pkgs.lib.licenses.psfl ];
1645 license = [ pkgs.lib.licenses.psfl ];
1639 };
1646 };
1640 };
1647 };
1641 "python-pam" = super.buildPythonPackage {
1648 "python-pam" = super.buildPythonPackage {
1642 name = "python-pam-1.8.4";
1649 name = "python-pam-1.8.4";
1643 doCheck = false;
1650 doCheck = false;
1644 src = fetchurl {
1651 src = fetchurl {
1645 url = "https://files.pythonhosted.org/packages/01/16/544d01cae9f28e0292dbd092b6b8b0bf222b528f362ee768a5bed2140111/python-pam-1.8.4.tar.gz";
1652 url = "https://files.pythonhosted.org/packages/01/16/544d01cae9f28e0292dbd092b6b8b0bf222b528f362ee768a5bed2140111/python-pam-1.8.4.tar.gz";
1646 sha256 = "16whhc0vr7gxsbzvsnq65nq8fs3wwmx755cavm8kkczdkz4djmn8";
1653 sha256 = "16whhc0vr7gxsbzvsnq65nq8fs3wwmx755cavm8kkczdkz4djmn8";
1647 };
1654 };
1648 meta = {
1655 meta = {
1649 license = [ { fullName = "License :: OSI Approved :: MIT License"; } pkgs.lib.licenses.mit ];
1656 license = [ { fullName = "License :: OSI Approved :: MIT License"; } pkgs.lib.licenses.mit ];
1650 };
1657 };
1651 };
1658 };
1652 "python-saml" = super.buildPythonPackage {
1659 "python-saml" = super.buildPythonPackage {
1653 name = "python-saml-2.4.2";
1660 name = "python-saml-2.4.2";
1654 doCheck = false;
1661 doCheck = false;
1655 propagatedBuildInputs = [
1662 propagatedBuildInputs = [
1656 self."dm.xmlsec.binding"
1663 self."dm.xmlsec.binding"
1657 self."isodate"
1664 self."isodate"
1658 self."defusedxml"
1665 self."defusedxml"
1659 ];
1666 ];
1660 src = fetchurl {
1667 src = fetchurl {
1661 url = "https://files.pythonhosted.org/packages/79/a8/a6611017e0883102fd5e2b73c9d90691b8134e38247c04ee1531d3dc647c/python-saml-2.4.2.tar.gz";
1668 url = "https://files.pythonhosted.org/packages/79/a8/a6611017e0883102fd5e2b73c9d90691b8134e38247c04ee1531d3dc647c/python-saml-2.4.2.tar.gz";
1662 sha256 = "0dls4hwvf13yg7x5yfjrghbywg8g38vn5vr0rsf70hli3ydbfm43";
1669 sha256 = "0dls4hwvf13yg7x5yfjrghbywg8g38vn5vr0rsf70hli3ydbfm43";
1663 };
1670 };
1664 meta = {
1671 meta = {
1665 license = [ pkgs.lib.licenses.mit ];
1672 license = [ pkgs.lib.licenses.mit ];
1666 };
1673 };
1667 };
1674 };
1668 "pytz" = super.buildPythonPackage {
1675 "pytz" = super.buildPythonPackage {
1669 name = "pytz-2019.2";
1676 name = "pytz-2019.2";
1670 doCheck = false;
1677 doCheck = false;
1671 src = fetchurl {
1678 src = fetchurl {
1672 url = "https://files.pythonhosted.org/packages/27/c0/fbd352ca76050952a03db776d241959d5a2ee1abddfeb9e2a53fdb489be4/pytz-2019.2.tar.gz";
1679 url = "https://files.pythonhosted.org/packages/27/c0/fbd352ca76050952a03db776d241959d5a2ee1abddfeb9e2a53fdb489be4/pytz-2019.2.tar.gz";
1673 sha256 = "0ckb27hhjc8i8gcdvk4d9avld62b7k52yjijc60s2m3y8cpb7h16";
1680 sha256 = "0ckb27hhjc8i8gcdvk4d9avld62b7k52yjijc60s2m3y8cpb7h16";
1674 };
1681 };
1675 meta = {
1682 meta = {
1676 license = [ pkgs.lib.licenses.mit ];
1683 license = [ pkgs.lib.licenses.mit ];
1677 };
1684 };
1678 };
1685 };
1679 "pyzmq" = super.buildPythonPackage {
1686 "pyzmq" = super.buildPythonPackage {
1680 name = "pyzmq-14.6.0";
1687 name = "pyzmq-14.6.0";
1681 doCheck = false;
1688 doCheck = false;
1682 src = fetchurl {
1689 src = fetchurl {
1683 url = "https://files.pythonhosted.org/packages/8a/3b/5463d5a9d712cd8bbdac335daece0d69f6a6792da4e3dd89956c0db4e4e6/pyzmq-14.6.0.tar.gz";
1690 url = "https://files.pythonhosted.org/packages/8a/3b/5463d5a9d712cd8bbdac335daece0d69f6a6792da4e3dd89956c0db4e4e6/pyzmq-14.6.0.tar.gz";
1684 sha256 = "1frmbjykvhmdg64g7sn20c9fpamrsfxwci1nhhg8q7jgz5pq0ikp";
1691 sha256 = "1frmbjykvhmdg64g7sn20c9fpamrsfxwci1nhhg8q7jgz5pq0ikp";
1685 };
1692 };
1686 meta = {
1693 meta = {
1687 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "LGPL+BSD"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ];
1694 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "LGPL+BSD"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ];
1688 };
1695 };
1689 };
1696 };
1690 "redis" = super.buildPythonPackage {
1697 "redis" = super.buildPythonPackage {
1691 name = "redis-3.3.8";
1698 name = "redis-3.3.8";
1692 doCheck = false;
1699 doCheck = false;
1693 src = fetchurl {
1700 src = fetchurl {
1694 url = "https://files.pythonhosted.org/packages/d7/e9/549305f1c2480f8c24abadfaa71c20967cc3269769073b59960e9a566072/redis-3.3.8.tar.gz";
1701 url = "https://files.pythonhosted.org/packages/d7/e9/549305f1c2480f8c24abadfaa71c20967cc3269769073b59960e9a566072/redis-3.3.8.tar.gz";
1695 sha256 = "0fyxzqax7lcwzwhvnz0i0q6v62hxyv1mv52ywx3bpff9a2vjz8lq";
1702 sha256 = "0fyxzqax7lcwzwhvnz0i0q6v62hxyv1mv52ywx3bpff9a2vjz8lq";
1696 };
1703 };
1697 meta = {
1704 meta = {
1698 license = [ pkgs.lib.licenses.mit ];
1705 license = [ pkgs.lib.licenses.mit ];
1699 };
1706 };
1700 };
1707 };
1701 "repoze.lru" = super.buildPythonPackage {
1708 "repoze.lru" = super.buildPythonPackage {
1702 name = "repoze.lru-0.7";
1709 name = "repoze.lru-0.7";
1703 doCheck = false;
1710 doCheck = false;
1704 src = fetchurl {
1711 src = fetchurl {
1705 url = "https://files.pythonhosted.org/packages/12/bc/595a77c4b5e204847fdf19268314ef59c85193a9dc9f83630fc459c0fee5/repoze.lru-0.7.tar.gz";
1712 url = "https://files.pythonhosted.org/packages/12/bc/595a77c4b5e204847fdf19268314ef59c85193a9dc9f83630fc459c0fee5/repoze.lru-0.7.tar.gz";
1706 sha256 = "0xzz1aw2smy8hdszrq8yhnklx6w1r1mf55061kalw3iq35gafa84";
1713 sha256 = "0xzz1aw2smy8hdszrq8yhnklx6w1r1mf55061kalw3iq35gafa84";
1707 };
1714 };
1708 meta = {
1715 meta = {
1709 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1716 license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1710 };
1717 };
1711 };
1718 };
1712 "repoze.sendmail" = super.buildPythonPackage {
1719 "repoze.sendmail" = super.buildPythonPackage {
1713 name = "repoze.sendmail-4.4.1";
1720 name = "repoze.sendmail-4.4.1";
1714 doCheck = false;
1721 doCheck = false;
1715 propagatedBuildInputs = [
1722 propagatedBuildInputs = [
1716 self."setuptools"
1723 self."setuptools"
1717 self."zope.interface"
1724 self."zope.interface"
1718 self."transaction"
1725 self."transaction"
1719 ];
1726 ];
1720 src = fetchurl {
1727 src = fetchurl {
1721 url = "https://files.pythonhosted.org/packages/12/4e/8ef1fd5c42765d712427b9c391419a77bd48877886d2cbc5e9f23c8cad9b/repoze.sendmail-4.4.1.tar.gz";
1728 url = "https://files.pythonhosted.org/packages/12/4e/8ef1fd5c42765d712427b9c391419a77bd48877886d2cbc5e9f23c8cad9b/repoze.sendmail-4.4.1.tar.gz";
1722 sha256 = "096ln02jr2afk7ab9j2czxqv2ryqq7m86ah572nqplx52iws73ks";
1729 sha256 = "096ln02jr2afk7ab9j2czxqv2ryqq7m86ah572nqplx52iws73ks";
1723 };
1730 };
1724 meta = {
1731 meta = {
1725 license = [ pkgs.lib.licenses.zpl21 ];
1732 license = [ pkgs.lib.licenses.zpl21 ];
1726 };
1733 };
1727 };
1734 };
1728 "requests" = super.buildPythonPackage {
1735 "requests" = super.buildPythonPackage {
1729 name = "requests-2.9.1";
1736 name = "requests-2.9.1";
1730 doCheck = false;
1737 doCheck = false;
1731 src = fetchurl {
1738 src = fetchurl {
1732 url = "https://files.pythonhosted.org/packages/f9/6d/07c44fb1ebe04d069459a189e7dab9e4abfe9432adcd4477367c25332748/requests-2.9.1.tar.gz";
1739 url = "https://files.pythonhosted.org/packages/f9/6d/07c44fb1ebe04d069459a189e7dab9e4abfe9432adcd4477367c25332748/requests-2.9.1.tar.gz";
1733 sha256 = "0zsqrzlybf25xscgi7ja4s48y2abf9wvjkn47wh984qgs1fq2xy5";
1740 sha256 = "0zsqrzlybf25xscgi7ja4s48y2abf9wvjkn47wh984qgs1fq2xy5";
1734 };
1741 };
1735 meta = {
1742 meta = {
1736 license = [ pkgs.lib.licenses.asl20 ];
1743 license = [ pkgs.lib.licenses.asl20 ];
1737 };
1744 };
1738 };
1745 };
1739 "rhodecode-enterprise-ce" = super.buildPythonPackage {
1746 "rhodecode-enterprise-ce" = super.buildPythonPackage {
1740 name = "rhodecode-enterprise-ce-4.18.0";
1747 name = "rhodecode-enterprise-ce-4.18.0";
1741 buildInputs = [
1748 buildInputs = [
1742 self."pytest"
1749 self."pytest"
1743 self."py"
1750 self."py"
1744 self."pytest-cov"
1751 self."pytest-cov"
1745 self."pytest-sugar"
1752 self."pytest-sugar"
1746 self."pytest-runner"
1753 self."pytest-runner"
1747 self."pytest-profiling"
1754 self."pytest-profiling"
1748 self."pytest-timeout"
1755 self."pytest-timeout"
1749 self."gprof2dot"
1756 self."gprof2dot"
1750 self."mock"
1757 self."mock"
1751 self."cov-core"
1758 self."cov-core"
1752 self."coverage"
1759 self."coverage"
1753 self."webtest"
1760 self."webtest"
1754 self."beautifulsoup4"
1761 self."beautifulsoup4"
1755 self."configobj"
1762 self."configobj"
1756 ];
1763 ];
1757 doCheck = true;
1764 doCheck = true;
1758 propagatedBuildInputs = [
1765 propagatedBuildInputs = [
1759 self."amqp"
1766 self."amqp"
1760 self."babel"
1767 self."babel"
1761 self."beaker"
1768 self."beaker"
1762 self."bleach"
1769 self."bleach"
1763 self."celery"
1770 self."celery"
1764 self."channelstream"
1771 self."channelstream"
1765 self."click"
1772 self."click"
1766 self."colander"
1773 self."colander"
1767 self."configobj"
1774 self."configobj"
1768 self."cssselect"
1775 self."cssselect"
1769 self."cryptography"
1776 self."cryptography"
1770 self."decorator"
1777 self."decorator"
1771 self."deform"
1778 self."deform"
1772 self."docutils"
1779 self."docutils"
1773 self."dogpile.cache"
1780 self."dogpile.cache"
1774 self."dogpile.core"
1781 self."dogpile.core"
1775 self."formencode"
1782 self."formencode"
1776 self."future"
1783 self."future"
1777 self."futures"
1784 self."futures"
1778 self."infrae.cache"
1785 self."infrae.cache"
1779 self."iso8601"
1786 self."iso8601"
1780 self."itsdangerous"
1787 self."itsdangerous"
1781 self."kombu"
1788 self."kombu"
1782 self."lxml"
1789 self."lxml"
1783 self."mako"
1790 self."mako"
1784 self."markdown"
1791 self."markdown"
1785 self."markupsafe"
1792 self."markupsafe"
1786 self."msgpack-python"
1793 self."msgpack-python"
1787 self."pyotp"
1794 self."pyotp"
1788 self."packaging"
1795 self."packaging"
1789 self."pathlib2"
1796 self."pathlib2"
1790 self."paste"
1797 self."paste"
1791 self."pastedeploy"
1798 self."pastedeploy"
1792 self."pastescript"
1799 self."pastescript"
1793 self."peppercorn"
1800 self."peppercorn"
1794 self."psutil"
1801 self."psutil"
1795 self."py-bcrypt"
1802 self."py-bcrypt"
1796 self."pycurl"
1803 self."pycurl"
1797 self."pycrypto"
1804 self."pycrypto"
1798 self."pygments"
1805 self."pygments"
1799 self."pyparsing"
1806 self."pyparsing"
1800 self."pyramid-debugtoolbar"
1807 self."pyramid-debugtoolbar"
1801 self."pyramid-mako"
1808 self."pyramid-mako"
1802 self."pyramid"
1809 self."pyramid"
1803 self."pyramid-mailer"
1810 self."pyramid-mailer"
1804 self."python-dateutil"
1811 self."python-dateutil"
1805 self."python-ldap"
1812 self."python-ldap"
1806 self."python-memcached"
1813 self."python-memcached"
1807 self."python-pam"
1814 self."python-pam"
1808 self."python-saml"
1815 self."python-saml"
1809 self."pytz"
1816 self."pytz"
1810 self."tzlocal"
1817 self."tzlocal"
1811 self."pyzmq"
1818 self."pyzmq"
1812 self."py-gfm"
1819 self."py-gfm"
1813 self."redis"
1820 self."redis"
1814 self."repoze.lru"
1821 self."repoze.lru"
1815 self."requests"
1822 self."requests"
1816 self."routes"
1823 self."routes"
1817 self."simplejson"
1824 self."simplejson"
1818 self."six"
1825 self."six"
1819 self."sqlalchemy"
1826 self."sqlalchemy"
1820 self."sshpubkeys"
1827 self."sshpubkeys"
1821 self."subprocess32"
1828 self."subprocess32"
1822 self."supervisor"
1829 self."supervisor"
1823 self."translationstring"
1830 self."translationstring"
1824 self."urllib3"
1831 self."urllib3"
1825 self."urlobject"
1832 self."urlobject"
1826 self."venusian"
1833 self."venusian"
1827 self."weberror"
1834 self."weberror"
1828 self."webhelpers2"
1835 self."webhelpers2"
1829 self."webhelpers"
1836 self."webhelpers"
1830 self."webob"
1837 self."webob"
1831 self."whoosh"
1838 self."whoosh"
1832 self."wsgiref"
1839 self."wsgiref"
1833 self."zope.cachedescriptors"
1840 self."zope.cachedescriptors"
1834 self."zope.deprecation"
1841 self."zope.deprecation"
1835 self."zope.event"
1842 self."zope.event"
1836 self."zope.interface"
1843 self."zope.interface"
1837 self."mysql-python"
1844 self."mysql-python"
1838 self."pymysql"
1845 self."pymysql"
1839 self."pysqlite"
1846 self."pysqlite"
1840 self."psycopg2"
1847 self."psycopg2"
1841 self."nbconvert"
1848 self."nbconvert"
1842 self."nbformat"
1849 self."nbformat"
1843 self."jupyter-client"
1850 self."jupyter-client"
1844 self."alembic"
1851 self."alembic"
1845 self."invoke"
1852 self."invoke"
1846 self."bumpversion"
1853 self."bumpversion"
1847 self."gevent"
1854 self."gevent"
1848 self."greenlet"
1855 self."greenlet"
1849 self."gunicorn"
1856 self."gunicorn"
1850 self."waitress"
1857 self."waitress"
1851 self."ipdb"
1858 self."ipdb"
1852 self."ipython"
1859 self."ipython"
1853 self."rhodecode-tools"
1860 self."rhodecode-tools"
1854 self."appenlight-client"
1861 self."appenlight-client"
1855 self."pytest"
1862 self."pytest"
1856 self."py"
1863 self."py"
1857 self."pytest-cov"
1864 self."pytest-cov"
1858 self."pytest-sugar"
1865 self."pytest-sugar"
1859 self."pytest-runner"
1866 self."pytest-runner"
1860 self."pytest-profiling"
1867 self."pytest-profiling"
1861 self."pytest-timeout"
1868 self."pytest-timeout"
1862 self."gprof2dot"
1869 self."gprof2dot"
1863 self."mock"
1870 self."mock"
1864 self."cov-core"
1871 self."cov-core"
1865 self."coverage"
1872 self."coverage"
1866 self."webtest"
1873 self."webtest"
1867 self."beautifulsoup4"
1874 self."beautifulsoup4"
1868 ];
1875 ];
1869 src = ./.;
1876 src = ./.;
1870 meta = {
1877 meta = {
1871 license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ];
1878 license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ];
1872 };
1879 };
1873 };
1880 };
1874 "rhodecode-tools" = super.buildPythonPackage {
1881 "rhodecode-tools" = super.buildPythonPackage {
1875 name = "rhodecode-tools-1.2.1";
1882 name = "rhodecode-tools-1.2.1";
1876 doCheck = false;
1883 doCheck = false;
1877 propagatedBuildInputs = [
1884 propagatedBuildInputs = [
1878 self."click"
1885 self."click"
1879 self."future"
1886 self."future"
1880 self."six"
1887 self."six"
1881 self."mako"
1888 self."mako"
1882 self."markupsafe"
1889 self."markupsafe"
1883 self."requests"
1890 self."requests"
1884 self."urllib3"
1891 self."urllib3"
1885 self."whoosh"
1892 self."whoosh"
1886 self."elasticsearch"
1893 self."elasticsearch"
1887 self."elasticsearch-dsl"
1894 self."elasticsearch-dsl"
1888 self."elasticsearch2"
1895 self."elasticsearch2"
1889 self."elasticsearch1-dsl"
1896 self."elasticsearch1-dsl"
1890 ];
1897 ];
1891 src = fetchurl {
1898 src = fetchurl {
1892 url = "https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-10ac93f4-bb7d-4b97-baea-68110743dd5a.tar.gz?md5=962dc77c06aceee62282b98d33149661";
1899 url = "https://code.rhodecode.com/rhodecode-tools-ce/artifacts/download/0-10ac93f4-bb7d-4b97-baea-68110743dd5a.tar.gz?md5=962dc77c06aceee62282b98d33149661";
1893 sha256 = "1vfhgf46inbx7jvlfx4fdzh3vz7lh37r291gzb5hx447pfm3qllg";
1900 sha256 = "1vfhgf46inbx7jvlfx4fdzh3vz7lh37r291gzb5hx447pfm3qllg";
1894 };
1901 };
1895 meta = {
1902 meta = {
1896 license = [ { fullName = "Apache 2.0 and Proprietary"; } ];
1903 license = [ { fullName = "Apache 2.0 and Proprietary"; } ];
1897 };
1904 };
1898 };
1905 };
1899 "routes" = super.buildPythonPackage {
1906 "routes" = super.buildPythonPackage {
1900 name = "routes-2.4.1";
1907 name = "routes-2.4.1";
1901 doCheck = false;
1908 doCheck = false;
1902 propagatedBuildInputs = [
1909 propagatedBuildInputs = [
1903 self."six"
1910 self."six"
1904 self."repoze.lru"
1911 self."repoze.lru"
1905 ];
1912 ];
1906 src = fetchurl {
1913 src = fetchurl {
1907 url = "https://files.pythonhosted.org/packages/33/38/ea827837e68d9c7dde4cff7ec122a93c319f0effc08ce92a17095576603f/Routes-2.4.1.tar.gz";
1914 url = "https://files.pythonhosted.org/packages/33/38/ea827837e68d9c7dde4cff7ec122a93c319f0effc08ce92a17095576603f/Routes-2.4.1.tar.gz";
1908 sha256 = "1zamff3m0kc4vyfniyhxpkkcqv1rrgnmh37ykxv34nna1ws47vi6";
1915 sha256 = "1zamff3m0kc4vyfniyhxpkkcqv1rrgnmh37ykxv34nna1ws47vi6";
1909 };
1916 };
1910 meta = {
1917 meta = {
1911 license = [ pkgs.lib.licenses.mit ];
1918 license = [ pkgs.lib.licenses.mit ];
1912 };
1919 };
1913 };
1920 };
1914 "scandir" = super.buildPythonPackage {
1921 "scandir" = super.buildPythonPackage {
1915 name = "scandir-1.10.0";
1922 name = "scandir-1.10.0";
1916 doCheck = false;
1923 doCheck = false;
1917 src = fetchurl {
1924 src = fetchurl {
1918 url = "https://files.pythonhosted.org/packages/df/f5/9c052db7bd54d0cbf1bc0bb6554362bba1012d03e5888950a4f5c5dadc4e/scandir-1.10.0.tar.gz";
1925 url = "https://files.pythonhosted.org/packages/df/f5/9c052db7bd54d0cbf1bc0bb6554362bba1012d03e5888950a4f5c5dadc4e/scandir-1.10.0.tar.gz";
1919 sha256 = "1bkqwmf056pkchf05ywbnf659wqlp6lljcdb0y88wr9f0vv32ijd";
1926 sha256 = "1bkqwmf056pkchf05ywbnf659wqlp6lljcdb0y88wr9f0vv32ijd";
1920 };
1927 };
1921 meta = {
1928 meta = {
1922 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "New BSD License"; } ];
1929 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "New BSD License"; } ];
1923 };
1930 };
1924 };
1931 };
1925 "setproctitle" = super.buildPythonPackage {
1932 "setproctitle" = super.buildPythonPackage {
1926 name = "setproctitle-1.1.10";
1933 name = "setproctitle-1.1.10";
1927 doCheck = false;
1934 doCheck = false;
1928 src = fetchurl {
1935 src = fetchurl {
1929 url = "https://files.pythonhosted.org/packages/5a/0d/dc0d2234aacba6cf1a729964383e3452c52096dc695581248b548786f2b3/setproctitle-1.1.10.tar.gz";
1936 url = "https://files.pythonhosted.org/packages/5a/0d/dc0d2234aacba6cf1a729964383e3452c52096dc695581248b548786f2b3/setproctitle-1.1.10.tar.gz";
1930 sha256 = "163kplw9dcrw0lffq1bvli5yws3rngpnvrxrzdw89pbphjjvg0v2";
1937 sha256 = "163kplw9dcrw0lffq1bvli5yws3rngpnvrxrzdw89pbphjjvg0v2";
1931 };
1938 };
1932 meta = {
1939 meta = {
1933 license = [ pkgs.lib.licenses.bsdOriginal ];
1940 license = [ pkgs.lib.licenses.bsdOriginal ];
1934 };
1941 };
1935 };
1942 };
1936 "setuptools" = super.buildPythonPackage {
1943 "setuptools" = super.buildPythonPackage {
1937 name = "setuptools-41.2.0";
1944 name = "setuptools-41.2.0";
1938 doCheck = false;
1945 doCheck = false;
1939 src = fetchurl {
1946 src = fetchurl {
1940 url = "https://files.pythonhosted.org/packages/d9/ca/7279974e489e8b65003fe618a1a741d6350227fa2bf48d16be76c7422423/setuptools-41.2.0.zip";
1947 url = "https://files.pythonhosted.org/packages/d9/ca/7279974e489e8b65003fe618a1a741d6350227fa2bf48d16be76c7422423/setuptools-41.2.0.zip";
1941 sha256 = "04k0dp9msmlv3g3zx7f5p8wdjr6hdf5c0bgmczlc4yncwyx6pf36";
1948 sha256 = "04k0dp9msmlv3g3zx7f5p8wdjr6hdf5c0bgmczlc4yncwyx6pf36";
1942 };
1949 };
1943 meta = {
1950 meta = {
1944 license = [ pkgs.lib.licenses.mit ];
1951 license = [ pkgs.lib.licenses.mit ];
1945 };
1952 };
1946 };
1953 };
1947 "simplegeneric" = super.buildPythonPackage {
1954 "simplegeneric" = super.buildPythonPackage {
1948 name = "simplegeneric-0.8.1";
1955 name = "simplegeneric-0.8.1";
1949 doCheck = false;
1956 doCheck = false;
1950 src = fetchurl {
1957 src = fetchurl {
1951 url = "https://files.pythonhosted.org/packages/3d/57/4d9c9e3ae9a255cd4e1106bb57e24056d3d0709fc01b2e3e345898e49d5b/simplegeneric-0.8.1.zip";
1958 url = "https://files.pythonhosted.org/packages/3d/57/4d9c9e3ae9a255cd4e1106bb57e24056d3d0709fc01b2e3e345898e49d5b/simplegeneric-0.8.1.zip";
1952 sha256 = "0wwi1c6md4vkbcsfsf8dklf3vr4mcdj4mpxkanwgb6jb1432x5yw";
1959 sha256 = "0wwi1c6md4vkbcsfsf8dklf3vr4mcdj4mpxkanwgb6jb1432x5yw";
1953 };
1960 };
1954 meta = {
1961 meta = {
1955 license = [ pkgs.lib.licenses.zpl21 ];
1962 license = [ pkgs.lib.licenses.zpl21 ];
1956 };
1963 };
1957 };
1964 };
1958 "simplejson" = super.buildPythonPackage {
1965 "simplejson" = super.buildPythonPackage {
1959 name = "simplejson-3.16.0";
1966 name = "simplejson-3.16.0";
1960 doCheck = false;
1967 doCheck = false;
1961 src = fetchurl {
1968 src = fetchurl {
1962 url = "https://files.pythonhosted.org/packages/e3/24/c35fb1c1c315fc0fffe61ea00d3f88e85469004713dab488dee4f35b0aff/simplejson-3.16.0.tar.gz";
1969 url = "https://files.pythonhosted.org/packages/e3/24/c35fb1c1c315fc0fffe61ea00d3f88e85469004713dab488dee4f35b0aff/simplejson-3.16.0.tar.gz";
1963 sha256 = "19cws1syk8jzq2pw43878dv6fjkb0ifvjpx0i9aajix6kc9jkwxi";
1970 sha256 = "19cws1syk8jzq2pw43878dv6fjkb0ifvjpx0i9aajix6kc9jkwxi";
1964 };
1971 };
1965 meta = {
1972 meta = {
1966 license = [ { fullName = "Academic Free License (AFL)"; } pkgs.lib.licenses.mit ];
1973 license = [ { fullName = "Academic Free License (AFL)"; } pkgs.lib.licenses.mit ];
1967 };
1974 };
1968 };
1975 };
1969 "six" = super.buildPythonPackage {
1976 "six" = super.buildPythonPackage {
1970 name = "six-1.11.0";
1977 name = "six-1.11.0";
1971 doCheck = false;
1978 doCheck = false;
1972 src = fetchurl {
1979 src = fetchurl {
1973 url = "https://files.pythonhosted.org/packages/16/d8/bc6316cf98419719bd59c91742194c111b6f2e85abac88e496adefaf7afe/six-1.11.0.tar.gz";
1980 url = "https://files.pythonhosted.org/packages/16/d8/bc6316cf98419719bd59c91742194c111b6f2e85abac88e496adefaf7afe/six-1.11.0.tar.gz";
1974 sha256 = "1scqzwc51c875z23phj48gircqjgnn3af8zy2izjwmnlxrxsgs3h";
1981 sha256 = "1scqzwc51c875z23phj48gircqjgnn3af8zy2izjwmnlxrxsgs3h";
1975 };
1982 };
1976 meta = {
1983 meta = {
1977 license = [ pkgs.lib.licenses.mit ];
1984 license = [ pkgs.lib.licenses.mit ];
1978 };
1985 };
1979 };
1986 };
1980 "sqlalchemy" = super.buildPythonPackage {
1987 "sqlalchemy" = super.buildPythonPackage {
1981 name = "sqlalchemy-1.1.18";
1988 name = "sqlalchemy-1.1.18";
1982 doCheck = false;
1989 doCheck = false;
1983 src = fetchurl {
1990 src = fetchurl {
1984 url = "https://files.pythonhosted.org/packages/cc/4d/96d93ff77cd67aca7618e402191eee3490d8f5f245d6ab7622d35fe504f4/SQLAlchemy-1.1.18.tar.gz";
1991 url = "https://files.pythonhosted.org/packages/cc/4d/96d93ff77cd67aca7618e402191eee3490d8f5f245d6ab7622d35fe504f4/SQLAlchemy-1.1.18.tar.gz";
1985 sha256 = "1ab4ysip6irajfbxl9wy27kv76miaz8h6759hfx92499z4dcf3lb";
1992 sha256 = "1ab4ysip6irajfbxl9wy27kv76miaz8h6759hfx92499z4dcf3lb";
1986 };
1993 };
1987 meta = {
1994 meta = {
1988 license = [ pkgs.lib.licenses.mit ];
1995 license = [ pkgs.lib.licenses.mit ];
1989 };
1996 };
1990 };
1997 };
1991 "sshpubkeys" = super.buildPythonPackage {
1998 "sshpubkeys" = super.buildPythonPackage {
1992 name = "sshpubkeys-3.1.0";
1999 name = "sshpubkeys-3.1.0";
1993 doCheck = false;
2000 doCheck = false;
1994 propagatedBuildInputs = [
2001 propagatedBuildInputs = [
1995 self."cryptography"
2002 self."cryptography"
1996 self."ecdsa"
2003 self."ecdsa"
1997 ];
2004 ];
1998 src = fetchurl {
2005 src = fetchurl {
1999 url = "https://files.pythonhosted.org/packages/00/23/f7508a12007c96861c3da811992f14283d79c819d71a217b3e12d5196649/sshpubkeys-3.1.0.tar.gz";
2006 url = "https://files.pythonhosted.org/packages/00/23/f7508a12007c96861c3da811992f14283d79c819d71a217b3e12d5196649/sshpubkeys-3.1.0.tar.gz";
2000 sha256 = "105g2li04nm1hb15a2y6hm9m9k7fbrkd5l3gy12w3kgcmsf3k25k";
2007 sha256 = "105g2li04nm1hb15a2y6hm9m9k7fbrkd5l3gy12w3kgcmsf3k25k";
2001 };
2008 };
2002 meta = {
2009 meta = {
2003 license = [ pkgs.lib.licenses.bsdOriginal ];
2010 license = [ pkgs.lib.licenses.bsdOriginal ];
2004 };
2011 };
2005 };
2012 };
2006 "subprocess32" = super.buildPythonPackage {
2013 "subprocess32" = super.buildPythonPackage {
2007 name = "subprocess32-3.5.4";
2014 name = "subprocess32-3.5.4";
2008 doCheck = false;
2015 doCheck = false;
2009 src = fetchurl {
2016 src = fetchurl {
2010 url = "https://files.pythonhosted.org/packages/32/c8/564be4d12629b912ea431f1a50eb8b3b9d00f1a0b1ceff17f266be190007/subprocess32-3.5.4.tar.gz";
2017 url = "https://files.pythonhosted.org/packages/32/c8/564be4d12629b912ea431f1a50eb8b3b9d00f1a0b1ceff17f266be190007/subprocess32-3.5.4.tar.gz";
2011 sha256 = "17f7mvwx2271s1wrl0qac3wjqqnrqag866zs3qc8v5wp0k43fagb";
2018 sha256 = "17f7mvwx2271s1wrl0qac3wjqqnrqag866zs3qc8v5wp0k43fagb";
2012 };
2019 };
2013 meta = {
2020 meta = {
2014 license = [ pkgs.lib.licenses.psfl ];
2021 license = [ pkgs.lib.licenses.psfl ];
2015 };
2022 };
2016 };
2023 };
2017 "supervisor" = super.buildPythonPackage {
2024 "supervisor" = super.buildPythonPackage {
2018 name = "supervisor-4.0.3";
2025 name = "supervisor-4.0.3";
2019 doCheck = false;
2026 doCheck = false;
2020 propagatedBuildInputs = [
2027 propagatedBuildInputs = [
2021 self."meld3"
2028 self."meld3"
2022 ];
2029 ];
2023 src = fetchurl {
2030 src = fetchurl {
2024 url = "https://files.pythonhosted.org/packages/97/48/f38bf70bd9282d1a18d591616557cc1a77a1c627d57dff66ead65c891dc8/supervisor-4.0.3.tar.gz";
2031 url = "https://files.pythonhosted.org/packages/97/48/f38bf70bd9282d1a18d591616557cc1a77a1c627d57dff66ead65c891dc8/supervisor-4.0.3.tar.gz";
2025 sha256 = "17hla7mx6w5m5jzkkjxgqa8wpswqmfhbhf49f692hw78fg0ans7p";
2032 sha256 = "17hla7mx6w5m5jzkkjxgqa8wpswqmfhbhf49f692hw78fg0ans7p";
2026 };
2033 };
2027 meta = {
2034 meta = {
2028 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
2035 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
2029 };
2036 };
2030 };
2037 };
2031 "tempita" = super.buildPythonPackage {
2038 "tempita" = super.buildPythonPackage {
2032 name = "tempita-0.5.2";
2039 name = "tempita-0.5.2";
2033 doCheck = false;
2040 doCheck = false;
2034 src = fetchurl {
2041 src = fetchurl {
2035 url = "https://files.pythonhosted.org/packages/56/c8/8ed6eee83dbddf7b0fc64dd5d4454bc05e6ccaafff47991f73f2894d9ff4/Tempita-0.5.2.tar.gz";
2042 url = "https://files.pythonhosted.org/packages/56/c8/8ed6eee83dbddf7b0fc64dd5d4454bc05e6ccaafff47991f73f2894d9ff4/Tempita-0.5.2.tar.gz";
2036 sha256 = "177wwq45slfyajd8csy477bmdmzipyw0dm7i85k3akb7m85wzkna";
2043 sha256 = "177wwq45slfyajd8csy477bmdmzipyw0dm7i85k3akb7m85wzkna";
2037 };
2044 };
2038 meta = {
2045 meta = {
2039 license = [ pkgs.lib.licenses.mit ];
2046 license = [ pkgs.lib.licenses.mit ];
2040 };
2047 };
2041 };
2048 };
2042 "termcolor" = super.buildPythonPackage {
2049 "termcolor" = super.buildPythonPackage {
2043 name = "termcolor-1.1.0";
2050 name = "termcolor-1.1.0";
2044 doCheck = false;
2051 doCheck = false;
2045 src = fetchurl {
2052 src = fetchurl {
2046 url = "https://files.pythonhosted.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz";
2053 url = "https://files.pythonhosted.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz";
2047 sha256 = "0fv1vq14rpqwgazxg4981904lfyp84mnammw7y046491cv76jv8x";
2054 sha256 = "0fv1vq14rpqwgazxg4981904lfyp84mnammw7y046491cv76jv8x";
2048 };
2055 };
2049 meta = {
2056 meta = {
2050 license = [ pkgs.lib.licenses.mit ];
2057 license = [ pkgs.lib.licenses.mit ];
2051 };
2058 };
2052 };
2059 };
2053 "testpath" = super.buildPythonPackage {
2060 "testpath" = super.buildPythonPackage {
2054 name = "testpath-0.4.2";
2061 name = "testpath-0.4.2";
2055 doCheck = false;
2062 doCheck = false;
2056 src = fetchurl {
2063 src = fetchurl {
2057 url = "https://files.pythonhosted.org/packages/06/30/9a7e917066d851d8b4117e85794b5f14516419ea714a8a2681ec6aa8a981/testpath-0.4.2.tar.gz";
2064 url = "https://files.pythonhosted.org/packages/06/30/9a7e917066d851d8b4117e85794b5f14516419ea714a8a2681ec6aa8a981/testpath-0.4.2.tar.gz";
2058 sha256 = "1y40hywscnnyb734pnzm55nd8r8kp1072bjxbil83gcd53cv755n";
2065 sha256 = "1y40hywscnnyb734pnzm55nd8r8kp1072bjxbil83gcd53cv755n";
2059 };
2066 };
2060 meta = {
2067 meta = {
2061 license = [ ];
2068 license = [ ];
2062 };
2069 };
2063 };
2070 };
2064 "traitlets" = super.buildPythonPackage {
2071 "traitlets" = super.buildPythonPackage {
2065 name = "traitlets-4.3.2";
2072 name = "traitlets-4.3.2";
2066 doCheck = false;
2073 doCheck = false;
2067 propagatedBuildInputs = [
2074 propagatedBuildInputs = [
2068 self."ipython-genutils"
2075 self."ipython-genutils"
2069 self."six"
2076 self."six"
2070 self."decorator"
2077 self."decorator"
2071 self."enum34"
2078 self."enum34"
2072 ];
2079 ];
2073 src = fetchurl {
2080 src = fetchurl {
2074 url = "https://files.pythonhosted.org/packages/a5/98/7f5ef2fe9e9e071813aaf9cb91d1a732e0a68b6c44a32b38cb8e14c3f069/traitlets-4.3.2.tar.gz";
2081 url = "https://files.pythonhosted.org/packages/a5/98/7f5ef2fe9e9e071813aaf9cb91d1a732e0a68b6c44a32b38cb8e14c3f069/traitlets-4.3.2.tar.gz";
2075 sha256 = "0dbq7sx26xqz5ixs711k5nc88p8a0nqyz6162pwks5dpcz9d4jww";
2082 sha256 = "0dbq7sx26xqz5ixs711k5nc88p8a0nqyz6162pwks5dpcz9d4jww";
2076 };
2083 };
2077 meta = {
2084 meta = {
2078 license = [ pkgs.lib.licenses.bsdOriginal ];
2085 license = [ pkgs.lib.licenses.bsdOriginal ];
2079 };
2086 };
2080 };
2087 };
2081 "transaction" = super.buildPythonPackage {
2088 "transaction" = super.buildPythonPackage {
2082 name = "transaction-2.4.0";
2089 name = "transaction-2.4.0";
2083 doCheck = false;
2090 doCheck = false;
2084 propagatedBuildInputs = [
2091 propagatedBuildInputs = [
2085 self."zope.interface"
2092 self."zope.interface"
2086 ];
2093 ];
2087 src = fetchurl {
2094 src = fetchurl {
2088 url = "https://files.pythonhosted.org/packages/9d/7d/0e8af0d059e052b9dcf2bb5a08aad20ae3e238746bdd3f8701a60969b363/transaction-2.4.0.tar.gz";
2095 url = "https://files.pythonhosted.org/packages/9d/7d/0e8af0d059e052b9dcf2bb5a08aad20ae3e238746bdd3f8701a60969b363/transaction-2.4.0.tar.gz";
2089 sha256 = "17wz1y524ca07vr03yddy8dv0gbscs06dbdywmllxv5rc725jq3j";
2096 sha256 = "17wz1y524ca07vr03yddy8dv0gbscs06dbdywmllxv5rc725jq3j";
2090 };
2097 };
2091 meta = {
2098 meta = {
2092 license = [ pkgs.lib.licenses.zpl21 ];
2099 license = [ pkgs.lib.licenses.zpl21 ];
2093 };
2100 };
2094 };
2101 };
2095 "translationstring" = super.buildPythonPackage {
2102 "translationstring" = super.buildPythonPackage {
2096 name = "translationstring-1.3";
2103 name = "translationstring-1.3";
2097 doCheck = false;
2104 doCheck = false;
2098 src = fetchurl {
2105 src = fetchurl {
2099 url = "https://files.pythonhosted.org/packages/5e/eb/bee578cc150b44c653b63f5ebe258b5d0d812ddac12497e5f80fcad5d0b4/translationstring-1.3.tar.gz";
2106 url = "https://files.pythonhosted.org/packages/5e/eb/bee578cc150b44c653b63f5ebe258b5d0d812ddac12497e5f80fcad5d0b4/translationstring-1.3.tar.gz";
2100 sha256 = "0bdpcnd9pv0131dl08h4zbcwmgc45lyvq3pa224xwan5b3x4rr2f";
2107 sha256 = "0bdpcnd9pv0131dl08h4zbcwmgc45lyvq3pa224xwan5b3x4rr2f";
2101 };
2108 };
2102 meta = {
2109 meta = {
2103 license = [ { fullName = "BSD-like (http://repoze.org/license.html)"; } ];
2110 license = [ { fullName = "BSD-like (http://repoze.org/license.html)"; } ];
2104 };
2111 };
2105 };
2112 };
2106 "tzlocal" = super.buildPythonPackage {
2113 "tzlocal" = super.buildPythonPackage {
2107 name = "tzlocal-1.5.1";
2114 name = "tzlocal-1.5.1";
2108 doCheck = false;
2115 doCheck = false;
2109 propagatedBuildInputs = [
2116 propagatedBuildInputs = [
2110 self."pytz"
2117 self."pytz"
2111 ];
2118 ];
2112 src = fetchurl {
2119 src = fetchurl {
2113 url = "https://files.pythonhosted.org/packages/cb/89/e3687d3ed99bc882793f82634e9824e62499fdfdc4b1ae39e211c5b05017/tzlocal-1.5.1.tar.gz";
2120 url = "https://files.pythonhosted.org/packages/cb/89/e3687d3ed99bc882793f82634e9824e62499fdfdc4b1ae39e211c5b05017/tzlocal-1.5.1.tar.gz";
2114 sha256 = "0kiciwiqx0bv0fbc913idxibc4ygg4cb7f8rcpd9ij2shi4bigjf";
2121 sha256 = "0kiciwiqx0bv0fbc913idxibc4ygg4cb7f8rcpd9ij2shi4bigjf";
2115 };
2122 };
2116 meta = {
2123 meta = {
2117 license = [ pkgs.lib.licenses.mit ];
2124 license = [ pkgs.lib.licenses.mit ];
2118 };
2125 };
2119 };
2126 };
2120 "urllib3" = super.buildPythonPackage {
2127 "urllib3" = super.buildPythonPackage {
2121 name = "urllib3-1.24.1";
2128 name = "urllib3-1.24.1";
2122 doCheck = false;
2129 doCheck = false;
2123 src = fetchurl {
2130 src = fetchurl {
2124 url = "https://files.pythonhosted.org/packages/b1/53/37d82ab391393565f2f831b8eedbffd57db5a718216f82f1a8b4d381a1c1/urllib3-1.24.1.tar.gz";
2131 url = "https://files.pythonhosted.org/packages/b1/53/37d82ab391393565f2f831b8eedbffd57db5a718216f82f1a8b4d381a1c1/urllib3-1.24.1.tar.gz";
2125 sha256 = "08lwd9f3hqznyf32vnzwvp87pchx062nkbgyrf67rwlkgj0jk5fy";
2132 sha256 = "08lwd9f3hqznyf32vnzwvp87pchx062nkbgyrf67rwlkgj0jk5fy";
2126 };
2133 };
2127 meta = {
2134 meta = {
2128 license = [ pkgs.lib.licenses.mit ];
2135 license = [ pkgs.lib.licenses.mit ];
2129 };
2136 };
2130 };
2137 };
2131 "urlobject" = super.buildPythonPackage {
2138 "urlobject" = super.buildPythonPackage {
2132 name = "urlobject-2.4.3";
2139 name = "urlobject-2.4.3";
2133 doCheck = false;
2140 doCheck = false;
2134 src = fetchurl {
2141 src = fetchurl {
2135 url = "https://files.pythonhosted.org/packages/e2/b8/1d0a916f4b34c4618846e6da0e4eeaa8fcb4a2f39e006434fe38acb74b34/URLObject-2.4.3.tar.gz";
2142 url = "https://files.pythonhosted.org/packages/e2/b8/1d0a916f4b34c4618846e6da0e4eeaa8fcb4a2f39e006434fe38acb74b34/URLObject-2.4.3.tar.gz";
2136 sha256 = "1ahc8ficzfvr2avln71immfh4ls0zyv6cdaa5xmkdj5rd87f5cj7";
2143 sha256 = "1ahc8ficzfvr2avln71immfh4ls0zyv6cdaa5xmkdj5rd87f5cj7";
2137 };
2144 };
2138 meta = {
2145 meta = {
2139 license = [ pkgs.lib.licenses.publicDomain ];
2146 license = [ pkgs.lib.licenses.publicDomain ];
2140 };
2147 };
2141 };
2148 };
2142 "venusian" = super.buildPythonPackage {
2149 "venusian" = super.buildPythonPackage {
2143 name = "venusian-1.2.0";
2150 name = "venusian-1.2.0";
2144 doCheck = false;
2151 doCheck = false;
2145 src = fetchurl {
2152 src = fetchurl {
2146 url = "https://files.pythonhosted.org/packages/7e/6f/40a9d43ac77cb51cb62be5b5662d170f43f8037bdc4eab56336c4ca92bb7/venusian-1.2.0.tar.gz";
2153 url = "https://files.pythonhosted.org/packages/7e/6f/40a9d43ac77cb51cb62be5b5662d170f43f8037bdc4eab56336c4ca92bb7/venusian-1.2.0.tar.gz";
2147 sha256 = "0ghyx66g8ikx9nx1mnwqvdcqm11i1vlq0hnvwl50s48bp22q5v34";
2154 sha256 = "0ghyx66g8ikx9nx1mnwqvdcqm11i1vlq0hnvwl50s48bp22q5v34";
2148 };
2155 };
2149 meta = {
2156 meta = {
2150 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
2157 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
2151 };
2158 };
2152 };
2159 };
2153 "vine" = super.buildPythonPackage {
2160 "vine" = super.buildPythonPackage {
2154 name = "vine-1.3.0";
2161 name = "vine-1.3.0";
2155 doCheck = false;
2162 doCheck = false;
2156 src = fetchurl {
2163 src = fetchurl {
2157 url = "https://files.pythonhosted.org/packages/1c/e1/79fb8046e607dd6c2ad05c9b8ebac9d0bd31d086a08f02699e96fc5b3046/vine-1.3.0.tar.gz";
2164 url = "https://files.pythonhosted.org/packages/1c/e1/79fb8046e607dd6c2ad05c9b8ebac9d0bd31d086a08f02699e96fc5b3046/vine-1.3.0.tar.gz";
2158 sha256 = "11ydsbhl1vabndc2r979dv61s6j2b0giq6dgvryifvq1m7bycghk";
2165 sha256 = "11ydsbhl1vabndc2r979dv61s6j2b0giq6dgvryifvq1m7bycghk";
2159 };
2166 };
2160 meta = {
2167 meta = {
2161 license = [ pkgs.lib.licenses.bsdOriginal ];
2168 license = [ pkgs.lib.licenses.bsdOriginal ];
2162 };
2169 };
2163 };
2170 };
2164 "waitress" = super.buildPythonPackage {
2171 "waitress" = super.buildPythonPackage {
2165 name = "waitress-1.3.1";
2172 name = "waitress-1.3.1";
2166 doCheck = false;
2173 doCheck = false;
2167 src = fetchurl {
2174 src = fetchurl {
2168 url = "https://files.pythonhosted.org/packages/a6/e6/708da7bba65898e5d759ade8391b1077e49d07be0b0223c39f5be04def56/waitress-1.3.1.tar.gz";
2175 url = "https://files.pythonhosted.org/packages/a6/e6/708da7bba65898e5d759ade8391b1077e49d07be0b0223c39f5be04def56/waitress-1.3.1.tar.gz";
2169 sha256 = "1iysl8ka3l4cdrr0r19fh1cv28q41mwpvgsb81ji7k4shkb0k3i7";
2176 sha256 = "1iysl8ka3l4cdrr0r19fh1cv28q41mwpvgsb81ji7k4shkb0k3i7";
2170 };
2177 };
2171 meta = {
2178 meta = {
2172 license = [ pkgs.lib.licenses.zpl21 ];
2179 license = [ pkgs.lib.licenses.zpl21 ];
2173 };
2180 };
2174 };
2181 };
2175 "wcwidth" = super.buildPythonPackage {
2182 "wcwidth" = super.buildPythonPackage {
2176 name = "wcwidth-0.1.7";
2183 name = "wcwidth-0.1.7";
2177 doCheck = false;
2184 doCheck = false;
2178 src = fetchurl {
2185 src = fetchurl {
2179 url = "https://files.pythonhosted.org/packages/55/11/e4a2bb08bb450fdbd42cc709dd40de4ed2c472cf0ccb9e64af22279c5495/wcwidth-0.1.7.tar.gz";
2186 url = "https://files.pythonhosted.org/packages/55/11/e4a2bb08bb450fdbd42cc709dd40de4ed2c472cf0ccb9e64af22279c5495/wcwidth-0.1.7.tar.gz";
2180 sha256 = "0pn6dflzm609m4r3i8ik5ni9ijjbb5fa3vg1n7hn6vkd49r77wrx";
2187 sha256 = "0pn6dflzm609m4r3i8ik5ni9ijjbb5fa3vg1n7hn6vkd49r77wrx";
2181 };
2188 };
2182 meta = {
2189 meta = {
2183 license = [ pkgs.lib.licenses.mit ];
2190 license = [ pkgs.lib.licenses.mit ];
2184 };
2191 };
2185 };
2192 };
2186 "webencodings" = super.buildPythonPackage {
2193 "webencodings" = super.buildPythonPackage {
2187 name = "webencodings-0.5.1";
2194 name = "webencodings-0.5.1";
2188 doCheck = false;
2195 doCheck = false;
2189 src = fetchurl {
2196 src = fetchurl {
2190 url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz";
2197 url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz";
2191 sha256 = "08qrgrc4hrximb2gqnl69g01s93rhf2842jfxdjljc1dbwj1qsmk";
2198 sha256 = "08qrgrc4hrximb2gqnl69g01s93rhf2842jfxdjljc1dbwj1qsmk";
2192 };
2199 };
2193 meta = {
2200 meta = {
2194 license = [ pkgs.lib.licenses.bsdOriginal ];
2201 license = [ pkgs.lib.licenses.bsdOriginal ];
2195 };
2202 };
2196 };
2203 };
2197 "weberror" = super.buildPythonPackage {
2204 "weberror" = super.buildPythonPackage {
2198 name = "weberror-0.10.3";
2205 name = "weberror-0.10.3";
2199 doCheck = false;
2206 doCheck = false;
2200 propagatedBuildInputs = [
2207 propagatedBuildInputs = [
2201 self."webob"
2208 self."webob"
2202 self."tempita"
2209 self."tempita"
2203 self."pygments"
2210 self."pygments"
2204 self."paste"
2211 self."paste"
2205 ];
2212 ];
2206 src = fetchurl {
2213 src = fetchurl {
2207 url = "https://files.pythonhosted.org/packages/35/76/e7e5c2ce7e9c7f31b54c1ff295a495886d1279a002557d74dd8957346a79/WebError-0.10.3.tar.gz";
2214 url = "https://files.pythonhosted.org/packages/35/76/e7e5c2ce7e9c7f31b54c1ff295a495886d1279a002557d74dd8957346a79/WebError-0.10.3.tar.gz";
2208 sha256 = "0frg4kvycqpj5bi8asfqfs6bxsr2cvjvb6b56c4d1ai1z57kbjx6";
2215 sha256 = "0frg4kvycqpj5bi8asfqfs6bxsr2cvjvb6b56c4d1ai1z57kbjx6";
2209 };
2216 };
2210 meta = {
2217 meta = {
2211 license = [ pkgs.lib.licenses.mit ];
2218 license = [ pkgs.lib.licenses.mit ];
2212 };
2219 };
2213 };
2220 };
2214 "webhelpers" = super.buildPythonPackage {
2221 "webhelpers" = super.buildPythonPackage {
2215 name = "webhelpers-1.3";
2222 name = "webhelpers-1.3";
2216 doCheck = false;
2223 doCheck = false;
2217 propagatedBuildInputs = [
2224 propagatedBuildInputs = [
2218 self."markupsafe"
2225 self."markupsafe"
2219 ];
2226 ];
2220 src = fetchurl {
2227 src = fetchurl {
2221 url = "https://files.pythonhosted.org/packages/ee/68/4d07672821d514184357f1552f2dad923324f597e722de3b016ca4f7844f/WebHelpers-1.3.tar.gz";
2228 url = "https://files.pythonhosted.org/packages/ee/68/4d07672821d514184357f1552f2dad923324f597e722de3b016ca4f7844f/WebHelpers-1.3.tar.gz";
2222 sha256 = "10x5i82qdkrvyw18gsybwggfhfpl869siaab89vnndi9x62g51pa";
2229 sha256 = "10x5i82qdkrvyw18gsybwggfhfpl869siaab89vnndi9x62g51pa";
2223 };
2230 };
2224 meta = {
2231 meta = {
2225 license = [ pkgs.lib.licenses.bsdOriginal ];
2232 license = [ pkgs.lib.licenses.bsdOriginal ];
2226 };
2233 };
2227 };
2234 };
2228 "webhelpers2" = super.buildPythonPackage {
2235 "webhelpers2" = super.buildPythonPackage {
2229 name = "webhelpers2-2.0";
2236 name = "webhelpers2-2.0";
2230 doCheck = false;
2237 doCheck = false;
2231 propagatedBuildInputs = [
2238 propagatedBuildInputs = [
2232 self."markupsafe"
2239 self."markupsafe"
2233 self."six"
2240 self."six"
2234 ];
2241 ];
2235 src = fetchurl {
2242 src = fetchurl {
2236 url = "https://files.pythonhosted.org/packages/ff/30/56342c6ea522439e3662427c8d7b5e5b390dff4ff2dc92d8afcb8ab68b75/WebHelpers2-2.0.tar.gz";
2243 url = "https://files.pythonhosted.org/packages/ff/30/56342c6ea522439e3662427c8d7b5e5b390dff4ff2dc92d8afcb8ab68b75/WebHelpers2-2.0.tar.gz";
2237 sha256 = "0aphva1qmxh83n01p53f5fd43m4srzbnfbz5ajvbx9aj2aipwmcs";
2244 sha256 = "0aphva1qmxh83n01p53f5fd43m4srzbnfbz5ajvbx9aj2aipwmcs";
2238 };
2245 };
2239 meta = {
2246 meta = {
2240 license = [ pkgs.lib.licenses.mit ];
2247 license = [ pkgs.lib.licenses.mit ];
2241 };
2248 };
2242 };
2249 };
2243 "webob" = super.buildPythonPackage {
2250 "webob" = super.buildPythonPackage {
2244 name = "webob-1.8.5";
2251 name = "webob-1.8.5";
2245 doCheck = false;
2252 doCheck = false;
2246 src = fetchurl {
2253 src = fetchurl {
2247 url = "https://files.pythonhosted.org/packages/9d/1a/0c89c070ee2829c934cb6c7082287c822e28236a4fcf90063e6be7c35532/WebOb-1.8.5.tar.gz";
2254 url = "https://files.pythonhosted.org/packages/9d/1a/0c89c070ee2829c934cb6c7082287c822e28236a4fcf90063e6be7c35532/WebOb-1.8.5.tar.gz";
2248 sha256 = "11khpzaxc88q31v25ic330gsf56fwmbdc9b30br8mvp0fmwspah5";
2255 sha256 = "11khpzaxc88q31v25ic330gsf56fwmbdc9b30br8mvp0fmwspah5";
2249 };
2256 };
2250 meta = {
2257 meta = {
2251 license = [ pkgs.lib.licenses.mit ];
2258 license = [ pkgs.lib.licenses.mit ];
2252 };
2259 };
2253 };
2260 };
2254 "webtest" = super.buildPythonPackage {
2261 "webtest" = super.buildPythonPackage {
2255 name = "webtest-2.0.33";
2262 name = "webtest-2.0.33";
2256 doCheck = false;
2263 doCheck = false;
2257 propagatedBuildInputs = [
2264 propagatedBuildInputs = [
2258 self."six"
2265 self."six"
2259 self."webob"
2266 self."webob"
2260 self."waitress"
2267 self."waitress"
2261 self."beautifulsoup4"
2268 self."beautifulsoup4"
2262 ];
2269 ];
2263 src = fetchurl {
2270 src = fetchurl {
2264 url = "https://files.pythonhosted.org/packages/a8/b0/ffc9413b637dbe26e291429bb0f6ed731e518d0cd03da28524a8fe2e8a8f/WebTest-2.0.33.tar.gz";
2271 url = "https://files.pythonhosted.org/packages/a8/b0/ffc9413b637dbe26e291429bb0f6ed731e518d0cd03da28524a8fe2e8a8f/WebTest-2.0.33.tar.gz";
2265 sha256 = "1l3z0cwqslsf4rcrhi2gr8kdfh74wn2dw76376i4g9i38gz8wd21";
2272 sha256 = "1l3z0cwqslsf4rcrhi2gr8kdfh74wn2dw76376i4g9i38gz8wd21";
2266 };
2273 };
2267 meta = {
2274 meta = {
2268 license = [ pkgs.lib.licenses.mit ];
2275 license = [ pkgs.lib.licenses.mit ];
2269 };
2276 };
2270 };
2277 };
2271 "whoosh" = super.buildPythonPackage {
2278 "whoosh" = super.buildPythonPackage {
2272 name = "whoosh-2.7.4";
2279 name = "whoosh-2.7.4";
2273 doCheck = false;
2280 doCheck = false;
2274 src = fetchurl {
2281 src = fetchurl {
2275 url = "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz";
2282 url = "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz";
2276 sha256 = "10qsqdjpbc85fykc1vgcs8xwbgn4l2l52c8d83xf1q59pwyn79bw";
2283 sha256 = "10qsqdjpbc85fykc1vgcs8xwbgn4l2l52c8d83xf1q59pwyn79bw";
2277 };
2284 };
2278 meta = {
2285 meta = {
2279 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ];
2286 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ];
2280 };
2287 };
2281 };
2288 };
2282 "ws4py" = super.buildPythonPackage {
2289 "ws4py" = super.buildPythonPackage {
2283 name = "ws4py-0.5.1";
2290 name = "ws4py-0.5.1";
2284 doCheck = false;
2291 doCheck = false;
2285 src = fetchurl {
2292 src = fetchurl {
2286 url = "https://files.pythonhosted.org/packages/53/20/4019a739b2eefe9282d3822ef6a225250af964b117356971bd55e274193c/ws4py-0.5.1.tar.gz";
2293 url = "https://files.pythonhosted.org/packages/53/20/4019a739b2eefe9282d3822ef6a225250af964b117356971bd55e274193c/ws4py-0.5.1.tar.gz";
2287 sha256 = "10slbbf2jm4hpr92jx7kh7mhf48sjl01v2w4d8z3f1p0ybbp7l19";
2294 sha256 = "10slbbf2jm4hpr92jx7kh7mhf48sjl01v2w4d8z3f1p0ybbp7l19";
2288 };
2295 };
2289 meta = {
2296 meta = {
2290 license = [ pkgs.lib.licenses.bsdOriginal ];
2297 license = [ pkgs.lib.licenses.bsdOriginal ];
2291 };
2298 };
2292 };
2299 };
2293 "wsgiref" = super.buildPythonPackage {
2300 "wsgiref" = super.buildPythonPackage {
2294 name = "wsgiref-0.1.2";
2301 name = "wsgiref-0.1.2";
2295 doCheck = false;
2302 doCheck = false;
2296 src = fetchurl {
2303 src = fetchurl {
2297 url = "https://files.pythonhosted.org/packages/41/9e/309259ce8dff8c596e8c26df86dbc4e848b9249fd36797fd60be456f03fc/wsgiref-0.1.2.zip";
2304 url = "https://files.pythonhosted.org/packages/41/9e/309259ce8dff8c596e8c26df86dbc4e848b9249fd36797fd60be456f03fc/wsgiref-0.1.2.zip";
2298 sha256 = "0y8fyjmpq7vwwm4x732w97qbkw78rjwal5409k04cw4m03411rn7";
2305 sha256 = "0y8fyjmpq7vwwm4x732w97qbkw78rjwal5409k04cw4m03411rn7";
2299 };
2306 };
2300 meta = {
2307 meta = {
2301 license = [ { fullName = "PSF or ZPL"; } ];
2308 license = [ { fullName = "PSF or ZPL"; } ];
2302 };
2309 };
2303 };
2310 };
2304 "zipp" = super.buildPythonPackage {
2311 "zipp" = super.buildPythonPackage {
2305 name = "zipp-0.6.0";
2312 name = "zipp-0.6.0";
2306 doCheck = false;
2313 doCheck = false;
2307 propagatedBuildInputs = [
2314 propagatedBuildInputs = [
2308 self."more-itertools"
2315 self."more-itertools"
2309 ];
2316 ];
2310 src = fetchurl {
2317 src = fetchurl {
2311 url = "https://files.pythonhosted.org/packages/57/dd/585d728479d97d25aeeb9aa470d36a4ad8d0ba5610f84e14770128ce6ff7/zipp-0.6.0.tar.gz";
2318 url = "https://files.pythonhosted.org/packages/57/dd/585d728479d97d25aeeb9aa470d36a4ad8d0ba5610f84e14770128ce6ff7/zipp-0.6.0.tar.gz";
2312 sha256 = "13ndkf7vklw978a4gdl1yfvn8hch28429a0iam67sg4nrp5v261p";
2319 sha256 = "13ndkf7vklw978a4gdl1yfvn8hch28429a0iam67sg4nrp5v261p";
2313 };
2320 };
2314 meta = {
2321 meta = {
2315 license = [ pkgs.lib.licenses.mit ];
2322 license = [ pkgs.lib.licenses.mit ];
2316 };
2323 };
2317 };
2324 };
2318 "zope.cachedescriptors" = super.buildPythonPackage {
2325 "zope.cachedescriptors" = super.buildPythonPackage {
2319 name = "zope.cachedescriptors-4.3.1";
2326 name = "zope.cachedescriptors-4.3.1";
2320 doCheck = false;
2327 doCheck = false;
2321 propagatedBuildInputs = [
2328 propagatedBuildInputs = [
2322 self."setuptools"
2329 self."setuptools"
2323 ];
2330 ];
2324 src = fetchurl {
2331 src = fetchurl {
2325 url = "https://files.pythonhosted.org/packages/2f/89/ebe1890cc6d3291ebc935558fa764d5fffe571018dbbee200e9db78762cb/zope.cachedescriptors-4.3.1.tar.gz";
2332 url = "https://files.pythonhosted.org/packages/2f/89/ebe1890cc6d3291ebc935558fa764d5fffe571018dbbee200e9db78762cb/zope.cachedescriptors-4.3.1.tar.gz";
2326 sha256 = "0jhr3m5p74c6r7k8iv0005b8bfsialih9d7zl5vx38rf5xq1lk8z";
2333 sha256 = "0jhr3m5p74c6r7k8iv0005b8bfsialih9d7zl5vx38rf5xq1lk8z";
2327 };
2334 };
2328 meta = {
2335 meta = {
2329 license = [ pkgs.lib.licenses.zpl21 ];
2336 license = [ pkgs.lib.licenses.zpl21 ];
2330 };
2337 };
2331 };
2338 };
2332 "zope.deprecation" = super.buildPythonPackage {
2339 "zope.deprecation" = super.buildPythonPackage {
2333 name = "zope.deprecation-4.4.0";
2340 name = "zope.deprecation-4.4.0";
2334 doCheck = false;
2341 doCheck = false;
2335 propagatedBuildInputs = [
2342 propagatedBuildInputs = [
2336 self."setuptools"
2343 self."setuptools"
2337 ];
2344 ];
2338 src = fetchurl {
2345 src = fetchurl {
2339 url = "https://files.pythonhosted.org/packages/34/da/46e92d32d545dd067b9436279d84c339e8b16de2ca393d7b892bc1e1e9fd/zope.deprecation-4.4.0.tar.gz";
2346 url = "https://files.pythonhosted.org/packages/34/da/46e92d32d545dd067b9436279d84c339e8b16de2ca393d7b892bc1e1e9fd/zope.deprecation-4.4.0.tar.gz";
2340 sha256 = "1pz2cv7gv9y1r3m0bdv7ks1alagmrn5msm5spwdzkb2by0w36i8d";
2347 sha256 = "1pz2cv7gv9y1r3m0bdv7ks1alagmrn5msm5spwdzkb2by0w36i8d";
2341 };
2348 };
2342 meta = {
2349 meta = {
2343 license = [ pkgs.lib.licenses.zpl21 ];
2350 license = [ pkgs.lib.licenses.zpl21 ];
2344 };
2351 };
2345 };
2352 };
2346 "zope.event" = super.buildPythonPackage {
2353 "zope.event" = super.buildPythonPackage {
2347 name = "zope.event-4.4";
2354 name = "zope.event-4.4";
2348 doCheck = false;
2355 doCheck = false;
2349 propagatedBuildInputs = [
2356 propagatedBuildInputs = [
2350 self."setuptools"
2357 self."setuptools"
2351 ];
2358 ];
2352 src = fetchurl {
2359 src = fetchurl {
2353 url = "https://files.pythonhosted.org/packages/4c/b2/51c0369adcf5be2334280eed230192ab3b03f81f8efda9ddea6f65cc7b32/zope.event-4.4.tar.gz";
2360 url = "https://files.pythonhosted.org/packages/4c/b2/51c0369adcf5be2334280eed230192ab3b03f81f8efda9ddea6f65cc7b32/zope.event-4.4.tar.gz";
2354 sha256 = "1ksbc726av9xacml6jhcfyn828hlhb9xlddpx6fcvnlvmpmpvhk9";
2361 sha256 = "1ksbc726av9xacml6jhcfyn828hlhb9xlddpx6fcvnlvmpmpvhk9";
2355 };
2362 };
2356 meta = {
2363 meta = {
2357 license = [ pkgs.lib.licenses.zpl21 ];
2364 license = [ pkgs.lib.licenses.zpl21 ];
2358 };
2365 };
2359 };
2366 };
2360 "zope.interface" = super.buildPythonPackage {
2367 "zope.interface" = super.buildPythonPackage {
2361 name = "zope.interface-4.6.0";
2368 name = "zope.interface-4.6.0";
2362 doCheck = false;
2369 doCheck = false;
2363 propagatedBuildInputs = [
2370 propagatedBuildInputs = [
2364 self."setuptools"
2371 self."setuptools"
2365 ];
2372 ];
2366 src = fetchurl {
2373 src = fetchurl {
2367 url = "https://files.pythonhosted.org/packages/4e/d0/c9d16bd5b38de44a20c6dc5d5ed80a49626fafcb3db9f9efdc2a19026db6/zope.interface-4.6.0.tar.gz";
2374 url = "https://files.pythonhosted.org/packages/4e/d0/c9d16bd5b38de44a20c6dc5d5ed80a49626fafcb3db9f9efdc2a19026db6/zope.interface-4.6.0.tar.gz";
2368 sha256 = "1rgh2x3rcl9r0v0499kf78xy86rnmanajf4ywmqb943wpk50sg8v";
2375 sha256 = "1rgh2x3rcl9r0v0499kf78xy86rnmanajf4ywmqb943wpk50sg8v";
2369 };
2376 };
2370 meta = {
2377 meta = {
2371 license = [ pkgs.lib.licenses.zpl21 ];
2378 license = [ pkgs.lib.licenses.zpl21 ];
2372 };
2379 };
2373 };
2380 };
2374
2381
2375 ### Test requirements
2382 ### Test requirements
2376
2383
2377
2384
2378 }
2385 }
@@ -1,16 +1,19 b''
1 [pytest]
1 [pytest]
2 testpaths = rhodecode
2 testpaths = rhodecode
3 norecursedirs = rhodecode/public rhodecode/templates tests/scripts
3 norecursedirs = rhodecode/public rhodecode/templates tests/scripts
4 cache_dir = /tmp/.pytest_cache
4 cache_dir = /tmp/.pytest_cache
5
5
6 pyramid_config = rhodecode/tests/rhodecode.ini
6 pyramid_config = rhodecode/tests/rhodecode.ini
7 vcsserver_protocol = http
7 vcsserver_protocol = http
8 vcsserver_config_http = rhodecode/tests/vcsserver_http.ini
8 vcsserver_config_http = rhodecode/tests/vcsserver_http.ini
9
9
10 addopts =
10 addopts =
11 --pdbcls=IPython.terminal.debugger:TerminalPdb
11 --pdbcls=IPython.terminal.debugger:TerminalPdb
12 --strict-markers
12
13
13 markers =
14 markers =
14 vcs_operations: Mark tests depending on a running RhodeCode instance.
15 vcs_operations: Mark tests depending on a running RhodeCode instance.
15 xfail_backends: Mark tests as xfail for given backends.
16 xfail_backends: Mark tests as xfail for given backends.
16 skip_backends: Mark tests as skipped for given backends.
17 skip_backends: Mark tests as skipped for given backends.
18 backends: Mark backends
19 dbs: database markers for running tests for given DB
@@ -1,16 +1,16 b''
1 # test related requirements
1 # test related requirements
2 pytest==3.8.2
2 pytest==4.6.5
3 py==1.6.0
3 py==1.8.0
4 pytest-cov==2.6.0
4 pytest-cov==2.7.1
5 pytest-sugar==0.9.1
5 pytest-sugar==0.9.2
6 pytest-runner==4.2.0
6 pytest-runner==5.1.0
7 pytest-profiling==1.3.0
7 pytest-profiling==1.7.0
8 pytest-timeout==1.3.2
8 pytest-timeout==1.3.3
9 gprof2dot==2017.9.19
9 gprof2dot==2017.9.19
10
10
11 mock==1.0.1
11 mock==3.0.5
12 cov-core==1.15.0
12 cov-core==1.15.0
13 coverage==4.5.3
13 coverage==4.5.4
14
14
15 webtest==2.0.33
15 webtest==2.0.33
16 beautifulsoup4==4.6.3
16 beautifulsoup4==4.6.3
@@ -1,107 +1,110 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
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 Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import pytest
22 import pytest
23
23
24 from rhodecode.model.db import User, ChangesetComment
24 from rhodecode.model.db import User, ChangesetComment
25 from rhodecode.model.meta import Session
25 from rhodecode.model.meta import Session
26 from rhodecode.model.comment import CommentsModel
26 from rhodecode.model.comment import CommentsModel
27 from rhodecode.api.tests.utils import (
27 from rhodecode.api.tests.utils import (
28 build_data, api_call, assert_error, assert_call_ok)
28 build_data, api_call, assert_error, assert_call_ok)
29
29
30
30
31 @pytest.fixture()
31 @pytest.fixture()
32 def make_repo_comments_factory(request):
32 def make_repo_comments_factory(request):
33
33
34 def maker(repo):
34 class Make(object):
35 user = User.get_first_super_admin()
35
36 commit = repo.scm_instance()[0]
36 def make_comments(self, repo):
37 user = User.get_first_super_admin()
38 commit = repo.scm_instance()[0]
37
39
38 commit_id = commit.raw_id
40 commit_id = commit.raw_id
39 file_0 = commit.affected_files[0]
41 file_0 = commit.affected_files[0]
40 comments = []
42 comments = []
41
43
42 # general
44 # general
43 CommentsModel().create(
45 CommentsModel().create(
44 text='General Comment', repo=repo, user=user, commit_id=commit_id,
46 text='General Comment', repo=repo, user=user, commit_id=commit_id,
45 comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False)
47 comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False)
46
48
47 # inline
49 # inline
48 CommentsModel().create(
50 CommentsModel().create(
49 text='Inline Comment', repo=repo, user=user, commit_id=commit_id,
51 text='Inline Comment', repo=repo, user=user, commit_id=commit_id,
50 f_path=file_0, line_no='n1',
52 f_path=file_0, line_no='n1',
51 comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False)
53 comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False)
52
54
53 # todo
55 # todo
54 CommentsModel().create(
56 CommentsModel().create(
55 text='INLINE TODO Comment', repo=repo, user=user, commit_id=commit_id,
57 text='INLINE TODO Comment', repo=repo, user=user, commit_id=commit_id,
56 f_path=file_0, line_no='n1',
58 f_path=file_0, line_no='n1',
57 comment_type=ChangesetComment.COMMENT_TYPE_TODO, send_email=False)
59 comment_type=ChangesetComment.COMMENT_TYPE_TODO, send_email=False)
58
60
59 @request.addfinalizer
61 @request.addfinalizer
60 def cleanup():
62 def cleanup():
61 for comment in comments:
63 for comment in comments:
62 Session().delete(comment)
64 Session().delete(comment)
63 return maker
65 return Make()
64
66
65
67
66 @pytest.mark.usefixtures("testuser_api", "app")
68 @pytest.mark.usefixtures("testuser_api", "app")
67 class TestGetRepo(object):
69 class TestGetRepo(object):
68
70
69 @pytest.mark.parametrize('filters, expected_count', [
71 @pytest.mark.parametrize('filters, expected_count', [
70 ({}, 3),
72 ({}, 3),
71 ({'comment_type': ChangesetComment.COMMENT_TYPE_NOTE}, 2),
73 ({'comment_type': ChangesetComment.COMMENT_TYPE_NOTE}, 2),
72 ({'comment_type': ChangesetComment.COMMENT_TYPE_TODO}, 1),
74 ({'comment_type': ChangesetComment.COMMENT_TYPE_TODO}, 1),
73 ({'commit_id': 'FILLED DYNAMIC'}, 3),
75 ({'commit_id': 'FILLED DYNAMIC'}, 3),
74 ])
76 ])
75 def test_api_get_repo_comments(self, backend, user_util,
77 def test_api_get_repo_comments(self, backend, user_util,
76 make_repo_comments_factory, filters, expected_count):
78 make_repo_comments_factory, filters, expected_count):
77 commits = [{'message': 'A'}, {'message': 'B'}]
79 commits = [{'message': 'A'}, {'message': 'B'}]
78 repo = backend.create_repo(commits=commits)
80 repo = backend.create_repo(commits=commits)
79 make_repo_comments_factory(repo)
81 make_repo_comments_factory.make_comments(repo)
80
82
81 api_call_params = {'repoid': repo.repo_name,}
83 api_call_params = {'repoid': repo.repo_name,}
82 api_call_params.update(filters)
84 api_call_params.update(filters)
83
85
84 if 'commit_id' in api_call_params:
86 if 'commit_id' in api_call_params:
85 commit = repo.scm_instance()[0]
87 commit = repo.scm_instance()[0]
86 commit_id = commit.raw_id
88 commit_id = commit.raw_id
87 api_call_params['commit_id'] = commit_id
89 api_call_params['commit_id'] = commit_id
88
90
89 id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params)
91 id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params)
90 response = api_call(self.app, params)
92 response = api_call(self.app, params)
91 result = assert_call_ok(id_, given=response.body)
93 result = assert_call_ok(id_, given=response.body)
92
94
93 assert len(result) == expected_count
95 assert len(result) == expected_count
94
96
95 def test_api_get_repo_comments_wrong_comment_typ(self, backend_hg):
97 def test_api_get_repo_comments_wrong_comment_type(
98 self, make_repo_comments_factory, backend_hg):
99 commits = [{'message': 'A'}, {'message': 'B'}]
100 repo = backend_hg.create_repo(commits=commits)
101 make_repo_comments_factory.make_comments(repo)
96
102
97 repo = backend_hg.create_repo()
103 api_call_params = {'repoid': repo.repo_name}
98 make_repo_comments_factory(repo)
99
100 api_call_params = {'repoid': repo.repo_name,}
101 api_call_params.update({'comment_type': 'bogus'})
104 api_call_params.update({'comment_type': 'bogus'})
102
105
103 expected = 'comment_type must be one of `{}` got {}'.format(
106 expected = 'comment_type must be one of `{}` got {}'.format(
104 ChangesetComment.COMMENT_TYPES, 'bogus')
107 ChangesetComment.COMMENT_TYPES, 'bogus')
105 id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params)
108 id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params)
106 response = api_call(self.app, params)
109 response = api_call(self.app, params)
107 assert_error(id_, expected, given=response.body)
110 assert_error(id_, expected, given=response.body)
@@ -1,292 +1,293 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
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 Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 from subprocess32 import Popen, PIPE
21 from subprocess32 import Popen, PIPE
22 import os
22 import os
23 import shutil
23 import shutil
24 import sys
24 import sys
25 import tempfile
25 import tempfile
26
26
27 import pytest
27 import pytest
28 from sqlalchemy.engine import url
28 from sqlalchemy.engine import url
29
29
30 from rhodecode.tests.fixture import TestINI
30 from rhodecode.tests.fixture import TestINI
31
31
32
32
33 def _get_dbs_from_metafunc(metafunc):
33 def _get_dbs_from_metafunc(metafunc):
34 if hasattr(metafunc.function, 'dbs'):
34 dbs_mark = metafunc.definition.get_closest_marker('dbs')
35 # Supported backends by this test function, created from
35
36 # pytest.mark.dbs
36 if dbs_mark:
37 backends = metafunc.definition.get_closest_marker('dbs').args
37 # Supported backends by this test function, created from pytest.mark.dbs
38 backends = dbs_mark.args
38 else:
39 else:
39 backends = metafunc.config.getoption('--dbs')
40 backends = metafunc.config.getoption('--dbs')
40 return backends
41 return backends
41
42
42
43
43 def pytest_generate_tests(metafunc):
44 def pytest_generate_tests(metafunc):
44 # Support test generation based on --dbs parameter
45 # Support test generation based on --dbs parameter
45 if 'db_backend' in metafunc.fixturenames:
46 if 'db_backend' in metafunc.fixturenames:
46 requested_backends = set(metafunc.config.getoption('--dbs'))
47 requested_backends = set(metafunc.config.getoption('--dbs'))
47 backends = _get_dbs_from_metafunc(metafunc)
48 backends = _get_dbs_from_metafunc(metafunc)
48 backends = requested_backends.intersection(backends)
49 backends = requested_backends.intersection(backends)
49 # TODO: johbo: Disabling a backend did not work out with
50 # TODO: johbo: Disabling a backend did not work out with
50 # parametrization, find better way to achieve this.
51 # parametrization, find better way to achieve this.
51 if not backends:
52 if not backends:
52 metafunc.function._skip = True
53 metafunc.function._skip = True
53 metafunc.parametrize('db_backend_name', backends)
54 metafunc.parametrize('db_backend_name', backends)
54
55
55
56
56 def pytest_collection_modifyitems(session, config, items):
57 def pytest_collection_modifyitems(session, config, items):
57 remaining = [
58 remaining = [
58 i for i in items if not getattr(i.obj, '_skip', False)]
59 i for i in items if not getattr(i.obj, '_skip', False)]
59 items[:] = remaining
60 items[:] = remaining
60
61
61
62
62 @pytest.fixture()
63 @pytest.fixture()
63 def db_backend(
64 def db_backend(
64 request, db_backend_name, ini_config, tmpdir_factory):
65 request, db_backend_name, ini_config, tmpdir_factory):
65 basetemp = tmpdir_factory.getbasetemp().strpath
66 basetemp = tmpdir_factory.getbasetemp().strpath
66 klass = _get_backend(db_backend_name)
67 klass = _get_backend(db_backend_name)
67
68
68 option_name = '--{}-connection-string'.format(db_backend_name)
69 option_name = '--{}-connection-string'.format(db_backend_name)
69 connection_string = request.config.getoption(option_name) or None
70 connection_string = request.config.getoption(option_name) or None
70
71
71 return klass(
72 return klass(
72 config_file=ini_config, basetemp=basetemp,
73 config_file=ini_config, basetemp=basetemp,
73 connection_string=connection_string)
74 connection_string=connection_string)
74
75
75
76
76 def _get_backend(backend_type):
77 def _get_backend(backend_type):
77 return {
78 return {
78 'sqlite': SQLiteDBBackend,
79 'sqlite': SQLiteDBBackend,
79 'postgres': PostgresDBBackend,
80 'postgres': PostgresDBBackend,
80 'mysql': MySQLDBBackend,
81 'mysql': MySQLDBBackend,
81 '': EmptyDBBackend
82 '': EmptyDBBackend
82 }[backend_type]
83 }[backend_type]
83
84
84
85
85 class DBBackend(object):
86 class DBBackend(object):
86 _store = os.path.dirname(os.path.abspath(__file__))
87 _store = os.path.dirname(os.path.abspath(__file__))
87 _type = None
88 _type = None
88 _base_ini_config = [{'app:main': {'vcs.start_server': 'false',
89 _base_ini_config = [{'app:main': {'vcs.start_server': 'false',
89 'startup.import_repos': 'false',
90 'startup.import_repos': 'false',
90 'is_test': 'False'}}]
91 'is_test': 'False'}}]
91 _db_url = [{'app:main': {'sqlalchemy.db1.url': ''}}]
92 _db_url = [{'app:main': {'sqlalchemy.db1.url': ''}}]
92 _base_db_name = 'rhodecode_test_db_backend'
93 _base_db_name = 'rhodecode_test_db_backend'
93
94
94 def __init__(
95 def __init__(
95 self, config_file, db_name=None, basetemp=None,
96 self, config_file, db_name=None, basetemp=None,
96 connection_string=None):
97 connection_string=None):
97
98
98 from rhodecode.lib.vcs.backends.hg import largefiles_store
99 from rhodecode.lib.vcs.backends.hg import largefiles_store
99 from rhodecode.lib.vcs.backends.git import lfs_store
100 from rhodecode.lib.vcs.backends.git import lfs_store
100
101
101 self.fixture_store = os.path.join(self._store, self._type)
102 self.fixture_store = os.path.join(self._store, self._type)
102 self.db_name = db_name or self._base_db_name
103 self.db_name = db_name or self._base_db_name
103 self._base_ini_file = config_file
104 self._base_ini_file = config_file
104 self.stderr = ''
105 self.stderr = ''
105 self.stdout = ''
106 self.stdout = ''
106 self._basetemp = basetemp or tempfile.gettempdir()
107 self._basetemp = basetemp or tempfile.gettempdir()
107 self._repos_location = os.path.join(self._basetemp, 'rc_test_repos')
108 self._repos_location = os.path.join(self._basetemp, 'rc_test_repos')
108 self._repos_hg_largefiles_store = largefiles_store(self._basetemp)
109 self._repos_hg_largefiles_store = largefiles_store(self._basetemp)
109 self._repos_git_lfs_store = lfs_store(self._basetemp)
110 self._repos_git_lfs_store = lfs_store(self._basetemp)
110 self.connection_string = connection_string
111 self.connection_string = connection_string
111
112
112 @property
113 @property
113 def connection_string(self):
114 def connection_string(self):
114 return self._connection_string
115 return self._connection_string
115
116
116 @connection_string.setter
117 @connection_string.setter
117 def connection_string(self, new_connection_string):
118 def connection_string(self, new_connection_string):
118 if not new_connection_string:
119 if not new_connection_string:
119 new_connection_string = self.get_default_connection_string()
120 new_connection_string = self.get_default_connection_string()
120 else:
121 else:
121 new_connection_string = new_connection_string.format(
122 new_connection_string = new_connection_string.format(
122 db_name=self.db_name)
123 db_name=self.db_name)
123 url_parts = url.make_url(new_connection_string)
124 url_parts = url.make_url(new_connection_string)
124 self._connection_string = new_connection_string
125 self._connection_string = new_connection_string
125 self.user = url_parts.username
126 self.user = url_parts.username
126 self.password = url_parts.password
127 self.password = url_parts.password
127 self.host = url_parts.host
128 self.host = url_parts.host
128
129
129 def get_default_connection_string(self):
130 def get_default_connection_string(self):
130 raise NotImplementedError('default connection_string is required.')
131 raise NotImplementedError('default connection_string is required.')
131
132
132 def execute(self, cmd, env=None, *args):
133 def execute(self, cmd, env=None, *args):
133 """
134 """
134 Runs command on the system with given ``args``.
135 Runs command on the system with given ``args``.
135 """
136 """
136
137
137 command = cmd + ' ' + ' '.join(args)
138 command = cmd + ' ' + ' '.join(args)
138 sys.stdout.write(command)
139 sys.stdout.write(command)
139
140
140 # Tell Python to use UTF-8 encoding out stdout
141 # Tell Python to use UTF-8 encoding out stdout
141 _env = os.environ.copy()
142 _env = os.environ.copy()
142 _env['PYTHONIOENCODING'] = 'UTF-8'
143 _env['PYTHONIOENCODING'] = 'UTF-8'
143 if env:
144 if env:
144 _env.update(env)
145 _env.update(env)
145 self.p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, env=_env)
146 self.p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, env=_env)
146 self.stdout, self.stderr = self.p.communicate()
147 self.stdout, self.stderr = self.p.communicate()
147 sys.stdout.write('COMMAND:'+command+'\n')
148 sys.stdout.write('COMMAND:'+command+'\n')
148 sys.stdout.write(self.stdout)
149 sys.stdout.write(self.stdout)
149 return self.stdout, self.stderr
150 return self.stdout, self.stderr
150
151
151 def assert_returncode_success(self):
152 def assert_returncode_success(self):
152 if not self.p.returncode == 0:
153 if not self.p.returncode == 0:
153 print(self.stderr)
154 print(self.stderr)
154 raise AssertionError('non 0 retcode:{}'.format(self.p.returncode))
155 raise AssertionError('non 0 retcode:{}'.format(self.p.returncode))
155
156
156 def assert_correct_output(self, stdout, version):
157 def assert_correct_output(self, stdout, version):
157 assert 'UPGRADE FOR STEP {} COMPLETED'.format(version) in stdout
158 assert 'UPGRADE FOR STEP {} COMPLETED'.format(version) in stdout
158
159
159 def setup_rhodecode_db(self, ini_params=None, env=None):
160 def setup_rhodecode_db(self, ini_params=None, env=None):
160 if not ini_params:
161 if not ini_params:
161 ini_params = self._base_ini_config
162 ini_params = self._base_ini_config
162
163
163 ini_params.extend(self._db_url)
164 ini_params.extend(self._db_url)
164 with TestINI(self._base_ini_file, ini_params,
165 with TestINI(self._base_ini_file, ini_params,
165 self._type, destroy=True) as _ini_file:
166 self._type, destroy=True) as _ini_file:
166
167
167 if not os.path.isdir(self._repos_location):
168 if not os.path.isdir(self._repos_location):
168 os.makedirs(self._repos_location)
169 os.makedirs(self._repos_location)
169 if not os.path.isdir(self._repos_hg_largefiles_store):
170 if not os.path.isdir(self._repos_hg_largefiles_store):
170 os.makedirs(self._repos_hg_largefiles_store)
171 os.makedirs(self._repos_hg_largefiles_store)
171 if not os.path.isdir(self._repos_git_lfs_store):
172 if not os.path.isdir(self._repos_git_lfs_store):
172 os.makedirs(self._repos_git_lfs_store)
173 os.makedirs(self._repos_git_lfs_store)
173
174
174 return self.execute(
175 return self.execute(
175 "rc-setup-app {0} --user=marcink "
176 "rc-setup-app {0} --user=marcink "
176 "--email=marcin@rhodeocode.com --password={1} "
177 "--email=marcin@rhodeocode.com --password={1} "
177 "--repos={2} --force-yes".format(
178 "--repos={2} --force-yes".format(
178 _ini_file, 'qweqwe', self._repos_location), env=env)
179 _ini_file, 'qweqwe', self._repos_location), env=env)
179
180
180 def upgrade_database(self, ini_params=None):
181 def upgrade_database(self, ini_params=None):
181 if not ini_params:
182 if not ini_params:
182 ini_params = self._base_ini_config
183 ini_params = self._base_ini_config
183 ini_params.extend(self._db_url)
184 ini_params.extend(self._db_url)
184
185
185 test_ini = TestINI(
186 test_ini = TestINI(
186 self._base_ini_file, ini_params, self._type, destroy=True)
187 self._base_ini_file, ini_params, self._type, destroy=True)
187 with test_ini as ini_file:
188 with test_ini as ini_file:
188 if not os.path.isdir(self._repos_location):
189 if not os.path.isdir(self._repos_location):
189 os.makedirs(self._repos_location)
190 os.makedirs(self._repos_location)
190
191
191 return self.execute(
192 return self.execute(
192 "rc-upgrade-db {0} --force-yes".format(ini_file))
193 "rc-upgrade-db {0} --force-yes".format(ini_file))
193
194
194 def setup_db(self):
195 def setup_db(self):
195 raise NotImplementedError
196 raise NotImplementedError
196
197
197 def teardown_db(self):
198 def teardown_db(self):
198 raise NotImplementedError
199 raise NotImplementedError
199
200
200 def import_dump(self, dumpname):
201 def import_dump(self, dumpname):
201 raise NotImplementedError
202 raise NotImplementedError
202
203
203
204
204 class EmptyDBBackend(DBBackend):
205 class EmptyDBBackend(DBBackend):
205 _type = ''
206 _type = ''
206
207
207 def setup_db(self):
208 def setup_db(self):
208 pass
209 pass
209
210
210 def teardown_db(self):
211 def teardown_db(self):
211 pass
212 pass
212
213
213 def import_dump(self, dumpname):
214 def import_dump(self, dumpname):
214 pass
215 pass
215
216
216 def assert_returncode_success(self):
217 def assert_returncode_success(self):
217 assert True
218 assert True
218
219
219
220
220 class SQLiteDBBackend(DBBackend):
221 class SQLiteDBBackend(DBBackend):
221 _type = 'sqlite'
222 _type = 'sqlite'
222
223
223 def get_default_connection_string(self):
224 def get_default_connection_string(self):
224 return 'sqlite:///{}/{}.sqlite'.format(self._basetemp, self.db_name)
225 return 'sqlite:///{}/{}.sqlite'.format(self._basetemp, self.db_name)
225
226
226 def setup_db(self):
227 def setup_db(self):
227 # dump schema for tests
228 # dump schema for tests
228 # cp -v $TEST_DB_NAME
229 # cp -v $TEST_DB_NAME
229 self._db_url = [{'app:main': {
230 self._db_url = [{'app:main': {
230 'sqlalchemy.db1.url': self.connection_string}}]
231 'sqlalchemy.db1.url': self.connection_string}}]
231
232
232 def import_dump(self, dumpname):
233 def import_dump(self, dumpname):
233 dump = os.path.join(self.fixture_store, dumpname)
234 dump = os.path.join(self.fixture_store, dumpname)
234 target = os.path.join(self._basetemp, '{0.db_name}.sqlite'.format(self))
235 target = os.path.join(self._basetemp, '{0.db_name}.sqlite'.format(self))
235 return self.execute('cp -v {} {}'.format(dump, target))
236 return self.execute('cp -v {} {}'.format(dump, target))
236
237
237 def teardown_db(self):
238 def teardown_db(self):
238 return self.execute("rm -rf {}.sqlite".format(
239 return self.execute("rm -rf {}.sqlite".format(
239 os.path.join(self._basetemp, self.db_name)))
240 os.path.join(self._basetemp, self.db_name)))
240
241
241
242
242 class MySQLDBBackend(DBBackend):
243 class MySQLDBBackend(DBBackend):
243 _type = 'mysql'
244 _type = 'mysql'
244
245
245 def get_default_connection_string(self):
246 def get_default_connection_string(self):
246 return 'mysql://root:qweqwe@127.0.0.1/{}'.format(self.db_name)
247 return 'mysql://root:qweqwe@127.0.0.1/{}'.format(self.db_name)
247
248
248 def setup_db(self):
249 def setup_db(self):
249 # dump schema for tests
250 # dump schema for tests
250 # mysqldump -uroot -pqweqwe $TEST_DB_NAME
251 # mysqldump -uroot -pqweqwe $TEST_DB_NAME
251 self._db_url = [{'app:main': {
252 self._db_url = [{'app:main': {
252 'sqlalchemy.db1.url': self.connection_string}}]
253 'sqlalchemy.db1.url': self.connection_string}}]
253 return self.execute("mysql -v -u{} -p{} -e 'create database '{}';'".format(
254 return self.execute("mysql -v -u{} -p{} -e 'create database '{}';'".format(
254 self.user, self.password, self.db_name))
255 self.user, self.password, self.db_name))
255
256
256 def import_dump(self, dumpname):
257 def import_dump(self, dumpname):
257 dump = os.path.join(self.fixture_store, dumpname)
258 dump = os.path.join(self.fixture_store, dumpname)
258 return self.execute("mysql -u{} -p{} {} < {}".format(
259 return self.execute("mysql -u{} -p{} {} < {}".format(
259 self.user, self.password, self.db_name, dump))
260 self.user, self.password, self.db_name, dump))
260
261
261 def teardown_db(self):
262 def teardown_db(self):
262 return self.execute("mysql -v -u{} -p{} -e 'drop database '{}';'".format(
263 return self.execute("mysql -v -u{} -p{} -e 'drop database '{}';'".format(
263 self.user, self.password, self.db_name))
264 self.user, self.password, self.db_name))
264
265
265
266
266 class PostgresDBBackend(DBBackend):
267 class PostgresDBBackend(DBBackend):
267 _type = 'postgres'
268 _type = 'postgres'
268
269
269 def get_default_connection_string(self):
270 def get_default_connection_string(self):
270 return 'postgresql://postgres:qweqwe@localhost/{}'.format(self.db_name)
271 return 'postgresql://postgres:qweqwe@localhost/{}'.format(self.db_name)
271
272
272 def setup_db(self):
273 def setup_db(self):
273 # dump schema for tests
274 # dump schema for tests
274 # pg_dump -U postgres -h localhost $TEST_DB_NAME
275 # pg_dump -U postgres -h localhost $TEST_DB_NAME
275 self._db_url = [{'app:main': {
276 self._db_url = [{'app:main': {
276 'sqlalchemy.db1.url':
277 'sqlalchemy.db1.url':
277 self.connection_string}}]
278 self.connection_string}}]
278 return self.execute("PGPASSWORD={} psql -U {} -h localhost "
279 return self.execute("PGPASSWORD={} psql -U {} -h localhost "
279 "-c 'create database '{}';'".format(
280 "-c 'create database '{}';'".format(
280 self.password, self.user, self.db_name))
281 self.password, self.user, self.db_name))
281
282
282 def teardown_db(self):
283 def teardown_db(self):
283 return self.execute("PGPASSWORD={} psql -U {} -h localhost "
284 return self.execute("PGPASSWORD={} psql -U {} -h localhost "
284 "-c 'drop database if exists '{}';'".format(
285 "-c 'drop database if exists '{}';'".format(
285 self.password, self.user, self.db_name))
286 self.password, self.user, self.db_name))
286
287
287 def import_dump(self, dumpname):
288 def import_dump(self, dumpname):
288 dump = os.path.join(self.fixture_store, dumpname)
289 dump = os.path.join(self.fixture_store, dumpname)
289 return self.execute(
290 return self.execute(
290 "PGPASSWORD={} psql -U {} -h localhost -d {} -1 "
291 "PGPASSWORD={} psql -U {} -h localhost -d {} -1 "
291 "-f {}".format(
292 "-f {}".format(
292 self.password, self.user, self.db_name, dump))
293 self.password, self.user, self.db_name, dump))
@@ -1,195 +1,189 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
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 Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
22 import stat
23 import sys
24
25 import pytest
21 import pytest
26 from mock import Mock, patch, DEFAULT
22 from mock import Mock, patch, DEFAULT
27
23
28 import rhodecode
24 import rhodecode
29 from rhodecode.model import db, scm
25 from rhodecode.model import db, scm
30 from rhodecode.tests import no_newline_id_generator
31
26
32
27
33 def test_scm_instance_config(backend):
28 def test_scm_instance_config(backend):
34 repo = backend.create_repo()
29 repo = backend.create_repo()
35 with patch.multiple('rhodecode.model.db.Repository',
30 with patch.multiple('rhodecode.model.db.Repository',
36 _get_instance=DEFAULT,
31 _get_instance=DEFAULT,
37 _get_instance_cached=DEFAULT) as mocks:
32 _get_instance_cached=DEFAULT) as mocks:
33
38 repo.scm_instance()
34 repo.scm_instance()
39 mocks['_get_instance'].assert_called_with(
35 mocks['_get_instance'].assert_called_with(
40 config=None, cache=False)
36 config=None, cache=False)
41
37
42 config = {'some': 'value'}
38 repo.scm_instance(vcs_full_cache=False)
43 repo.scm_instance(config=config)
44 mocks['_get_instance'].assert_called_with(
39 mocks['_get_instance'].assert_called_with(
45 config=config, cache=False)
40 config=None, cache=False)
46
41
47 with patch.dict(rhodecode.CONFIG, {'vcs_full_cache': 'true'}):
42 repo.scm_instance(vcs_full_cache=True)
48 repo.scm_instance(config=config)
43 mocks['_get_instance_cached'].assert_called()
49 mocks['_get_instance_cached'].assert_called()
50
44
51
45
52 def test_get_instance_config(backend):
46 def test_get_instance_config(backend):
53 repo = backend.create_repo()
47 repo = backend.create_repo()
54 vcs_class = Mock()
48 vcs_class = Mock()
55 with patch.multiple('rhodecode.lib.vcs.backends',
49 with patch.multiple('rhodecode.lib.vcs.backends',
56 get_scm=DEFAULT,
50 get_scm=DEFAULT,
57 get_backend=DEFAULT) as mocks:
51 get_backend=DEFAULT) as mocks:
58 mocks['get_scm'].return_value = backend.alias
52 mocks['get_scm'].return_value = backend.alias
59 mocks['get_backend'].return_value = vcs_class
53 mocks['get_backend'].return_value = vcs_class
60 with patch('rhodecode.model.db.Repository._config') as config_mock:
54 with patch('rhodecode.model.db.Repository._config') as config_mock:
61 repo._get_instance()
55 repo._get_instance()
62 vcs_class.assert_called_with(
56 vcs_class.assert_called_with(
63 repo_path=repo.repo_full_path, config=config_mock,
57 repo_path=repo.repo_full_path, config=config_mock,
64 create=False, with_wire={'cache': True, 'repo_state_uid': None})
58 create=False, with_wire={'cache': True, 'repo_state_uid': None})
65
59
66 new_config = {'override': 'old_config'}
60 new_config = {'override': 'old_config'}
67 repo._get_instance(config=new_config)
61 repo._get_instance(config=new_config)
68 vcs_class.assert_called_with(
62 vcs_class.assert_called_with(
69 repo_path=repo.repo_full_path, config=new_config, create=False,
63 repo_path=repo.repo_full_path, config=new_config, create=False,
70 with_wire={'cache': True, 'repo_state_uid': None})
64 with_wire={'cache': True, 'repo_state_uid': None})
71
65
72
66
73 def test_mark_for_invalidation_config(backend):
67 def test_mark_for_invalidation_config(backend):
74 repo = backend.create_repo()
68 repo = backend.create_repo()
75 with patch('rhodecode.model.db.Repository.update_commit_cache') as _mock:
69 with patch('rhodecode.model.db.Repository.update_commit_cache') as _mock:
76 scm.ScmModel().mark_for_invalidation(repo.repo_name)
70 scm.ScmModel().mark_for_invalidation(repo.repo_name)
77 _, kwargs = _mock.call_args
71 _, kwargs = _mock.call_args
78 assert kwargs['config'].__dict__ == repo._config.__dict__
72 assert kwargs['config'].__dict__ == repo._config.__dict__
79
73
80
74
81 def test_mark_for_invalidation_with_delete_updates_last_commit(backend):
75 def test_mark_for_invalidation_with_delete_updates_last_commit(backend):
82 commits = [{'message': 'A'}, {'message': 'B'}]
76 commits = [{'message': 'A'}, {'message': 'B'}]
83 repo = backend.create_repo(commits=commits)
77 repo = backend.create_repo(commits=commits)
84 scm.ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
78 scm.ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
85 assert repo.changeset_cache['revision'] == 1
79 assert repo.changeset_cache['revision'] == 1
86
80
87
81
88 def test_mark_for_invalidation_with_delete_updates_last_commit_empty(backend):
82 def test_mark_for_invalidation_with_delete_updates_last_commit_empty(backend):
89 repo = backend.create_repo()
83 repo = backend.create_repo()
90 scm.ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
84 scm.ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
91 assert repo.changeset_cache['revision'] == -1
85 assert repo.changeset_cache['revision'] == -1
92
86
93
87
94 def test_strip_with_multiple_heads(backend_hg):
88 def test_strip_with_multiple_heads(backend_hg):
95 commits = [
89 commits = [
96 {'message': 'A'},
90 {'message': 'A'},
97 {'message': 'a'},
91 {'message': 'a'},
98 {'message': 'b'},
92 {'message': 'b'},
99 {'message': 'B', 'parents': ['A']},
93 {'message': 'B', 'parents': ['A']},
100 {'message': 'a1'},
94 {'message': 'a1'},
101 ]
95 ]
102 repo = backend_hg.create_repo(commits=commits)
96 repo = backend_hg.create_repo(commits=commits)
103 commit_ids = backend_hg.commit_ids
97 commit_ids = backend_hg.commit_ids
104
98
105 model = scm.ScmModel()
99 model = scm.ScmModel()
106 model.strip(repo, commit_ids['b'], branch=None)
100 model.strip(repo, commit_ids['b'], branch=None)
107
101
108 vcs_repo = repo.scm_instance()
102 vcs_repo = repo.scm_instance()
109 rest_commit_ids = [c.raw_id for c in vcs_repo.get_commits()]
103 rest_commit_ids = [c.raw_id for c in vcs_repo.get_commits()]
110 assert len(rest_commit_ids) == 4
104 assert len(rest_commit_ids) == 4
111 assert commit_ids['b'] not in rest_commit_ids
105 assert commit_ids['b'] not in rest_commit_ids
112
106
113
107
114 def test_strip_with_single_heads(backend_hg):
108 def test_strip_with_single_heads(backend_hg):
115 commits = [
109 commits = [
116 {'message': 'A'},
110 {'message': 'A'},
117 {'message': 'a'},
111 {'message': 'a'},
118 {'message': 'b'},
112 {'message': 'b'},
119 ]
113 ]
120 repo = backend_hg.create_repo(commits=commits)
114 repo = backend_hg.create_repo(commits=commits)
121 commit_ids = backend_hg.commit_ids
115 commit_ids = backend_hg.commit_ids
122
116
123 model = scm.ScmModel()
117 model = scm.ScmModel()
124 model.strip(repo, commit_ids['b'], branch=None)
118 model.strip(repo, commit_ids['b'], branch=None)
125
119
126 vcs_repo = repo.scm_instance()
120 vcs_repo = repo.scm_instance()
127 rest_commit_ids = [c.raw_id for c in vcs_repo.get_commits()]
121 rest_commit_ids = [c.raw_id for c in vcs_repo.get_commits()]
128 assert len(rest_commit_ids) == 2
122 assert len(rest_commit_ids) == 2
129 assert commit_ids['b'] not in rest_commit_ids
123 assert commit_ids['b'] not in rest_commit_ids
130
124
131
125
132 def test_get_nodes_returns_unicode_flat(backend):
126 def test_get_nodes_returns_unicode_flat(backend):
133 repo = backend.repo
127 repo = backend.repo
134 commit_id = repo.get_commit(commit_idx=0).raw_id
128 commit_id = repo.get_commit(commit_idx=0).raw_id
135 directories, files = scm.ScmModel().get_nodes(repo.repo_name, commit_id, flat=True)
129 directories, files = scm.ScmModel().get_nodes(repo.repo_name, commit_id, flat=True)
136 assert_contains_only_unicode(directories)
130 assert_contains_only_unicode(directories)
137 assert_contains_only_unicode(files)
131 assert_contains_only_unicode(files)
138
132
139
133
140 def test_get_nodes_returns_unicode_non_flat(backend):
134 def test_get_nodes_returns_unicode_non_flat(backend):
141 repo = backend.repo
135 repo = backend.repo
142 commit_id = repo.get_commit(commit_idx=0).raw_id
136 commit_id = repo.get_commit(commit_idx=0).raw_id
143
137
144 directories, files = scm.ScmModel().get_nodes(repo.repo_name, commit_id, flat=False)
138 directories, files = scm.ScmModel().get_nodes(repo.repo_name, commit_id, flat=False)
145 # johbo: Checking only the names for now, since that is the critical
139 # johbo: Checking only the names for now, since that is the critical
146 # part.
140 # part.
147 assert_contains_only_unicode([d['name'] for d in directories])
141 assert_contains_only_unicode([d['name'] for d in directories])
148 assert_contains_only_unicode([f['name'] for f in files])
142 assert_contains_only_unicode([f['name'] for f in files])
149
143
150
144
151 def test_get_nodes_max_file_bytes(backend_random):
145 def test_get_nodes_max_file_bytes(backend_random):
152 repo = backend_random.repo
146 repo = backend_random.repo
153 max_file_bytes = 10
147 max_file_bytes = 10
154 directories, files = scm.ScmModel().get_nodes(
148 directories, files = scm.ScmModel().get_nodes(
155 repo.repo_name, repo.get_commit(commit_idx=0).raw_id, content=True,
149 repo.repo_name, repo.get_commit(commit_idx=0).raw_id, content=True,
156 extended_info=True, flat=False)
150 extended_info=True, flat=False)
157 assert any(file['content'] and len(file['content']) > max_file_bytes
151 assert any(file['content'] and len(file['content']) > max_file_bytes
158 for file in files)
152 for file in files)
159
153
160 directories, files = scm.ScmModel().get_nodes(
154 directories, files = scm.ScmModel().get_nodes(
161 repo.repo_name, repo.get_commit(commit_idx=0).raw_id, content=True,
155 repo.repo_name, repo.get_commit(commit_idx=0).raw_id, content=True,
162 extended_info=True, flat=False, max_file_bytes=max_file_bytes)
156 extended_info=True, flat=False, max_file_bytes=max_file_bytes)
163 assert all(
157 assert all(
164 file['content'] is None if file['size'] > max_file_bytes else True
158 file['content'] is None if file['size'] > max_file_bytes else True
165 for file in files)
159 for file in files)
166
160
167
161
168 def assert_contains_only_unicode(structure):
162 def assert_contains_only_unicode(structure):
169 assert structure
163 assert structure
170 for value in structure:
164 for value in structure:
171 assert isinstance(value, unicode)
165 assert isinstance(value, unicode)
172
166
173
167
174 @pytest.mark.backends("hg", "git")
168 @pytest.mark.backends("hg", "git")
175 def test_get_non_unicode_reference(backend):
169 def test_get_non_unicode_reference(backend):
176 model = scm.ScmModel()
170 model = scm.ScmModel()
177 non_unicode_list = ["AdΔ±nΔ±".decode("cp1254")]
171 non_unicode_list = ["AdΔ±nΔ±".decode("cp1254")]
178
172
179 def scm_instance():
173 def scm_instance():
180 return Mock(
174 return Mock(
181 branches=non_unicode_list, bookmarks=non_unicode_list,
175 branches=non_unicode_list, bookmarks=non_unicode_list,
182 tags=non_unicode_list, alias=backend.alias)
176 tags=non_unicode_list, alias=backend.alias)
183
177
184 repo = Mock(__class__=db.Repository, scm_instance=scm_instance)
178 repo = Mock(__class__=db.Repository, scm_instance=scm_instance)
185 choices, __ = model.get_repo_landing_revs(translator=lambda s: s, repo=repo)
179 choices, __ = model.get_repo_landing_revs(translator=lambda s: s, repo=repo)
186 if backend.alias == 'hg':
180 if backend.alias == 'hg':
187 valid_choices = [
181 valid_choices = [
188 'rev:tip', u'branch:Ad\xc4\xb1n\xc4\xb1',
182 'rev:tip', u'branch:Ad\xc4\xb1n\xc4\xb1',
189 u'book:Ad\xc4\xb1n\xc4\xb1', u'tag:Ad\xc4\xb1n\xc4\xb1']
183 u'book:Ad\xc4\xb1n\xc4\xb1', u'tag:Ad\xc4\xb1n\xc4\xb1']
190 else:
184 else:
191 valid_choices = [
185 valid_choices = [
192 'rev:tip', u'branch:Ad\xc4\xb1n\xc4\xb1',
186 'rev:tip', u'branch:Ad\xc4\xb1n\xc4\xb1',
193 u'tag:Ad\xc4\xb1n\xc4\xb1']
187 u'tag:Ad\xc4\xb1n\xc4\xb1']
194
188
195 assert choices == valid_choices
189 assert choices == valid_choices
@@ -1,1826 +1,1817 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
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 Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import collections
21 import collections
22 import datetime
22 import datetime
23 import hashlib
23 import hashlib
24 import os
24 import os
25 import re
25 import re
26 import pprint
26 import pprint
27 import shutil
27 import shutil
28 import socket
28 import socket
29 import subprocess32
29 import subprocess32
30 import time
30 import time
31 import uuid
31 import uuid
32 import dateutil.tz
32 import dateutil.tz
33 import functools
34
33
35 import mock
34 import mock
36 import pyramid.testing
35 import pyramid.testing
37 import pytest
36 import pytest
38 import colander
37 import colander
39 import requests
38 import requests
40 import pyramid.paster
39 import pyramid.paster
41
40
42 import rhodecode
41 import rhodecode
43 from rhodecode.lib.utils2 import AttributeDict
42 from rhodecode.lib.utils2 import AttributeDict
44 from rhodecode.model.changeset_status import ChangesetStatusModel
43 from rhodecode.model.changeset_status import ChangesetStatusModel
45 from rhodecode.model.comment import CommentsModel
44 from rhodecode.model.comment import CommentsModel
46 from rhodecode.model.db import (
45 from rhodecode.model.db import (
47 PullRequest, Repository, RhodeCodeSetting, ChangesetStatus, RepoGroup,
46 PullRequest, Repository, RhodeCodeSetting, ChangesetStatus, RepoGroup,
48 UserGroup, RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi)
47 UserGroup, RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi)
49 from rhodecode.model.meta import Session
48 from rhodecode.model.meta import Session
50 from rhodecode.model.pull_request import PullRequestModel
49 from rhodecode.model.pull_request import PullRequestModel
51 from rhodecode.model.repo import RepoModel
50 from rhodecode.model.repo import RepoModel
52 from rhodecode.model.repo_group import RepoGroupModel
51 from rhodecode.model.repo_group import RepoGroupModel
53 from rhodecode.model.user import UserModel
52 from rhodecode.model.user import UserModel
54 from rhodecode.model.settings import VcsSettingsModel
53 from rhodecode.model.settings import VcsSettingsModel
55 from rhodecode.model.user_group import UserGroupModel
54 from rhodecode.model.user_group import UserGroupModel
56 from rhodecode.model.integration import IntegrationModel
55 from rhodecode.model.integration import IntegrationModel
57 from rhodecode.integrations import integration_type_registry
56 from rhodecode.integrations import integration_type_registry
58 from rhodecode.integrations.types.base import IntegrationTypeBase
57 from rhodecode.integrations.types.base import IntegrationTypeBase
59 from rhodecode.lib.utils import repo2db_mapper
58 from rhodecode.lib.utils import repo2db_mapper
60 from rhodecode.lib.vcs.backends import get_backend
59 from rhodecode.lib.vcs.backends import get_backend
61 from rhodecode.lib.vcs.nodes import FileNode
60 from rhodecode.lib.vcs.nodes import FileNode
62 from rhodecode.tests import (
61 from rhodecode.tests import (
63 login_user_session, get_new_dir, utils, TESTS_TMP_PATH,
62 login_user_session, get_new_dir, utils, TESTS_TMP_PATH,
64 TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR2_LOGIN,
63 TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR2_LOGIN,
65 TEST_USER_REGULAR_PASS)
64 TEST_USER_REGULAR_PASS)
66 from rhodecode.tests.utils import CustomTestApp, set_anonymous_access
65 from rhodecode.tests.utils import CustomTestApp, set_anonymous_access
67 from rhodecode.tests.fixture import Fixture
66 from rhodecode.tests.fixture import Fixture
68 from rhodecode.config import utils as config_utils
67 from rhodecode.config import utils as config_utils
69
68
69
70 def _split_comma(value):
70 def _split_comma(value):
71 return value.split(',')
71 return value.split(',')
72
72
73
73
74 def pytest_addoption(parser):
74 def pytest_addoption(parser):
75 parser.addoption(
75 parser.addoption(
76 '--keep-tmp-path', action='store_true',
76 '--keep-tmp-path', action='store_true',
77 help="Keep the test temporary directories")
77 help="Keep the test temporary directories")
78 parser.addoption(
78 parser.addoption(
79 '--backends', action='store', type=_split_comma,
79 '--backends', action='store', type=_split_comma,
80 default=['git', 'hg', 'svn'],
80 default=['git', 'hg', 'svn'],
81 help="Select which backends to test for backend specific tests.")
81 help="Select which backends to test for backend specific tests.")
82 parser.addoption(
82 parser.addoption(
83 '--dbs', action='store', type=_split_comma,
83 '--dbs', action='store', type=_split_comma,
84 default=['sqlite'],
84 default=['sqlite'],
85 help="Select which database to test for database specific tests. "
85 help="Select which database to test for database specific tests. "
86 "Possible options are sqlite,postgres,mysql")
86 "Possible options are sqlite,postgres,mysql")
87 parser.addoption(
87 parser.addoption(
88 '--appenlight', '--ae', action='store_true',
88 '--appenlight', '--ae', action='store_true',
89 help="Track statistics in appenlight.")
89 help="Track statistics in appenlight.")
90 parser.addoption(
90 parser.addoption(
91 '--appenlight-api-key', '--ae-key',
91 '--appenlight-api-key', '--ae-key',
92 help="API key for Appenlight.")
92 help="API key for Appenlight.")
93 parser.addoption(
93 parser.addoption(
94 '--appenlight-url', '--ae-url',
94 '--appenlight-url', '--ae-url',
95 default="https://ae.rhodecode.com",
95 default="https://ae.rhodecode.com",
96 help="Appenlight service URL, defaults to https://ae.rhodecode.com")
96 help="Appenlight service URL, defaults to https://ae.rhodecode.com")
97 parser.addoption(
97 parser.addoption(
98 '--sqlite-connection-string', action='store',
98 '--sqlite-connection-string', action='store',
99 default='', help="Connection string for the dbs tests with SQLite")
99 default='', help="Connection string for the dbs tests with SQLite")
100 parser.addoption(
100 parser.addoption(
101 '--postgres-connection-string', action='store',
101 '--postgres-connection-string', action='store',
102 default='', help="Connection string for the dbs tests with Postgres")
102 default='', help="Connection string for the dbs tests with Postgres")
103 parser.addoption(
103 parser.addoption(
104 '--mysql-connection-string', action='store',
104 '--mysql-connection-string', action='store',
105 default='', help="Connection string for the dbs tests with MySQL")
105 default='', help="Connection string for the dbs tests with MySQL")
106 parser.addoption(
106 parser.addoption(
107 '--repeat', type=int, default=100,
107 '--repeat', type=int, default=100,
108 help="Number of repetitions in performance tests.")
108 help="Number of repetitions in performance tests.")
109
109
110
110
111 def pytest_configure(config):
111 def pytest_configure(config):
112 from rhodecode.config import patches
112 from rhodecode.config import patches
113
113
114
114
115 def pytest_collection_modifyitems(session, config, items):
115 def pytest_collection_modifyitems(session, config, items):
116 # nottest marked, compare nose, used for transition from nose to pytest
116 # nottest marked, compare nose, used for transition from nose to pytest
117 remaining = [
117 remaining = [
118 i for i in items if getattr(i.obj, '__test__', True)]
118 i for i in items if getattr(i.obj, '__test__', True)]
119 items[:] = remaining
119 items[:] = remaining
120
120
121
121
122 def pytest_generate_tests(metafunc):
122 def pytest_generate_tests(metafunc):
123
123 # Support test generation based on --backend parameter
124 # Support test generation based on --backend parameter
124 if 'backend_alias' in metafunc.fixturenames:
125 if 'backend_alias' in metafunc.fixturenames:
125 backends = get_backends_from_metafunc(metafunc)
126 backends = get_backends_from_metafunc(metafunc)
126 scope = None
127 scope = None
127 if not backends:
128 if not backends:
128 pytest.skip("Not enabled for any of selected backends")
129 pytest.skip("Not enabled for any of selected backends")
130
129 metafunc.parametrize('backend_alias', backends, scope=scope)
131 metafunc.parametrize('backend_alias', backends, scope=scope)
130 elif hasattr(metafunc.function, 'backends'):
132
133 backend_mark = metafunc.definition.get_closest_marker('backends')
134 if backend_mark:
131 backends = get_backends_from_metafunc(metafunc)
135 backends = get_backends_from_metafunc(metafunc)
132 if not backends:
136 if not backends:
133 pytest.skip("Not enabled for any of selected backends")
137 pytest.skip("Not enabled for any of selected backends")
134
138
135
139
136 def get_backends_from_metafunc(metafunc):
140 def get_backends_from_metafunc(metafunc):
137 requested_backends = set(metafunc.config.getoption('--backends'))
141 requested_backends = set(metafunc.config.getoption('--backends'))
138 if hasattr(metafunc.function, 'backends'):
142 backend_mark = metafunc.definition.get_closest_marker('backends')
143 if backend_mark:
139 # Supported backends by this test function, created from
144 # Supported backends by this test function, created from
140 # pytest.mark.backends
145 # pytest.mark.backends
141 backends = metafunc.definition.get_closest_marker('backends').args
146 backends = backend_mark.args
142 elif hasattr(metafunc.cls, 'backend_alias'):
147 elif hasattr(metafunc.cls, 'backend_alias'):
143 # Support class attribute "backend_alias", this is mainly
148 # Support class attribute "backend_alias", this is mainly
144 # for legacy reasons for tests not yet using pytest.mark.backends
149 # for legacy reasons for tests not yet using pytest.mark.backends
145 backends = [metafunc.cls.backend_alias]
150 backends = [metafunc.cls.backend_alias]
146 else:
151 else:
147 backends = metafunc.config.getoption('--backends')
152 backends = metafunc.config.getoption('--backends')
148 return requested_backends.intersection(backends)
153 return requested_backends.intersection(backends)
149
154
150
155
151 @pytest.fixture(scope='session', autouse=True)
156 @pytest.fixture(scope='session', autouse=True)
152 def activate_example_rcextensions(request):
157 def activate_example_rcextensions(request):
153 """
158 """
154 Patch in an example rcextensions module which verifies passed in kwargs.
159 Patch in an example rcextensions module which verifies passed in kwargs.
155 """
160 """
156 from rhodecode.config import rcextensions
161 from rhodecode.config import rcextensions
157
162
158 old_extensions = rhodecode.EXTENSIONS
163 old_extensions = rhodecode.EXTENSIONS
159 rhodecode.EXTENSIONS = rcextensions
164 rhodecode.EXTENSIONS = rcextensions
160 rhodecode.EXTENSIONS.calls = collections.defaultdict(list)
165 rhodecode.EXTENSIONS.calls = collections.defaultdict(list)
161
166
162 @request.addfinalizer
167 @request.addfinalizer
163 def cleanup():
168 def cleanup():
164 rhodecode.EXTENSIONS = old_extensions
169 rhodecode.EXTENSIONS = old_extensions
165
170
166
171
167 @pytest.fixture()
172 @pytest.fixture()
168 def capture_rcextensions():
173 def capture_rcextensions():
169 """
174 """
170 Returns the recorded calls to entry points in rcextensions.
175 Returns the recorded calls to entry points in rcextensions.
171 """
176 """
172 calls = rhodecode.EXTENSIONS.calls
177 calls = rhodecode.EXTENSIONS.calls
173 calls.clear()
178 calls.clear()
174 # Note: At this moment, it is still the empty dict, but that will
179 # Note: At this moment, it is still the empty dict, but that will
175 # be filled during the test run and since it is a reference this
180 # be filled during the test run and since it is a reference this
176 # is enough to make it work.
181 # is enough to make it work.
177 return calls
182 return calls
178
183
179
184
180 @pytest.fixture(scope='session')
185 @pytest.fixture(scope='session')
181 def http_environ_session():
186 def http_environ_session():
182 """
187 """
183 Allow to use "http_environ" in session scope.
188 Allow to use "http_environ" in session scope.
184 """
189 """
185 return plain_http_environ()
190 return plain_http_environ()
186
191
187
192
188 def plain_http_host_stub():
193 def plain_http_host_stub():
189 """
194 """
190 Value of HTTP_HOST in the test run.
195 Value of HTTP_HOST in the test run.
191 """
196 """
192 return 'example.com:80'
197 return 'example.com:80'
193
198
194
199
195 @pytest.fixture()
200 @pytest.fixture()
196 def http_host_stub():
201 def http_host_stub():
197 """
202 """
198 Value of HTTP_HOST in the test run.
203 Value of HTTP_HOST in the test run.
199 """
204 """
200 return plain_http_host_stub()
205 return plain_http_host_stub()
201
206
202
207
203 def plain_http_host_only_stub():
208 def plain_http_host_only_stub():
204 """
209 """
205 Value of HTTP_HOST in the test run.
210 Value of HTTP_HOST in the test run.
206 """
211 """
207 return plain_http_host_stub().split(':')[0]
212 return plain_http_host_stub().split(':')[0]
208
213
209
214
210 @pytest.fixture()
215 @pytest.fixture()
211 def http_host_only_stub():
216 def http_host_only_stub():
212 """
217 """
213 Value of HTTP_HOST in the test run.
218 Value of HTTP_HOST in the test run.
214 """
219 """
215 return plain_http_host_only_stub()
220 return plain_http_host_only_stub()
216
221
217
222
218 def plain_http_environ():
223 def plain_http_environ():
219 """
224 """
220 HTTP extra environ keys.
225 HTTP extra environ keys.
221
226
222 User by the test application and as well for setting up the pylons
227 User by the test application and as well for setting up the pylons
223 environment. In the case of the fixture "app" it should be possible
228 environment. In the case of the fixture "app" it should be possible
224 to override this for a specific test case.
229 to override this for a specific test case.
225 """
230 """
226 return {
231 return {
227 'SERVER_NAME': plain_http_host_only_stub(),
232 'SERVER_NAME': plain_http_host_only_stub(),
228 'SERVER_PORT': plain_http_host_stub().split(':')[1],
233 'SERVER_PORT': plain_http_host_stub().split(':')[1],
229 'HTTP_HOST': plain_http_host_stub(),
234 'HTTP_HOST': plain_http_host_stub(),
230 'HTTP_USER_AGENT': 'rc-test-agent',
235 'HTTP_USER_AGENT': 'rc-test-agent',
231 'REQUEST_METHOD': 'GET'
236 'REQUEST_METHOD': 'GET'
232 }
237 }
233
238
234
239
235 @pytest.fixture()
240 @pytest.fixture()
236 def http_environ():
241 def http_environ():
237 """
242 """
238 HTTP extra environ keys.
243 HTTP extra environ keys.
239
244
240 User by the test application and as well for setting up the pylons
245 User by the test application and as well for setting up the pylons
241 environment. In the case of the fixture "app" it should be possible
246 environment. In the case of the fixture "app" it should be possible
242 to override this for a specific test case.
247 to override this for a specific test case.
243 """
248 """
244 return plain_http_environ()
249 return plain_http_environ()
245
250
246
251
247 @pytest.fixture(scope='session')
252 @pytest.fixture(scope='session')
248 def baseapp(ini_config, vcsserver, http_environ_session):
253 def baseapp(ini_config, vcsserver, http_environ_session):
249 from rhodecode.lib.pyramid_utils import get_app_config
254 from rhodecode.lib.pyramid_utils import get_app_config
250 from rhodecode.config.middleware import make_pyramid_app
255 from rhodecode.config.middleware import make_pyramid_app
251
256
252 print("Using the RhodeCode configuration:{}".format(ini_config))
257 print("Using the RhodeCode configuration:{}".format(ini_config))
253 pyramid.paster.setup_logging(ini_config)
258 pyramid.paster.setup_logging(ini_config)
254
259
255 settings = get_app_config(ini_config)
260 settings = get_app_config(ini_config)
256 app = make_pyramid_app({'__file__': ini_config}, **settings)
261 app = make_pyramid_app({'__file__': ini_config}, **settings)
257
262
258 return app
263 return app
259
264
260
265
261 @pytest.fixture(scope='function')
266 @pytest.fixture(scope='function')
262 def app(request, config_stub, baseapp, http_environ):
267 def app(request, config_stub, baseapp, http_environ):
263 app = CustomTestApp(
268 app = CustomTestApp(
264 baseapp,
269 baseapp,
265 extra_environ=http_environ)
270 extra_environ=http_environ)
266 if request.cls:
271 if request.cls:
267 request.cls.app = app
272 request.cls.app = app
268 return app
273 return app
269
274
270
275
271 @pytest.fixture(scope='session')
276 @pytest.fixture(scope='session')
272 def app_settings(baseapp, ini_config):
277 def app_settings(baseapp, ini_config):
273 """
278 """
274 Settings dictionary used to create the app.
279 Settings dictionary used to create the app.
275
280
276 Parses the ini file and passes the result through the sanitize and apply
281 Parses the ini file and passes the result through the sanitize and apply
277 defaults mechanism in `rhodecode.config.middleware`.
282 defaults mechanism in `rhodecode.config.middleware`.
278 """
283 """
279 return baseapp.config.get_settings()
284 return baseapp.config.get_settings()
280
285
281
286
282 @pytest.fixture(scope='session')
287 @pytest.fixture(scope='session')
283 def db_connection(ini_settings):
288 def db_connection(ini_settings):
284 # Initialize the database connection.
289 # Initialize the database connection.
285 config_utils.initialize_database(ini_settings)
290 config_utils.initialize_database(ini_settings)
286
291
287
292
288 LoginData = collections.namedtuple('LoginData', ('csrf_token', 'user'))
293 LoginData = collections.namedtuple('LoginData', ('csrf_token', 'user'))
289
294
290
295
291 def _autologin_user(app, *args):
296 def _autologin_user(app, *args):
292 session = login_user_session(app, *args)
297 session = login_user_session(app, *args)
293 csrf_token = rhodecode.lib.auth.get_csrf_token(session)
298 csrf_token = rhodecode.lib.auth.get_csrf_token(session)
294 return LoginData(csrf_token, session['rhodecode_user'])
299 return LoginData(csrf_token, session['rhodecode_user'])
295
300
296
301
297 @pytest.fixture()
302 @pytest.fixture()
298 def autologin_user(app):
303 def autologin_user(app):
299 """
304 """
300 Utility fixture which makes sure that the admin user is logged in
305 Utility fixture which makes sure that the admin user is logged in
301 """
306 """
302 return _autologin_user(app)
307 return _autologin_user(app)
303
308
304
309
305 @pytest.fixture()
310 @pytest.fixture()
306 def autologin_regular_user(app):
311 def autologin_regular_user(app):
307 """
312 """
308 Utility fixture which makes sure that the regular user is logged in
313 Utility fixture which makes sure that the regular user is logged in
309 """
314 """
310 return _autologin_user(
315 return _autologin_user(
311 app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
316 app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS)
312
317
313
318
314 @pytest.fixture(scope='function')
319 @pytest.fixture(scope='function')
315 def csrf_token(request, autologin_user):
320 def csrf_token(request, autologin_user):
316 return autologin_user.csrf_token
321 return autologin_user.csrf_token
317
322
318
323
319 @pytest.fixture(scope='function')
324 @pytest.fixture(scope='function')
320 def xhr_header(request):
325 def xhr_header(request):
321 return {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
326 return {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
322
327
323
328
324 @pytest.fixture()
329 @pytest.fixture()
325 def real_crypto_backend(monkeypatch):
330 def real_crypto_backend(monkeypatch):
326 """
331 """
327 Switch the production crypto backend on for this test.
332 Switch the production crypto backend on for this test.
328
333
329 During the test run the crypto backend is replaced with a faster
334 During the test run the crypto backend is replaced with a faster
330 implementation based on the MD5 algorithm.
335 implementation based on the MD5 algorithm.
331 """
336 """
332 monkeypatch.setattr(rhodecode, 'is_test', False)
337 monkeypatch.setattr(rhodecode, 'is_test', False)
333
338
334
339
335 @pytest.fixture(scope='class')
340 @pytest.fixture(scope='class')
336 def index_location(request, baseapp):
341 def index_location(request, baseapp):
337 index_location = baseapp.config.get_settings()['search.location']
342 index_location = baseapp.config.get_settings()['search.location']
338 if request.cls:
343 if request.cls:
339 request.cls.index_location = index_location
344 request.cls.index_location = index_location
340 return index_location
345 return index_location
341
346
342
347
343 @pytest.fixture(scope='session', autouse=True)
348 @pytest.fixture(scope='session', autouse=True)
344 def tests_tmp_path(request):
349 def tests_tmp_path(request):
345 """
350 """
346 Create temporary directory to be used during the test session.
351 Create temporary directory to be used during the test session.
347 """
352 """
348 if not os.path.exists(TESTS_TMP_PATH):
353 if not os.path.exists(TESTS_TMP_PATH):
349 os.makedirs(TESTS_TMP_PATH)
354 os.makedirs(TESTS_TMP_PATH)
350
355
351 if not request.config.getoption('--keep-tmp-path'):
356 if not request.config.getoption('--keep-tmp-path'):
352 @request.addfinalizer
357 @request.addfinalizer
353 def remove_tmp_path():
358 def remove_tmp_path():
354 shutil.rmtree(TESTS_TMP_PATH)
359 shutil.rmtree(TESTS_TMP_PATH)
355
360
356 return TESTS_TMP_PATH
361 return TESTS_TMP_PATH
357
362
358
363
359 @pytest.fixture()
364 @pytest.fixture()
360 def test_repo_group(request):
365 def test_repo_group(request):
361 """
366 """
362 Create a temporary repository group, and destroy it after
367 Create a temporary repository group, and destroy it after
363 usage automatically
368 usage automatically
364 """
369 """
365 fixture = Fixture()
370 fixture = Fixture()
366 repogroupid = 'test_repo_group_%s' % str(time.time()).replace('.', '')
371 repogroupid = 'test_repo_group_%s' % str(time.time()).replace('.', '')
367 repo_group = fixture.create_repo_group(repogroupid)
372 repo_group = fixture.create_repo_group(repogroupid)
368
373
369 def _cleanup():
374 def _cleanup():
370 fixture.destroy_repo_group(repogroupid)
375 fixture.destroy_repo_group(repogroupid)
371
376
372 request.addfinalizer(_cleanup)
377 request.addfinalizer(_cleanup)
373 return repo_group
378 return repo_group
374
379
375
380
376 @pytest.fixture()
381 @pytest.fixture()
377 def test_user_group(request):
382 def test_user_group(request):
378 """
383 """
379 Create a temporary user group, and destroy it after
384 Create a temporary user group, and destroy it after
380 usage automatically
385 usage automatically
381 """
386 """
382 fixture = Fixture()
387 fixture = Fixture()
383 usergroupid = 'test_user_group_%s' % str(time.time()).replace('.', '')
388 usergroupid = 'test_user_group_%s' % str(time.time()).replace('.', '')
384 user_group = fixture.create_user_group(usergroupid)
389 user_group = fixture.create_user_group(usergroupid)
385
390
386 def _cleanup():
391 def _cleanup():
387 fixture.destroy_user_group(user_group)
392 fixture.destroy_user_group(user_group)
388
393
389 request.addfinalizer(_cleanup)
394 request.addfinalizer(_cleanup)
390 return user_group
395 return user_group
391
396
392
397
393 @pytest.fixture(scope='session')
398 @pytest.fixture(scope='session')
394 def test_repo(request):
399 def test_repo(request):
395 container = TestRepoContainer()
400 container = TestRepoContainer()
396 request.addfinalizer(container._cleanup)
401 request.addfinalizer(container._cleanup)
397 return container
402 return container
398
403
399
404
400 class TestRepoContainer(object):
405 class TestRepoContainer(object):
401 """
406 """
402 Container for test repositories which are used read only.
407 Container for test repositories which are used read only.
403
408
404 Repositories will be created on demand and re-used during the lifetime
409 Repositories will be created on demand and re-used during the lifetime
405 of this object.
410 of this object.
406
411
407 Usage to get the svn test repository "minimal"::
412 Usage to get the svn test repository "minimal"::
408
413
409 test_repo = TestContainer()
414 test_repo = TestContainer()
410 repo = test_repo('minimal', 'svn')
415 repo = test_repo('minimal', 'svn')
411
416
412 """
417 """
413
418
414 dump_extractors = {
419 dump_extractors = {
415 'git': utils.extract_git_repo_from_dump,
420 'git': utils.extract_git_repo_from_dump,
416 'hg': utils.extract_hg_repo_from_dump,
421 'hg': utils.extract_hg_repo_from_dump,
417 'svn': utils.extract_svn_repo_from_dump,
422 'svn': utils.extract_svn_repo_from_dump,
418 }
423 }
419
424
420 def __init__(self):
425 def __init__(self):
421 self._cleanup_repos = []
426 self._cleanup_repos = []
422 self._fixture = Fixture()
427 self._fixture = Fixture()
423 self._repos = {}
428 self._repos = {}
424
429
425 def __call__(self, dump_name, backend_alias, config=None):
430 def __call__(self, dump_name, backend_alias, config=None):
426 key = (dump_name, backend_alias)
431 key = (dump_name, backend_alias)
427 if key not in self._repos:
432 if key not in self._repos:
428 repo = self._create_repo(dump_name, backend_alias, config)
433 repo = self._create_repo(dump_name, backend_alias, config)
429 self._repos[key] = repo.repo_id
434 self._repos[key] = repo.repo_id
430 return Repository.get(self._repos[key])
435 return Repository.get(self._repos[key])
431
436
432 def _create_repo(self, dump_name, backend_alias, config):
437 def _create_repo(self, dump_name, backend_alias, config):
433 repo_name = '%s-%s' % (backend_alias, dump_name)
438 repo_name = '%s-%s' % (backend_alias, dump_name)
434 backend = get_backend(backend_alias)
439 backend = get_backend(backend_alias)
435 dump_extractor = self.dump_extractors[backend_alias]
440 dump_extractor = self.dump_extractors[backend_alias]
436 repo_path = dump_extractor(dump_name, repo_name)
441 repo_path = dump_extractor(dump_name, repo_name)
437
442
438 vcs_repo = backend(repo_path, config=config)
443 vcs_repo = backend(repo_path, config=config)
439 repo2db_mapper({repo_name: vcs_repo})
444 repo2db_mapper({repo_name: vcs_repo})
440
445
441 repo = RepoModel().get_by_repo_name(repo_name)
446 repo = RepoModel().get_by_repo_name(repo_name)
442 self._cleanup_repos.append(repo_name)
447 self._cleanup_repos.append(repo_name)
443 return repo
448 return repo
444
449
445 def _cleanup(self):
450 def _cleanup(self):
446 for repo_name in reversed(self._cleanup_repos):
451 for repo_name in reversed(self._cleanup_repos):
447 self._fixture.destroy_repo(repo_name)
452 self._fixture.destroy_repo(repo_name)
448
453
449
454
450 def backend_base(request, backend_alias, baseapp, test_repo):
455 def backend_base(request, backend_alias, baseapp, test_repo):
451 if backend_alias not in request.config.getoption('--backends'):
456 if backend_alias not in request.config.getoption('--backends'):
452 pytest.skip("Backend %s not selected." % (backend_alias, ))
457 pytest.skip("Backend %s not selected." % (backend_alias, ))
453
458
454 utils.check_xfail_backends(request.node, backend_alias)
459 utils.check_xfail_backends(request.node, backend_alias)
455 utils.check_skip_backends(request.node, backend_alias)
460 utils.check_skip_backends(request.node, backend_alias)
456
461
457 repo_name = 'vcs_test_%s' % (backend_alias, )
462 repo_name = 'vcs_test_%s' % (backend_alias, )
458 backend = Backend(
463 backend = Backend(
459 alias=backend_alias,
464 alias=backend_alias,
460 repo_name=repo_name,
465 repo_name=repo_name,
461 test_name=request.node.name,
466 test_name=request.node.name,
462 test_repo_container=test_repo)
467 test_repo_container=test_repo)
463 request.addfinalizer(backend.cleanup)
468 request.addfinalizer(backend.cleanup)
464 return backend
469 return backend
465
470
466
471
467 @pytest.fixture()
472 @pytest.fixture()
468 def backend(request, backend_alias, baseapp, test_repo):
473 def backend(request, backend_alias, baseapp, test_repo):
469 """
474 """
470 Parametrized fixture which represents a single backend implementation.
475 Parametrized fixture which represents a single backend implementation.
471
476
472 It respects the option `--backends` to focus the test run on specific
477 It respects the option `--backends` to focus the test run on specific
473 backend implementations.
478 backend implementations.
474
479
475 It also supports `pytest.mark.xfail_backends` to mark tests as failing
480 It also supports `pytest.mark.xfail_backends` to mark tests as failing
476 for specific backends. This is intended as a utility for incremental
481 for specific backends. This is intended as a utility for incremental
477 development of a new backend implementation.
482 development of a new backend implementation.
478 """
483 """
479 return backend_base(request, backend_alias, baseapp, test_repo)
484 return backend_base(request, backend_alias, baseapp, test_repo)
480
485
481
486
482 @pytest.fixture()
487 @pytest.fixture()
483 def backend_git(request, baseapp, test_repo):
488 def backend_git(request, baseapp, test_repo):
484 return backend_base(request, 'git', baseapp, test_repo)
489 return backend_base(request, 'git', baseapp, test_repo)
485
490
486
491
487 @pytest.fixture()
492 @pytest.fixture()
488 def backend_hg(request, baseapp, test_repo):
493 def backend_hg(request, baseapp, test_repo):
489 return backend_base(request, 'hg', baseapp, test_repo)
494 return backend_base(request, 'hg', baseapp, test_repo)
490
495
491
496
492 @pytest.fixture()
497 @pytest.fixture()
493 def backend_svn(request, baseapp, test_repo):
498 def backend_svn(request, baseapp, test_repo):
494 return backend_base(request, 'svn', baseapp, test_repo)
499 return backend_base(request, 'svn', baseapp, test_repo)
495
500
496
501
497 @pytest.fixture()
502 @pytest.fixture()
498 def backend_random(backend_git):
503 def backend_random(backend_git):
499 """
504 """
500 Use this to express that your tests need "a backend.
505 Use this to express that your tests need "a backend.
501
506
502 A few of our tests need a backend, so that we can run the code. This
507 A few of our tests need a backend, so that we can run the code. This
503 fixture is intended to be used for such cases. It will pick one of the
508 fixture is intended to be used for such cases. It will pick one of the
504 backends and run the tests.
509 backends and run the tests.
505
510
506 The fixture `backend` would run the test multiple times for each
511 The fixture `backend` would run the test multiple times for each
507 available backend which is a pure waste of time if the test is
512 available backend which is a pure waste of time if the test is
508 independent of the backend type.
513 independent of the backend type.
509 """
514 """
510 # TODO: johbo: Change this to pick a random backend
515 # TODO: johbo: Change this to pick a random backend
511 return backend_git
516 return backend_git
512
517
513
518
514 @pytest.fixture()
519 @pytest.fixture()
515 def backend_stub(backend_git):
520 def backend_stub(backend_git):
516 """
521 """
517 Use this to express that your tests need a backend stub
522 Use this to express that your tests need a backend stub
518
523
519 TODO: mikhail: Implement a real stub logic instead of returning
524 TODO: mikhail: Implement a real stub logic instead of returning
520 a git backend
525 a git backend
521 """
526 """
522 return backend_git
527 return backend_git
523
528
524
529
525 @pytest.fixture()
530 @pytest.fixture()
526 def repo_stub(backend_stub):
531 def repo_stub(backend_stub):
527 """
532 """
528 Use this to express that your tests need a repository stub
533 Use this to express that your tests need a repository stub
529 """
534 """
530 return backend_stub.create_repo()
535 return backend_stub.create_repo()
531
536
532
537
533 class Backend(object):
538 class Backend(object):
534 """
539 """
535 Represents the test configuration for one supported backend
540 Represents the test configuration for one supported backend
536
541
537 Provides easy access to different test repositories based on
542 Provides easy access to different test repositories based on
538 `__getitem__`. Such repositories will only be created once per test
543 `__getitem__`. Such repositories will only be created once per test
539 session.
544 session.
540 """
545 """
541
546
542 invalid_repo_name = re.compile(r'[^0-9a-zA-Z]+')
547 invalid_repo_name = re.compile(r'[^0-9a-zA-Z]+')
543 _master_repo = None
548 _master_repo = None
544 _commit_ids = {}
549 _commit_ids = {}
545
550
546 def __init__(self, alias, repo_name, test_name, test_repo_container):
551 def __init__(self, alias, repo_name, test_name, test_repo_container):
547 self.alias = alias
552 self.alias = alias
548 self.repo_name = repo_name
553 self.repo_name = repo_name
549 self._cleanup_repos = []
554 self._cleanup_repos = []
550 self._test_name = test_name
555 self._test_name = test_name
551 self._test_repo_container = test_repo_container
556 self._test_repo_container = test_repo_container
552 # TODO: johbo: Used as a delegate interim. Not yet sure if Backend or
557 # TODO: johbo: Used as a delegate interim. Not yet sure if Backend or
553 # Fixture will survive in the end.
558 # Fixture will survive in the end.
554 self._fixture = Fixture()
559 self._fixture = Fixture()
555
560
556 def __getitem__(self, key):
561 def __getitem__(self, key):
557 return self._test_repo_container(key, self.alias)
562 return self._test_repo_container(key, self.alias)
558
563
559 def create_test_repo(self, key, config=None):
564 def create_test_repo(self, key, config=None):
560 return self._test_repo_container(key, self.alias, config)
565 return self._test_repo_container(key, self.alias, config)
561
566
562 @property
567 @property
563 def repo(self):
568 def repo(self):
564 """
569 """
565 Returns the "current" repository. This is the vcs_test repo or the
570 Returns the "current" repository. This is the vcs_test repo or the
566 last repo which has been created with `create_repo`.
571 last repo which has been created with `create_repo`.
567 """
572 """
568 from rhodecode.model.db import Repository
573 from rhodecode.model.db import Repository
569 return Repository.get_by_repo_name(self.repo_name)
574 return Repository.get_by_repo_name(self.repo_name)
570
575
571 @property
576 @property
572 def default_branch_name(self):
577 def default_branch_name(self):
573 VcsRepository = get_backend(self.alias)
578 VcsRepository = get_backend(self.alias)
574 return VcsRepository.DEFAULT_BRANCH_NAME
579 return VcsRepository.DEFAULT_BRANCH_NAME
575
580
576 @property
581 @property
577 def default_head_id(self):
582 def default_head_id(self):
578 """
583 """
579 Returns the default head id of the underlying backend.
584 Returns the default head id of the underlying backend.
580
585
581 This will be the default branch name in case the backend does have a
586 This will be the default branch name in case the backend does have a
582 default branch. In the other cases it will point to a valid head
587 default branch. In the other cases it will point to a valid head
583 which can serve as the base to create a new commit on top of it.
588 which can serve as the base to create a new commit on top of it.
584 """
589 """
585 vcsrepo = self.repo.scm_instance()
590 vcsrepo = self.repo.scm_instance()
586 head_id = (
591 head_id = (
587 vcsrepo.DEFAULT_BRANCH_NAME or
592 vcsrepo.DEFAULT_BRANCH_NAME or
588 vcsrepo.commit_ids[-1])
593 vcsrepo.commit_ids[-1])
589 return head_id
594 return head_id
590
595
591 @property
596 @property
592 def commit_ids(self):
597 def commit_ids(self):
593 """
598 """
594 Returns the list of commits for the last created repository
599 Returns the list of commits for the last created repository
595 """
600 """
596 return self._commit_ids
601 return self._commit_ids
597
602
598 def create_master_repo(self, commits):
603 def create_master_repo(self, commits):
599 """
604 """
600 Create a repository and remember it as a template.
605 Create a repository and remember it as a template.
601
606
602 This allows to easily create derived repositories to construct
607 This allows to easily create derived repositories to construct
603 more complex scenarios for diff, compare and pull requests.
608 more complex scenarios for diff, compare and pull requests.
604
609
605 Returns a commit map which maps from commit message to raw_id.
610 Returns a commit map which maps from commit message to raw_id.
606 """
611 """
607 self._master_repo = self.create_repo(commits=commits)
612 self._master_repo = self.create_repo(commits=commits)
608 return self._commit_ids
613 return self._commit_ids
609
614
610 def create_repo(
615 def create_repo(
611 self, commits=None, number_of_commits=0, heads=None,
616 self, commits=None, number_of_commits=0, heads=None,
612 name_suffix=u'', bare=False, **kwargs):
617 name_suffix=u'', bare=False, **kwargs):
613 """
618 """
614 Create a repository and record it for later cleanup.
619 Create a repository and record it for later cleanup.
615
620
616 :param commits: Optional. A sequence of dict instances.
621 :param commits: Optional. A sequence of dict instances.
617 Will add a commit per entry to the new repository.
622 Will add a commit per entry to the new repository.
618 :param number_of_commits: Optional. If set to a number, this number of
623 :param number_of_commits: Optional. If set to a number, this number of
619 commits will be added to the new repository.
624 commits will be added to the new repository.
620 :param heads: Optional. Can be set to a sequence of of commit
625 :param heads: Optional. Can be set to a sequence of of commit
621 names which shall be pulled in from the master repository.
626 names which shall be pulled in from the master repository.
622 :param name_suffix: adds special suffix to generated repo name
627 :param name_suffix: adds special suffix to generated repo name
623 :param bare: set a repo as bare (no checkout)
628 :param bare: set a repo as bare (no checkout)
624 """
629 """
625 self.repo_name = self._next_repo_name() + name_suffix
630 self.repo_name = self._next_repo_name() + name_suffix
626 repo = self._fixture.create_repo(
631 repo = self._fixture.create_repo(
627 self.repo_name, repo_type=self.alias, bare=bare, **kwargs)
632 self.repo_name, repo_type=self.alias, bare=bare, **kwargs)
628 self._cleanup_repos.append(repo.repo_name)
633 self._cleanup_repos.append(repo.repo_name)
629
634
630 commits = commits or [
635 commits = commits or [
631 {'message': 'Commit %s of %s' % (x, self.repo_name)}
636 {'message': 'Commit %s of %s' % (x, self.repo_name)}
632 for x in range(number_of_commits)]
637 for x in range(number_of_commits)]
633 vcs_repo = repo.scm_instance()
638 vcs_repo = repo.scm_instance()
634 vcs_repo.count()
639 vcs_repo.count()
635 self._add_commits_to_repo(vcs_repo, commits)
640 self._add_commits_to_repo(vcs_repo, commits)
636 if heads:
641 if heads:
637 self.pull_heads(repo, heads)
642 self.pull_heads(repo, heads)
638
643
639 return repo
644 return repo
640
645
641 def pull_heads(self, repo, heads):
646 def pull_heads(self, repo, heads):
642 """
647 """
643 Make sure that repo contains all commits mentioned in `heads`
648 Make sure that repo contains all commits mentioned in `heads`
644 """
649 """
645 vcsmaster = self._master_repo.scm_instance()
650 vcsmaster = self._master_repo.scm_instance()
646 vcsrepo = repo.scm_instance()
651 vcsrepo = repo.scm_instance()
647 vcsrepo.config.clear_section('hooks')
652 vcsrepo.config.clear_section('hooks')
648 commit_ids = [self._commit_ids[h] for h in heads]
653 commit_ids = [self._commit_ids[h] for h in heads]
649 vcsrepo.pull(vcsmaster.path, commit_ids=commit_ids)
654 vcsrepo.pull(vcsmaster.path, commit_ids=commit_ids)
650
655
651 def create_fork(self):
656 def create_fork(self):
652 repo_to_fork = self.repo_name
657 repo_to_fork = self.repo_name
653 self.repo_name = self._next_repo_name()
658 self.repo_name = self._next_repo_name()
654 repo = self._fixture.create_fork(repo_to_fork, self.repo_name)
659 repo = self._fixture.create_fork(repo_to_fork, self.repo_name)
655 self._cleanup_repos.append(self.repo_name)
660 self._cleanup_repos.append(self.repo_name)
656 return repo
661 return repo
657
662
658 def new_repo_name(self, suffix=u''):
663 def new_repo_name(self, suffix=u''):
659 self.repo_name = self._next_repo_name() + suffix
664 self.repo_name = self._next_repo_name() + suffix
660 self._cleanup_repos.append(self.repo_name)
665 self._cleanup_repos.append(self.repo_name)
661 return self.repo_name
666 return self.repo_name
662
667
663 def _next_repo_name(self):
668 def _next_repo_name(self):
664 return u"%s_%s" % (
669 return u"%s_%s" % (
665 self.invalid_repo_name.sub(u'_', self._test_name), len(self._cleanup_repos))
670 self.invalid_repo_name.sub(u'_', self._test_name), len(self._cleanup_repos))
666
671
667 def ensure_file(self, filename, content='Test content\n'):
672 def ensure_file(self, filename, content='Test content\n'):
668 assert self._cleanup_repos, "Avoid writing into vcs_test repos"
673 assert self._cleanup_repos, "Avoid writing into vcs_test repos"
669 commits = [
674 commits = [
670 {'added': [
675 {'added': [
671 FileNode(filename, content=content),
676 FileNode(filename, content=content),
672 ]},
677 ]},
673 ]
678 ]
674 self._add_commits_to_repo(self.repo.scm_instance(), commits)
679 self._add_commits_to_repo(self.repo.scm_instance(), commits)
675
680
676 def enable_downloads(self):
681 def enable_downloads(self):
677 repo = self.repo
682 repo = self.repo
678 repo.enable_downloads = True
683 repo.enable_downloads = True
679 Session().add(repo)
684 Session().add(repo)
680 Session().commit()
685 Session().commit()
681
686
682 def cleanup(self):
687 def cleanup(self):
683 for repo_name in reversed(self._cleanup_repos):
688 for repo_name in reversed(self._cleanup_repos):
684 self._fixture.destroy_repo(repo_name)
689 self._fixture.destroy_repo(repo_name)
685
690
686 def _add_commits_to_repo(self, repo, commits):
691 def _add_commits_to_repo(self, repo, commits):
687 commit_ids = _add_commits_to_repo(repo, commits)
692 commit_ids = _add_commits_to_repo(repo, commits)
688 if not commit_ids:
693 if not commit_ids:
689 return
694 return
690 self._commit_ids = commit_ids
695 self._commit_ids = commit_ids
691
696
692 # Creating refs for Git to allow fetching them from remote repository
697 # Creating refs for Git to allow fetching them from remote repository
693 if self.alias == 'git':
698 if self.alias == 'git':
694 refs = {}
699 refs = {}
695 for message in self._commit_ids:
700 for message in self._commit_ids:
696 # TODO: mikhail: do more special chars replacements
701 # TODO: mikhail: do more special chars replacements
697 ref_name = 'refs/test-refs/{}'.format(
702 ref_name = 'refs/test-refs/{}'.format(
698 message.replace(' ', ''))
703 message.replace(' ', ''))
699 refs[ref_name] = self._commit_ids[message]
704 refs[ref_name] = self._commit_ids[message]
700 self._create_refs(repo, refs)
705 self._create_refs(repo, refs)
701
706
702 def _create_refs(self, repo, refs):
707 def _create_refs(self, repo, refs):
703 for ref_name in refs:
708 for ref_name in refs:
704 repo.set_refs(ref_name, refs[ref_name])
709 repo.set_refs(ref_name, refs[ref_name])
705
710
706
711
707 def vcsbackend_base(request, backend_alias, tests_tmp_path, baseapp, test_repo):
712 def vcsbackend_base(request, backend_alias, tests_tmp_path, baseapp, test_repo):
708 if backend_alias not in request.config.getoption('--backends'):
713 if backend_alias not in request.config.getoption('--backends'):
709 pytest.skip("Backend %s not selected." % (backend_alias, ))
714 pytest.skip("Backend %s not selected." % (backend_alias, ))
710
715
711 utils.check_xfail_backends(request.node, backend_alias)
716 utils.check_xfail_backends(request.node, backend_alias)
712 utils.check_skip_backends(request.node, backend_alias)
717 utils.check_skip_backends(request.node, backend_alias)
713
718
714 repo_name = 'vcs_test_%s' % (backend_alias, )
719 repo_name = 'vcs_test_%s' % (backend_alias, )
715 repo_path = os.path.join(tests_tmp_path, repo_name)
720 repo_path = os.path.join(tests_tmp_path, repo_name)
716 backend = VcsBackend(
721 backend = VcsBackend(
717 alias=backend_alias,
722 alias=backend_alias,
718 repo_path=repo_path,
723 repo_path=repo_path,
719 test_name=request.node.name,
724 test_name=request.node.name,
720 test_repo_container=test_repo)
725 test_repo_container=test_repo)
721 request.addfinalizer(backend.cleanup)
726 request.addfinalizer(backend.cleanup)
722 return backend
727 return backend
723
728
724
729
725 @pytest.fixture()
730 @pytest.fixture()
726 def vcsbackend(request, backend_alias, tests_tmp_path, baseapp, test_repo):
731 def vcsbackend(request, backend_alias, tests_tmp_path, baseapp, test_repo):
727 """
732 """
728 Parametrized fixture which represents a single vcs backend implementation.
733 Parametrized fixture which represents a single vcs backend implementation.
729
734
730 See the fixture `backend` for more details. This one implements the same
735 See the fixture `backend` for more details. This one implements the same
731 concept, but on vcs level. So it does not provide model instances etc.
736 concept, but on vcs level. So it does not provide model instances etc.
732
737
733 Parameters are generated dynamically, see :func:`pytest_generate_tests`
738 Parameters are generated dynamically, see :func:`pytest_generate_tests`
734 for how this works.
739 for how this works.
735 """
740 """
736 return vcsbackend_base(request, backend_alias, tests_tmp_path, baseapp, test_repo)
741 return vcsbackend_base(request, backend_alias, tests_tmp_path, baseapp, test_repo)
737
742
738
743
739 @pytest.fixture()
744 @pytest.fixture()
740 def vcsbackend_git(request, tests_tmp_path, baseapp, test_repo):
745 def vcsbackend_git(request, tests_tmp_path, baseapp, test_repo):
741 return vcsbackend_base(request, 'git', tests_tmp_path, baseapp, test_repo)
746 return vcsbackend_base(request, 'git', tests_tmp_path, baseapp, test_repo)
742
747
743
748
744 @pytest.fixture()
749 @pytest.fixture()
745 def vcsbackend_hg(request, tests_tmp_path, baseapp, test_repo):
750 def vcsbackend_hg(request, tests_tmp_path, baseapp, test_repo):
746 return vcsbackend_base(request, 'hg', tests_tmp_path, baseapp, test_repo)
751 return vcsbackend_base(request, 'hg', tests_tmp_path, baseapp, test_repo)
747
752
748
753
749 @pytest.fixture()
754 @pytest.fixture()
750 def vcsbackend_svn(request, tests_tmp_path, baseapp, test_repo):
755 def vcsbackend_svn(request, tests_tmp_path, baseapp, test_repo):
751 return vcsbackend_base(request, 'svn', tests_tmp_path, baseapp, test_repo)
756 return vcsbackend_base(request, 'svn', tests_tmp_path, baseapp, test_repo)
752
757
753
758
754 @pytest.fixture()
759 @pytest.fixture()
755 def vcsbackend_stub(vcsbackend_git):
760 def vcsbackend_stub(vcsbackend_git):
756 """
761 """
757 Use this to express that your test just needs a stub of a vcsbackend.
762 Use this to express that your test just needs a stub of a vcsbackend.
758
763
759 Plan is to eventually implement an in-memory stub to speed tests up.
764 Plan is to eventually implement an in-memory stub to speed tests up.
760 """
765 """
761 return vcsbackend_git
766 return vcsbackend_git
762
767
763
768
764 class VcsBackend(object):
769 class VcsBackend(object):
765 """
770 """
766 Represents the test configuration for one supported vcs backend.
771 Represents the test configuration for one supported vcs backend.
767 """
772 """
768
773
769 invalid_repo_name = re.compile(r'[^0-9a-zA-Z]+')
774 invalid_repo_name = re.compile(r'[^0-9a-zA-Z]+')
770
775
771 def __init__(self, alias, repo_path, test_name, test_repo_container):
776 def __init__(self, alias, repo_path, test_name, test_repo_container):
772 self.alias = alias
777 self.alias = alias
773 self._repo_path = repo_path
778 self._repo_path = repo_path
774 self._cleanup_repos = []
779 self._cleanup_repos = []
775 self._test_name = test_name
780 self._test_name = test_name
776 self._test_repo_container = test_repo_container
781 self._test_repo_container = test_repo_container
777
782
778 def __getitem__(self, key):
783 def __getitem__(self, key):
779 return self._test_repo_container(key, self.alias).scm_instance()
784 return self._test_repo_container(key, self.alias).scm_instance()
780
785
781 @property
786 @property
782 def repo(self):
787 def repo(self):
783 """
788 """
784 Returns the "current" repository. This is the vcs_test repo of the last
789 Returns the "current" repository. This is the vcs_test repo of the last
785 repo which has been created.
790 repo which has been created.
786 """
791 """
787 Repository = get_backend(self.alias)
792 Repository = get_backend(self.alias)
788 return Repository(self._repo_path)
793 return Repository(self._repo_path)
789
794
790 @property
795 @property
791 def backend(self):
796 def backend(self):
792 """
797 """
793 Returns the backend implementation class.
798 Returns the backend implementation class.
794 """
799 """
795 return get_backend(self.alias)
800 return get_backend(self.alias)
796
801
797 def create_repo(self, commits=None, number_of_commits=0, _clone_repo=None,
802 def create_repo(self, commits=None, number_of_commits=0, _clone_repo=None,
798 bare=False):
803 bare=False):
799 repo_name = self._next_repo_name()
804 repo_name = self._next_repo_name()
800 self._repo_path = get_new_dir(repo_name)
805 self._repo_path = get_new_dir(repo_name)
801 repo_class = get_backend(self.alias)
806 repo_class = get_backend(self.alias)
802 src_url = None
807 src_url = None
803 if _clone_repo:
808 if _clone_repo:
804 src_url = _clone_repo.path
809 src_url = _clone_repo.path
805 repo = repo_class(self._repo_path, create=True, src_url=src_url, bare=bare)
810 repo = repo_class(self._repo_path, create=True, src_url=src_url, bare=bare)
806 self._cleanup_repos.append(repo)
811 self._cleanup_repos.append(repo)
807
812
808 commits = commits or [
813 commits = commits or [
809 {'message': 'Commit %s of %s' % (x, repo_name)}
814 {'message': 'Commit %s of %s' % (x, repo_name)}
810 for x in xrange(number_of_commits)]
815 for x in xrange(number_of_commits)]
811 _add_commits_to_repo(repo, commits)
816 _add_commits_to_repo(repo, commits)
812 return repo
817 return repo
813
818
814 def clone_repo(self, repo):
819 def clone_repo(self, repo):
815 return self.create_repo(_clone_repo=repo)
820 return self.create_repo(_clone_repo=repo)
816
821
817 def cleanup(self):
822 def cleanup(self):
818 for repo in self._cleanup_repos:
823 for repo in self._cleanup_repos:
819 shutil.rmtree(repo.path)
824 shutil.rmtree(repo.path)
820
825
821 def new_repo_path(self):
826 def new_repo_path(self):
822 repo_name = self._next_repo_name()
827 repo_name = self._next_repo_name()
823 self._repo_path = get_new_dir(repo_name)
828 self._repo_path = get_new_dir(repo_name)
824 return self._repo_path
829 return self._repo_path
825
830
826 def _next_repo_name(self):
831 def _next_repo_name(self):
827 return "%s_%s" % (
832 return "%s_%s" % (
828 self.invalid_repo_name.sub('_', self._test_name),
833 self.invalid_repo_name.sub('_', self._test_name),
829 len(self._cleanup_repos))
834 len(self._cleanup_repos))
830
835
831 def add_file(self, repo, filename, content='Test content\n'):
836 def add_file(self, repo, filename, content='Test content\n'):
832 imc = repo.in_memory_commit
837 imc = repo.in_memory_commit
833 imc.add(FileNode(filename, content=content))
838 imc.add(FileNode(filename, content=content))
834 imc.commit(
839 imc.commit(
835 message=u'Automatic commit from vcsbackend fixture',
840 message=u'Automatic commit from vcsbackend fixture',
836 author=u'Automatic <automatic@rhodecode.com>')
841 author=u'Automatic <automatic@rhodecode.com>')
837
842
838 def ensure_file(self, filename, content='Test content\n'):
843 def ensure_file(self, filename, content='Test content\n'):
839 assert self._cleanup_repos, "Avoid writing into vcs_test repos"
844 assert self._cleanup_repos, "Avoid writing into vcs_test repos"
840 self.add_file(self.repo, filename, content)
845 self.add_file(self.repo, filename, content)
841
846
842
847
843 def _add_commits_to_repo(vcs_repo, commits):
848 def _add_commits_to_repo(vcs_repo, commits):
844 commit_ids = {}
849 commit_ids = {}
845 if not commits:
850 if not commits:
846 return commit_ids
851 return commit_ids
847
852
848 imc = vcs_repo.in_memory_commit
853 imc = vcs_repo.in_memory_commit
849 commit = None
854 commit = None
850
855
851 for idx, commit in enumerate(commits):
856 for idx, commit in enumerate(commits):
852 message = unicode(commit.get('message', 'Commit %s' % idx))
857 message = unicode(commit.get('message', 'Commit %s' % idx))
853
858
854 for node in commit.get('added', []):
859 for node in commit.get('added', []):
855 imc.add(FileNode(node.path, content=node.content))
860 imc.add(FileNode(node.path, content=node.content))
856 for node in commit.get('changed', []):
861 for node in commit.get('changed', []):
857 imc.change(FileNode(node.path, content=node.content))
862 imc.change(FileNode(node.path, content=node.content))
858 for node in commit.get('removed', []):
863 for node in commit.get('removed', []):
859 imc.remove(FileNode(node.path))
864 imc.remove(FileNode(node.path))
860
865
861 parents = [
866 parents = [
862 vcs_repo.get_commit(commit_id=commit_ids[p])
867 vcs_repo.get_commit(commit_id=commit_ids[p])
863 for p in commit.get('parents', [])]
868 for p in commit.get('parents', [])]
864
869
865 operations = ('added', 'changed', 'removed')
870 operations = ('added', 'changed', 'removed')
866 if not any((commit.get(o) for o in operations)):
871 if not any((commit.get(o) for o in operations)):
867 imc.add(FileNode('file_%s' % idx, content=message))
872 imc.add(FileNode('file_%s' % idx, content=message))
868
873
869 commit = imc.commit(
874 commit = imc.commit(
870 message=message,
875 message=message,
871 author=unicode(commit.get('author', 'Automatic <automatic@rhodecode.com>')),
876 author=unicode(commit.get('author', 'Automatic <automatic@rhodecode.com>')),
872 date=commit.get('date'),
877 date=commit.get('date'),
873 branch=commit.get('branch'),
878 branch=commit.get('branch'),
874 parents=parents)
879 parents=parents)
875
880
876 commit_ids[commit.message] = commit.raw_id
881 commit_ids[commit.message] = commit.raw_id
877
882
878 return commit_ids
883 return commit_ids
879
884
880
885
881 @pytest.fixture()
886 @pytest.fixture()
882 def reposerver(request):
887 def reposerver(request):
883 """
888 """
884 Allows to serve a backend repository
889 Allows to serve a backend repository
885 """
890 """
886
891
887 repo_server = RepoServer()
892 repo_server = RepoServer()
888 request.addfinalizer(repo_server.cleanup)
893 request.addfinalizer(repo_server.cleanup)
889 return repo_server
894 return repo_server
890
895
891
896
892 class RepoServer(object):
897 class RepoServer(object):
893 """
898 """
894 Utility to serve a local repository for the duration of a test case.
899 Utility to serve a local repository for the duration of a test case.
895
900
896 Supports only Subversion so far.
901 Supports only Subversion so far.
897 """
902 """
898
903
899 url = None
904 url = None
900
905
901 def __init__(self):
906 def __init__(self):
902 self._cleanup_servers = []
907 self._cleanup_servers = []
903
908
904 def serve(self, vcsrepo):
909 def serve(self, vcsrepo):
905 if vcsrepo.alias != 'svn':
910 if vcsrepo.alias != 'svn':
906 raise TypeError("Backend %s not supported" % vcsrepo.alias)
911 raise TypeError("Backend %s not supported" % vcsrepo.alias)
907
912
908 proc = subprocess32.Popen(
913 proc = subprocess32.Popen(
909 ['svnserve', '-d', '--foreground', '--listen-host', 'localhost',
914 ['svnserve', '-d', '--foreground', '--listen-host', 'localhost',
910 '--root', vcsrepo.path])
915 '--root', vcsrepo.path])
911 self._cleanup_servers.append(proc)
916 self._cleanup_servers.append(proc)
912 self.url = 'svn://localhost'
917 self.url = 'svn://localhost'
913
918
914 def cleanup(self):
919 def cleanup(self):
915 for proc in self._cleanup_servers:
920 for proc in self._cleanup_servers:
916 proc.terminate()
921 proc.terminate()
917
922
918
923
919 @pytest.fixture()
924 @pytest.fixture()
920 def pr_util(backend, request, config_stub):
925 def pr_util(backend, request, config_stub):
921 """
926 """
922 Utility for tests of models and for functional tests around pull requests.
927 Utility for tests of models and for functional tests around pull requests.
923
928
924 It gives an instance of :class:`PRTestUtility` which provides various
929 It gives an instance of :class:`PRTestUtility` which provides various
925 utility methods around one pull request.
930 utility methods around one pull request.
926
931
927 This fixture uses `backend` and inherits its parameterization.
932 This fixture uses `backend` and inherits its parameterization.
928 """
933 """
929
934
930 util = PRTestUtility(backend)
935 util = PRTestUtility(backend)
931 request.addfinalizer(util.cleanup)
936 request.addfinalizer(util.cleanup)
932
937
933 return util
938 return util
934
939
935
940
936 class PRTestUtility(object):
941 class PRTestUtility(object):
937
942
938 pull_request = None
943 pull_request = None
939 pull_request_id = None
944 pull_request_id = None
940 mergeable_patcher = None
945 mergeable_patcher = None
941 mergeable_mock = None
946 mergeable_mock = None
942 notification_patcher = None
947 notification_patcher = None
943
948
944 def __init__(self, backend):
949 def __init__(self, backend):
945 self.backend = backend
950 self.backend = backend
946
951
947 def create_pull_request(
952 def create_pull_request(
948 self, commits=None, target_head=None, source_head=None,
953 self, commits=None, target_head=None, source_head=None,
949 revisions=None, approved=False, author=None, mergeable=False,
954 revisions=None, approved=False, author=None, mergeable=False,
950 enable_notifications=True, name_suffix=u'', reviewers=None,
955 enable_notifications=True, name_suffix=u'', reviewers=None,
951 title=u"Test", description=u"Description"):
956 title=u"Test", description=u"Description"):
952 self.set_mergeable(mergeable)
957 self.set_mergeable(mergeable)
953 if not enable_notifications:
958 if not enable_notifications:
954 # mock notification side effect
959 # mock notification side effect
955 self.notification_patcher = mock.patch(
960 self.notification_patcher = mock.patch(
956 'rhodecode.model.notification.NotificationModel.create')
961 'rhodecode.model.notification.NotificationModel.create')
957 self.notification_patcher.start()
962 self.notification_patcher.start()
958
963
959 if not self.pull_request:
964 if not self.pull_request:
960 if not commits:
965 if not commits:
961 commits = [
966 commits = [
962 {'message': 'c1'},
967 {'message': 'c1'},
963 {'message': 'c2'},
968 {'message': 'c2'},
964 {'message': 'c3'},
969 {'message': 'c3'},
965 ]
970 ]
966 target_head = 'c1'
971 target_head = 'c1'
967 source_head = 'c2'
972 source_head = 'c2'
968 revisions = ['c2']
973 revisions = ['c2']
969
974
970 self.commit_ids = self.backend.create_master_repo(commits)
975 self.commit_ids = self.backend.create_master_repo(commits)
971 self.target_repository = self.backend.create_repo(
976 self.target_repository = self.backend.create_repo(
972 heads=[target_head], name_suffix=name_suffix)
977 heads=[target_head], name_suffix=name_suffix)
973 self.source_repository = self.backend.create_repo(
978 self.source_repository = self.backend.create_repo(
974 heads=[source_head], name_suffix=name_suffix)
979 heads=[source_head], name_suffix=name_suffix)
975 self.author = author or UserModel().get_by_username(
980 self.author = author or UserModel().get_by_username(
976 TEST_USER_ADMIN_LOGIN)
981 TEST_USER_ADMIN_LOGIN)
977
982
978 model = PullRequestModel()
983 model = PullRequestModel()
979 self.create_parameters = {
984 self.create_parameters = {
980 'created_by': self.author,
985 'created_by': self.author,
981 'source_repo': self.source_repository.repo_name,
986 'source_repo': self.source_repository.repo_name,
982 'source_ref': self._default_branch_reference(source_head),
987 'source_ref': self._default_branch_reference(source_head),
983 'target_repo': self.target_repository.repo_name,
988 'target_repo': self.target_repository.repo_name,
984 'target_ref': self._default_branch_reference(target_head),
989 'target_ref': self._default_branch_reference(target_head),
985 'revisions': [self.commit_ids[r] for r in revisions],
990 'revisions': [self.commit_ids[r] for r in revisions],
986 'reviewers': reviewers or self._get_reviewers(),
991 'reviewers': reviewers or self._get_reviewers(),
987 'title': title,
992 'title': title,
988 'description': description,
993 'description': description,
989 }
994 }
990 self.pull_request = model.create(**self.create_parameters)
995 self.pull_request = model.create(**self.create_parameters)
991 assert model.get_versions(self.pull_request) == []
996 assert model.get_versions(self.pull_request) == []
992
997
993 self.pull_request_id = self.pull_request.pull_request_id
998 self.pull_request_id = self.pull_request.pull_request_id
994
999
995 if approved:
1000 if approved:
996 self.approve()
1001 self.approve()
997
1002
998 Session().add(self.pull_request)
1003 Session().add(self.pull_request)
999 Session().commit()
1004 Session().commit()
1000
1005
1001 return self.pull_request
1006 return self.pull_request
1002
1007
1003 def approve(self):
1008 def approve(self):
1004 self.create_status_votes(
1009 self.create_status_votes(
1005 ChangesetStatus.STATUS_APPROVED,
1010 ChangesetStatus.STATUS_APPROVED,
1006 *self.pull_request.reviewers)
1011 *self.pull_request.reviewers)
1007
1012
1008 def close(self):
1013 def close(self):
1009 PullRequestModel().close_pull_request(self.pull_request, self.author)
1014 PullRequestModel().close_pull_request(self.pull_request, self.author)
1010
1015
1011 def _default_branch_reference(self, commit_message):
1016 def _default_branch_reference(self, commit_message):
1012 reference = '%s:%s:%s' % (
1017 reference = '%s:%s:%s' % (
1013 'branch',
1018 'branch',
1014 self.backend.default_branch_name,
1019 self.backend.default_branch_name,
1015 self.commit_ids[commit_message])
1020 self.commit_ids[commit_message])
1016 return reference
1021 return reference
1017
1022
1018 def _get_reviewers(self):
1023 def _get_reviewers(self):
1019 return [
1024 return [
1020 (TEST_USER_REGULAR_LOGIN, ['default1'], False, []),
1025 (TEST_USER_REGULAR_LOGIN, ['default1'], False, []),
1021 (TEST_USER_REGULAR2_LOGIN, ['default2'], False, []),
1026 (TEST_USER_REGULAR2_LOGIN, ['default2'], False, []),
1022 ]
1027 ]
1023
1028
1024 def update_source_repository(self, head=None):
1029 def update_source_repository(self, head=None):
1025 heads = [head or 'c3']
1030 heads = [head or 'c3']
1026 self.backend.pull_heads(self.source_repository, heads=heads)
1031 self.backend.pull_heads(self.source_repository, heads=heads)
1027
1032
1028 def add_one_commit(self, head=None):
1033 def add_one_commit(self, head=None):
1029 self.update_source_repository(head=head)
1034 self.update_source_repository(head=head)
1030 old_commit_ids = set(self.pull_request.revisions)
1035 old_commit_ids = set(self.pull_request.revisions)
1031 PullRequestModel().update_commits(self.pull_request)
1036 PullRequestModel().update_commits(self.pull_request)
1032 commit_ids = set(self.pull_request.revisions)
1037 commit_ids = set(self.pull_request.revisions)
1033 new_commit_ids = commit_ids - old_commit_ids
1038 new_commit_ids = commit_ids - old_commit_ids
1034 assert len(new_commit_ids) == 1
1039 assert len(new_commit_ids) == 1
1035 return new_commit_ids.pop()
1040 return new_commit_ids.pop()
1036
1041
1037 def remove_one_commit(self):
1042 def remove_one_commit(self):
1038 assert len(self.pull_request.revisions) == 2
1043 assert len(self.pull_request.revisions) == 2
1039 source_vcs = self.source_repository.scm_instance()
1044 source_vcs = self.source_repository.scm_instance()
1040 removed_commit_id = source_vcs.commit_ids[-1]
1045 removed_commit_id = source_vcs.commit_ids[-1]
1041
1046
1042 # TODO: johbo: Git and Mercurial have an inconsistent vcs api here,
1047 # TODO: johbo: Git and Mercurial have an inconsistent vcs api here,
1043 # remove the if once that's sorted out.
1048 # remove the if once that's sorted out.
1044 if self.backend.alias == "git":
1049 if self.backend.alias == "git":
1045 kwargs = {'branch_name': self.backend.default_branch_name}
1050 kwargs = {'branch_name': self.backend.default_branch_name}
1046 else:
1051 else:
1047 kwargs = {}
1052 kwargs = {}
1048 source_vcs.strip(removed_commit_id, **kwargs)
1053 source_vcs.strip(removed_commit_id, **kwargs)
1049
1054
1050 PullRequestModel().update_commits(self.pull_request)
1055 PullRequestModel().update_commits(self.pull_request)
1051 assert len(self.pull_request.revisions) == 1
1056 assert len(self.pull_request.revisions) == 1
1052 return removed_commit_id
1057 return removed_commit_id
1053
1058
1054 def create_comment(self, linked_to=None):
1059 def create_comment(self, linked_to=None):
1055 comment = CommentsModel().create(
1060 comment = CommentsModel().create(
1056 text=u"Test comment",
1061 text=u"Test comment",
1057 repo=self.target_repository.repo_name,
1062 repo=self.target_repository.repo_name,
1058 user=self.author,
1063 user=self.author,
1059 pull_request=self.pull_request)
1064 pull_request=self.pull_request)
1060 assert comment.pull_request_version_id is None
1065 assert comment.pull_request_version_id is None
1061
1066
1062 if linked_to:
1067 if linked_to:
1063 PullRequestModel()._link_comments_to_version(linked_to)
1068 PullRequestModel()._link_comments_to_version(linked_to)
1064
1069
1065 return comment
1070 return comment
1066
1071
1067 def create_inline_comment(
1072 def create_inline_comment(
1068 self, linked_to=None, line_no=u'n1', file_path='file_1'):
1073 self, linked_to=None, line_no=u'n1', file_path='file_1'):
1069 comment = CommentsModel().create(
1074 comment = CommentsModel().create(
1070 text=u"Test comment",
1075 text=u"Test comment",
1071 repo=self.target_repository.repo_name,
1076 repo=self.target_repository.repo_name,
1072 user=self.author,
1077 user=self.author,
1073 line_no=line_no,
1078 line_no=line_no,
1074 f_path=file_path,
1079 f_path=file_path,
1075 pull_request=self.pull_request)
1080 pull_request=self.pull_request)
1076 assert comment.pull_request_version_id is None
1081 assert comment.pull_request_version_id is None
1077
1082
1078 if linked_to:
1083 if linked_to:
1079 PullRequestModel()._link_comments_to_version(linked_to)
1084 PullRequestModel()._link_comments_to_version(linked_to)
1080
1085
1081 return comment
1086 return comment
1082
1087
1083 def create_version_of_pull_request(self):
1088 def create_version_of_pull_request(self):
1084 pull_request = self.create_pull_request()
1089 pull_request = self.create_pull_request()
1085 version = PullRequestModel()._create_version_from_snapshot(
1090 version = PullRequestModel()._create_version_from_snapshot(
1086 pull_request)
1091 pull_request)
1087 return version
1092 return version
1088
1093
1089 def create_status_votes(self, status, *reviewers):
1094 def create_status_votes(self, status, *reviewers):
1090 for reviewer in reviewers:
1095 for reviewer in reviewers:
1091 ChangesetStatusModel().set_status(
1096 ChangesetStatusModel().set_status(
1092 repo=self.pull_request.target_repo,
1097 repo=self.pull_request.target_repo,
1093 status=status,
1098 status=status,
1094 user=reviewer.user_id,
1099 user=reviewer.user_id,
1095 pull_request=self.pull_request)
1100 pull_request=self.pull_request)
1096
1101
1097 def set_mergeable(self, value):
1102 def set_mergeable(self, value):
1098 if not self.mergeable_patcher:
1103 if not self.mergeable_patcher:
1099 self.mergeable_patcher = mock.patch.object(
1104 self.mergeable_patcher = mock.patch.object(
1100 VcsSettingsModel, 'get_general_settings')
1105 VcsSettingsModel, 'get_general_settings')
1101 self.mergeable_mock = self.mergeable_patcher.start()
1106 self.mergeable_mock = self.mergeable_patcher.start()
1102 self.mergeable_mock.return_value = {
1107 self.mergeable_mock.return_value = {
1103 'rhodecode_pr_merge_enabled': value}
1108 'rhodecode_pr_merge_enabled': value}
1104
1109
1105 def cleanup(self):
1110 def cleanup(self):
1106 # In case the source repository is already cleaned up, the pull
1111 # In case the source repository is already cleaned up, the pull
1107 # request will already be deleted.
1112 # request will already be deleted.
1108 pull_request = PullRequest().get(self.pull_request_id)
1113 pull_request = PullRequest().get(self.pull_request_id)
1109 if pull_request:
1114 if pull_request:
1110 PullRequestModel().delete(pull_request, pull_request.author)
1115 PullRequestModel().delete(pull_request, pull_request.author)
1111 Session().commit()
1116 Session().commit()
1112
1117
1113 if self.notification_patcher:
1118 if self.notification_patcher:
1114 self.notification_patcher.stop()
1119 self.notification_patcher.stop()
1115
1120
1116 if self.mergeable_patcher:
1121 if self.mergeable_patcher:
1117 self.mergeable_patcher.stop()
1122 self.mergeable_patcher.stop()
1118
1123
1119
1124
1120 @pytest.fixture()
1125 @pytest.fixture()
1121 def user_admin(baseapp):
1126 def user_admin(baseapp):
1122 """
1127 """
1123 Provides the default admin test user as an instance of `db.User`.
1128 Provides the default admin test user as an instance of `db.User`.
1124 """
1129 """
1125 user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
1130 user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN)
1126 return user
1131 return user
1127
1132
1128
1133
1129 @pytest.fixture()
1134 @pytest.fixture()
1130 def user_regular(baseapp):
1135 def user_regular(baseapp):
1131 """
1136 """
1132 Provides the default regular test user as an instance of `db.User`.
1137 Provides the default regular test user as an instance of `db.User`.
1133 """
1138 """
1134 user = UserModel().get_by_username(TEST_USER_REGULAR_LOGIN)
1139 user = UserModel().get_by_username(TEST_USER_REGULAR_LOGIN)
1135 return user
1140 return user
1136
1141
1137
1142
1138 @pytest.fixture()
1143 @pytest.fixture()
1139 def user_util(request, db_connection):
1144 def user_util(request, db_connection):
1140 """
1145 """
1141 Provides a wired instance of `UserUtility` with integrated cleanup.
1146 Provides a wired instance of `UserUtility` with integrated cleanup.
1142 """
1147 """
1143 utility = UserUtility(test_name=request.node.name)
1148 utility = UserUtility(test_name=request.node.name)
1144 request.addfinalizer(utility.cleanup)
1149 request.addfinalizer(utility.cleanup)
1145 return utility
1150 return utility
1146
1151
1147
1152
1148 # TODO: johbo: Split this up into utilities per domain or something similar
1153 # TODO: johbo: Split this up into utilities per domain or something similar
1149 class UserUtility(object):
1154 class UserUtility(object):
1150
1155
1151 def __init__(self, test_name="test"):
1156 def __init__(self, test_name="test"):
1152 self._test_name = self._sanitize_name(test_name)
1157 self._test_name = self._sanitize_name(test_name)
1153 self.fixture = Fixture()
1158 self.fixture = Fixture()
1154 self.repo_group_ids = []
1159 self.repo_group_ids = []
1155 self.repos_ids = []
1160 self.repos_ids = []
1156 self.user_ids = []
1161 self.user_ids = []
1157 self.user_group_ids = []
1162 self.user_group_ids = []
1158 self.user_repo_permission_ids = []
1163 self.user_repo_permission_ids = []
1159 self.user_group_repo_permission_ids = []
1164 self.user_group_repo_permission_ids = []
1160 self.user_repo_group_permission_ids = []
1165 self.user_repo_group_permission_ids = []
1161 self.user_group_repo_group_permission_ids = []
1166 self.user_group_repo_group_permission_ids = []
1162 self.user_user_group_permission_ids = []
1167 self.user_user_group_permission_ids = []
1163 self.user_group_user_group_permission_ids = []
1168 self.user_group_user_group_permission_ids = []
1164 self.user_permissions = []
1169 self.user_permissions = []
1165
1170
1166 def _sanitize_name(self, name):
1171 def _sanitize_name(self, name):
1167 for char in ['[', ']']:
1172 for char in ['[', ']']:
1168 name = name.replace(char, '_')
1173 name = name.replace(char, '_')
1169 return name
1174 return name
1170
1175
1171 def create_repo_group(
1176 def create_repo_group(
1172 self, owner=TEST_USER_ADMIN_LOGIN, auto_cleanup=True):
1177 self, owner=TEST_USER_ADMIN_LOGIN, auto_cleanup=True):
1173 group_name = "{prefix}_repogroup_{count}".format(
1178 group_name = "{prefix}_repogroup_{count}".format(
1174 prefix=self._test_name,
1179 prefix=self._test_name,
1175 count=len(self.repo_group_ids))
1180 count=len(self.repo_group_ids))
1176 repo_group = self.fixture.create_repo_group(
1181 repo_group = self.fixture.create_repo_group(
1177 group_name, cur_user=owner)
1182 group_name, cur_user=owner)
1178 if auto_cleanup:
1183 if auto_cleanup:
1179 self.repo_group_ids.append(repo_group.group_id)
1184 self.repo_group_ids.append(repo_group.group_id)
1180 return repo_group
1185 return repo_group
1181
1186
1182 def create_repo(self, owner=TEST_USER_ADMIN_LOGIN, parent=None,
1187 def create_repo(self, owner=TEST_USER_ADMIN_LOGIN, parent=None,
1183 auto_cleanup=True, repo_type='hg', bare=False):
1188 auto_cleanup=True, repo_type='hg', bare=False):
1184 repo_name = "{prefix}_repository_{count}".format(
1189 repo_name = "{prefix}_repository_{count}".format(
1185 prefix=self._test_name,
1190 prefix=self._test_name,
1186 count=len(self.repos_ids))
1191 count=len(self.repos_ids))
1187
1192
1188 repository = self.fixture.create_repo(
1193 repository = self.fixture.create_repo(
1189 repo_name, cur_user=owner, repo_group=parent, repo_type=repo_type, bare=bare)
1194 repo_name, cur_user=owner, repo_group=parent, repo_type=repo_type, bare=bare)
1190 if auto_cleanup:
1195 if auto_cleanup:
1191 self.repos_ids.append(repository.repo_id)
1196 self.repos_ids.append(repository.repo_id)
1192 return repository
1197 return repository
1193
1198
1194 def create_user(self, auto_cleanup=True, **kwargs):
1199 def create_user(self, auto_cleanup=True, **kwargs):
1195 user_name = "{prefix}_user_{count}".format(
1200 user_name = "{prefix}_user_{count}".format(
1196 prefix=self._test_name,
1201 prefix=self._test_name,
1197 count=len(self.user_ids))
1202 count=len(self.user_ids))
1198 user = self.fixture.create_user(user_name, **kwargs)
1203 user = self.fixture.create_user(user_name, **kwargs)
1199 if auto_cleanup:
1204 if auto_cleanup:
1200 self.user_ids.append(user.user_id)
1205 self.user_ids.append(user.user_id)
1201 return user
1206 return user
1202
1207
1203 def create_additional_user_email(self, user, email):
1208 def create_additional_user_email(self, user, email):
1204 uem = self.fixture.create_additional_user_email(user=user, email=email)
1209 uem = self.fixture.create_additional_user_email(user=user, email=email)
1205 return uem
1210 return uem
1206
1211
1207 def create_user_with_group(self):
1212 def create_user_with_group(self):
1208 user = self.create_user()
1213 user = self.create_user()
1209 user_group = self.create_user_group(members=[user])
1214 user_group = self.create_user_group(members=[user])
1210 return user, user_group
1215 return user, user_group
1211
1216
1212 def create_user_group(self, owner=TEST_USER_ADMIN_LOGIN, members=None,
1217 def create_user_group(self, owner=TEST_USER_ADMIN_LOGIN, members=None,
1213 auto_cleanup=True, **kwargs):
1218 auto_cleanup=True, **kwargs):
1214 group_name = "{prefix}_usergroup_{count}".format(
1219 group_name = "{prefix}_usergroup_{count}".format(
1215 prefix=self._test_name,
1220 prefix=self._test_name,
1216 count=len(self.user_group_ids))
1221 count=len(self.user_group_ids))
1217 user_group = self.fixture.create_user_group(
1222 user_group = self.fixture.create_user_group(
1218 group_name, cur_user=owner, **kwargs)
1223 group_name, cur_user=owner, **kwargs)
1219
1224
1220 if auto_cleanup:
1225 if auto_cleanup:
1221 self.user_group_ids.append(user_group.users_group_id)
1226 self.user_group_ids.append(user_group.users_group_id)
1222 if members:
1227 if members:
1223 for user in members:
1228 for user in members:
1224 UserGroupModel().add_user_to_group(user_group, user)
1229 UserGroupModel().add_user_to_group(user_group, user)
1225 return user_group
1230 return user_group
1226
1231
1227 def grant_user_permission(self, user_name, permission_name):
1232 def grant_user_permission(self, user_name, permission_name):
1228 self.inherit_default_user_permissions(user_name, False)
1233 self.inherit_default_user_permissions(user_name, False)
1229 self.user_permissions.append((user_name, permission_name))
1234 self.user_permissions.append((user_name, permission_name))
1230
1235
1231 def grant_user_permission_to_repo_group(
1236 def grant_user_permission_to_repo_group(
1232 self, repo_group, user, permission_name):
1237 self, repo_group, user, permission_name):
1233 permission = RepoGroupModel().grant_user_permission(
1238 permission = RepoGroupModel().grant_user_permission(
1234 repo_group, user, permission_name)
1239 repo_group, user, permission_name)
1235 self.user_repo_group_permission_ids.append(
1240 self.user_repo_group_permission_ids.append(
1236 (repo_group.group_id, user.user_id))
1241 (repo_group.group_id, user.user_id))
1237 return permission
1242 return permission
1238
1243
1239 def grant_user_group_permission_to_repo_group(
1244 def grant_user_group_permission_to_repo_group(
1240 self, repo_group, user_group, permission_name):
1245 self, repo_group, user_group, permission_name):
1241 permission = RepoGroupModel().grant_user_group_permission(
1246 permission = RepoGroupModel().grant_user_group_permission(
1242 repo_group, user_group, permission_name)
1247 repo_group, user_group, permission_name)
1243 self.user_group_repo_group_permission_ids.append(
1248 self.user_group_repo_group_permission_ids.append(
1244 (repo_group.group_id, user_group.users_group_id))
1249 (repo_group.group_id, user_group.users_group_id))
1245 return permission
1250 return permission
1246
1251
1247 def grant_user_permission_to_repo(
1252 def grant_user_permission_to_repo(
1248 self, repo, user, permission_name):
1253 self, repo, user, permission_name):
1249 permission = RepoModel().grant_user_permission(
1254 permission = RepoModel().grant_user_permission(
1250 repo, user, permission_name)
1255 repo, user, permission_name)
1251 self.user_repo_permission_ids.append(
1256 self.user_repo_permission_ids.append(
1252 (repo.repo_id, user.user_id))
1257 (repo.repo_id, user.user_id))
1253 return permission
1258 return permission
1254
1259
1255 def grant_user_group_permission_to_repo(
1260 def grant_user_group_permission_to_repo(
1256 self, repo, user_group, permission_name):
1261 self, repo, user_group, permission_name):
1257 permission = RepoModel().grant_user_group_permission(
1262 permission = RepoModel().grant_user_group_permission(
1258 repo, user_group, permission_name)
1263 repo, user_group, permission_name)
1259 self.user_group_repo_permission_ids.append(
1264 self.user_group_repo_permission_ids.append(
1260 (repo.repo_id, user_group.users_group_id))
1265 (repo.repo_id, user_group.users_group_id))
1261 return permission
1266 return permission
1262
1267
1263 def grant_user_permission_to_user_group(
1268 def grant_user_permission_to_user_group(
1264 self, target_user_group, user, permission_name):
1269 self, target_user_group, user, permission_name):
1265 permission = UserGroupModel().grant_user_permission(
1270 permission = UserGroupModel().grant_user_permission(
1266 target_user_group, user, permission_name)
1271 target_user_group, user, permission_name)
1267 self.user_user_group_permission_ids.append(
1272 self.user_user_group_permission_ids.append(
1268 (target_user_group.users_group_id, user.user_id))
1273 (target_user_group.users_group_id, user.user_id))
1269 return permission
1274 return permission
1270
1275
1271 def grant_user_group_permission_to_user_group(
1276 def grant_user_group_permission_to_user_group(
1272 self, target_user_group, user_group, permission_name):
1277 self, target_user_group, user_group, permission_name):
1273 permission = UserGroupModel().grant_user_group_permission(
1278 permission = UserGroupModel().grant_user_group_permission(
1274 target_user_group, user_group, permission_name)
1279 target_user_group, user_group, permission_name)
1275 self.user_group_user_group_permission_ids.append(
1280 self.user_group_user_group_permission_ids.append(
1276 (target_user_group.users_group_id, user_group.users_group_id))
1281 (target_user_group.users_group_id, user_group.users_group_id))
1277 return permission
1282 return permission
1278
1283
1279 def revoke_user_permission(self, user_name, permission_name):
1284 def revoke_user_permission(self, user_name, permission_name):
1280 self.inherit_default_user_permissions(user_name, True)
1285 self.inherit_default_user_permissions(user_name, True)
1281 UserModel().revoke_perm(user_name, permission_name)
1286 UserModel().revoke_perm(user_name, permission_name)
1282
1287
1283 def inherit_default_user_permissions(self, user_name, value):
1288 def inherit_default_user_permissions(self, user_name, value):
1284 user = UserModel().get_by_username(user_name)
1289 user = UserModel().get_by_username(user_name)
1285 user.inherit_default_permissions = value
1290 user.inherit_default_permissions = value
1286 Session().add(user)
1291 Session().add(user)
1287 Session().commit()
1292 Session().commit()
1288
1293
1289 def cleanup(self):
1294 def cleanup(self):
1290 self._cleanup_permissions()
1295 self._cleanup_permissions()
1291 self._cleanup_repos()
1296 self._cleanup_repos()
1292 self._cleanup_repo_groups()
1297 self._cleanup_repo_groups()
1293 self._cleanup_user_groups()
1298 self._cleanup_user_groups()
1294 self._cleanup_users()
1299 self._cleanup_users()
1295
1300
1296 def _cleanup_permissions(self):
1301 def _cleanup_permissions(self):
1297 if self.user_permissions:
1302 if self.user_permissions:
1298 for user_name, permission_name in self.user_permissions:
1303 for user_name, permission_name in self.user_permissions:
1299 self.revoke_user_permission(user_name, permission_name)
1304 self.revoke_user_permission(user_name, permission_name)
1300
1305
1301 for permission in self.user_repo_permission_ids:
1306 for permission in self.user_repo_permission_ids:
1302 RepoModel().revoke_user_permission(*permission)
1307 RepoModel().revoke_user_permission(*permission)
1303
1308
1304 for permission in self.user_group_repo_permission_ids:
1309 for permission in self.user_group_repo_permission_ids:
1305 RepoModel().revoke_user_group_permission(*permission)
1310 RepoModel().revoke_user_group_permission(*permission)
1306
1311
1307 for permission in self.user_repo_group_permission_ids:
1312 for permission in self.user_repo_group_permission_ids:
1308 RepoGroupModel().revoke_user_permission(*permission)
1313 RepoGroupModel().revoke_user_permission(*permission)
1309
1314
1310 for permission in self.user_group_repo_group_permission_ids:
1315 for permission in self.user_group_repo_group_permission_ids:
1311 RepoGroupModel().revoke_user_group_permission(*permission)
1316 RepoGroupModel().revoke_user_group_permission(*permission)
1312
1317
1313 for permission in self.user_user_group_permission_ids:
1318 for permission in self.user_user_group_permission_ids:
1314 UserGroupModel().revoke_user_permission(*permission)
1319 UserGroupModel().revoke_user_permission(*permission)
1315
1320
1316 for permission in self.user_group_user_group_permission_ids:
1321 for permission in self.user_group_user_group_permission_ids:
1317 UserGroupModel().revoke_user_group_permission(*permission)
1322 UserGroupModel().revoke_user_group_permission(*permission)
1318
1323
1319 def _cleanup_repo_groups(self):
1324 def _cleanup_repo_groups(self):
1320 def _repo_group_compare(first_group_id, second_group_id):
1325 def _repo_group_compare(first_group_id, second_group_id):
1321 """
1326 """
1322 Gives higher priority to the groups with the most complex paths
1327 Gives higher priority to the groups with the most complex paths
1323 """
1328 """
1324 first_group = RepoGroup.get(first_group_id)
1329 first_group = RepoGroup.get(first_group_id)
1325 second_group = RepoGroup.get(second_group_id)
1330 second_group = RepoGroup.get(second_group_id)
1326 first_group_parts = (
1331 first_group_parts = (
1327 len(first_group.group_name.split('/')) if first_group else 0)
1332 len(first_group.group_name.split('/')) if first_group else 0)
1328 second_group_parts = (
1333 second_group_parts = (
1329 len(second_group.group_name.split('/')) if second_group else 0)
1334 len(second_group.group_name.split('/')) if second_group else 0)
1330 return cmp(second_group_parts, first_group_parts)
1335 return cmp(second_group_parts, first_group_parts)
1331
1336
1332 sorted_repo_group_ids = sorted(
1337 sorted_repo_group_ids = sorted(
1333 self.repo_group_ids, cmp=_repo_group_compare)
1338 self.repo_group_ids, cmp=_repo_group_compare)
1334 for repo_group_id in sorted_repo_group_ids:
1339 for repo_group_id in sorted_repo_group_ids:
1335 self.fixture.destroy_repo_group(repo_group_id)
1340 self.fixture.destroy_repo_group(repo_group_id)
1336
1341
1337 def _cleanup_repos(self):
1342 def _cleanup_repos(self):
1338 sorted_repos_ids = sorted(self.repos_ids)
1343 sorted_repos_ids = sorted(self.repos_ids)
1339 for repo_id in sorted_repos_ids:
1344 for repo_id in sorted_repos_ids:
1340 self.fixture.destroy_repo(repo_id)
1345 self.fixture.destroy_repo(repo_id)
1341
1346
1342 def _cleanup_user_groups(self):
1347 def _cleanup_user_groups(self):
1343 def _user_group_compare(first_group_id, second_group_id):
1348 def _user_group_compare(first_group_id, second_group_id):
1344 """
1349 """
1345 Gives higher priority to the groups with the most complex paths
1350 Gives higher priority to the groups with the most complex paths
1346 """
1351 """
1347 first_group = UserGroup.get(first_group_id)
1352 first_group = UserGroup.get(first_group_id)
1348 second_group = UserGroup.get(second_group_id)
1353 second_group = UserGroup.get(second_group_id)
1349 first_group_parts = (
1354 first_group_parts = (
1350 len(first_group.users_group_name.split('/'))
1355 len(first_group.users_group_name.split('/'))
1351 if first_group else 0)
1356 if first_group else 0)
1352 second_group_parts = (
1357 second_group_parts = (
1353 len(second_group.users_group_name.split('/'))
1358 len(second_group.users_group_name.split('/'))
1354 if second_group else 0)
1359 if second_group else 0)
1355 return cmp(second_group_parts, first_group_parts)
1360 return cmp(second_group_parts, first_group_parts)
1356
1361
1357 sorted_user_group_ids = sorted(
1362 sorted_user_group_ids = sorted(
1358 self.user_group_ids, cmp=_user_group_compare)
1363 self.user_group_ids, cmp=_user_group_compare)
1359 for user_group_id in sorted_user_group_ids:
1364 for user_group_id in sorted_user_group_ids:
1360 self.fixture.destroy_user_group(user_group_id)
1365 self.fixture.destroy_user_group(user_group_id)
1361
1366
1362 def _cleanup_users(self):
1367 def _cleanup_users(self):
1363 for user_id in self.user_ids:
1368 for user_id in self.user_ids:
1364 self.fixture.destroy_user(user_id)
1369 self.fixture.destroy_user(user_id)
1365
1370
1366
1371
1367 # TODO: Think about moving this into a pytest-pyro package and make it a
1372 # TODO: Think about moving this into a pytest-pyro package and make it a
1368 # pytest plugin
1373 # pytest plugin
1369 @pytest.hookimpl(tryfirst=True, hookwrapper=True)
1374 @pytest.hookimpl(tryfirst=True, hookwrapper=True)
1370 def pytest_runtest_makereport(item, call):
1375 def pytest_runtest_makereport(item, call):
1371 """
1376 """
1372 Adding the remote traceback if the exception has this information.
1377 Adding the remote traceback if the exception has this information.
1373
1378
1374 VCSServer attaches this information as the attribute `_vcs_server_traceback`
1379 VCSServer attaches this information as the attribute `_vcs_server_traceback`
1375 to the exception instance.
1380 to the exception instance.
1376 """
1381 """
1377 outcome = yield
1382 outcome = yield
1378 report = outcome.get_result()
1383 report = outcome.get_result()
1379 if call.excinfo:
1384 if call.excinfo:
1380 _add_vcsserver_remote_traceback(report, call.excinfo.value)
1385 _add_vcsserver_remote_traceback(report, call.excinfo.value)
1381
1386
1382
1387
1383 def _add_vcsserver_remote_traceback(report, exc):
1388 def _add_vcsserver_remote_traceback(report, exc):
1384 vcsserver_traceback = getattr(exc, '_vcs_server_traceback', None)
1389 vcsserver_traceback = getattr(exc, '_vcs_server_traceback', None)
1385
1390
1386 if vcsserver_traceback:
1391 if vcsserver_traceback:
1387 section = 'VCSServer remote traceback ' + report.when
1392 section = 'VCSServer remote traceback ' + report.when
1388 report.sections.append((section, vcsserver_traceback))
1393 report.sections.append((section, vcsserver_traceback))
1389
1394
1390
1395
1391 @pytest.fixture(scope='session')
1396 @pytest.fixture(scope='session')
1392 def testrun():
1397 def testrun():
1393 return {
1398 return {
1394 'uuid': uuid.uuid4(),
1399 'uuid': uuid.uuid4(),
1395 'start': datetime.datetime.utcnow().isoformat(),
1400 'start': datetime.datetime.utcnow().isoformat(),
1396 'timestamp': int(time.time()),
1401 'timestamp': int(time.time()),
1397 }
1402 }
1398
1403
1399
1404
1400 class AppenlightClient(object):
1405 class AppenlightClient(object):
1401
1406
1402 url_template = '{url}?protocol_version=0.5'
1407 url_template = '{url}?protocol_version=0.5'
1403
1408
1404 def __init__(
1409 def __init__(
1405 self, url, api_key, add_server=True, add_timestamp=True,
1410 self, url, api_key, add_server=True, add_timestamp=True,
1406 namespace=None, request=None, testrun=None):
1411 namespace=None, request=None, testrun=None):
1407 self.url = self.url_template.format(url=url)
1412 self.url = self.url_template.format(url=url)
1408 self.api_key = api_key
1413 self.api_key = api_key
1409 self.add_server = add_server
1414 self.add_server = add_server
1410 self.add_timestamp = add_timestamp
1415 self.add_timestamp = add_timestamp
1411 self.namespace = namespace
1416 self.namespace = namespace
1412 self.request = request
1417 self.request = request
1413 self.server = socket.getfqdn(socket.gethostname())
1418 self.server = socket.getfqdn(socket.gethostname())
1414 self.tags_before = {}
1419 self.tags_before = {}
1415 self.tags_after = {}
1420 self.tags_after = {}
1416 self.stats = []
1421 self.stats = []
1417 self.testrun = testrun or {}
1422 self.testrun = testrun or {}
1418
1423
1419 def tag_before(self, tag, value):
1424 def tag_before(self, tag, value):
1420 self.tags_before[tag] = value
1425 self.tags_before[tag] = value
1421
1426
1422 def tag_after(self, tag, value):
1427 def tag_after(self, tag, value):
1423 self.tags_after[tag] = value
1428 self.tags_after[tag] = value
1424
1429
1425 def collect(self, data):
1430 def collect(self, data):
1426 if self.add_server:
1431 if self.add_server:
1427 data.setdefault('server', self.server)
1432 data.setdefault('server', self.server)
1428 if self.add_timestamp:
1433 if self.add_timestamp:
1429 data.setdefault('date', datetime.datetime.utcnow().isoformat())
1434 data.setdefault('date', datetime.datetime.utcnow().isoformat())
1430 if self.namespace:
1435 if self.namespace:
1431 data.setdefault('namespace', self.namespace)
1436 data.setdefault('namespace', self.namespace)
1432 if self.request:
1437 if self.request:
1433 data.setdefault('request', self.request)
1438 data.setdefault('request', self.request)
1434 self.stats.append(data)
1439 self.stats.append(data)
1435
1440
1436 def send_stats(self):
1441 def send_stats(self):
1437 tags = [
1442 tags = [
1438 ('testrun', self.request),
1443 ('testrun', self.request),
1439 ('testrun.start', self.testrun['start']),
1444 ('testrun.start', self.testrun['start']),
1440 ('testrun.timestamp', self.testrun['timestamp']),
1445 ('testrun.timestamp', self.testrun['timestamp']),
1441 ('test', self.namespace),
1446 ('test', self.namespace),
1442 ]
1447 ]
1443 for key, value in self.tags_before.items():
1448 for key, value in self.tags_before.items():
1444 tags.append((key + '.before', value))
1449 tags.append((key + '.before', value))
1445 try:
1450 try:
1446 delta = self.tags_after[key] - value
1451 delta = self.tags_after[key] - value
1447 tags.append((key + '.delta', delta))
1452 tags.append((key + '.delta', delta))
1448 except Exception:
1453 except Exception:
1449 pass
1454 pass
1450 for key, value in self.tags_after.items():
1455 for key, value in self.tags_after.items():
1451 tags.append((key + '.after', value))
1456 tags.append((key + '.after', value))
1452 self.collect({
1457 self.collect({
1453 'message': "Collected tags",
1458 'message': "Collected tags",
1454 'tags': tags,
1459 'tags': tags,
1455 })
1460 })
1456
1461
1457 response = requests.post(
1462 response = requests.post(
1458 self.url,
1463 self.url,
1459 headers={
1464 headers={
1460 'X-appenlight-api-key': self.api_key},
1465 'X-appenlight-api-key': self.api_key},
1461 json=self.stats,
1466 json=self.stats,
1462 )
1467 )
1463
1468
1464 if not response.status_code == 200:
1469 if not response.status_code == 200:
1465 pprint.pprint(self.stats)
1470 pprint.pprint(self.stats)
1466 print(response.headers)
1471 print(response.headers)
1467 print(response.text)
1472 print(response.text)
1468 raise Exception('Sending to appenlight failed')
1473 raise Exception('Sending to appenlight failed')
1469
1474
1470
1475
1471 @pytest.fixture()
1476 @pytest.fixture()
1472 def gist_util(request, db_connection):
1477 def gist_util(request, db_connection):
1473 """
1478 """
1474 Provides a wired instance of `GistUtility` with integrated cleanup.
1479 Provides a wired instance of `GistUtility` with integrated cleanup.
1475 """
1480 """
1476 utility = GistUtility()
1481 utility = GistUtility()
1477 request.addfinalizer(utility.cleanup)
1482 request.addfinalizer(utility.cleanup)
1478 return utility
1483 return utility
1479
1484
1480
1485
1481 class GistUtility(object):
1486 class GistUtility(object):
1482 def __init__(self):
1487 def __init__(self):
1483 self.fixture = Fixture()
1488 self.fixture = Fixture()
1484 self.gist_ids = []
1489 self.gist_ids = []
1485
1490
1486 def create_gist(self, **kwargs):
1491 def create_gist(self, **kwargs):
1487 gist = self.fixture.create_gist(**kwargs)
1492 gist = self.fixture.create_gist(**kwargs)
1488 self.gist_ids.append(gist.gist_id)
1493 self.gist_ids.append(gist.gist_id)
1489 return gist
1494 return gist
1490
1495
1491 def cleanup(self):
1496 def cleanup(self):
1492 for id_ in self.gist_ids:
1497 for id_ in self.gist_ids:
1493 self.fixture.destroy_gists(str(id_))
1498 self.fixture.destroy_gists(str(id_))
1494
1499
1495
1500
1496 @pytest.fixture()
1501 @pytest.fixture()
1497 def enabled_backends(request):
1502 def enabled_backends(request):
1498 backends = request.config.option.backends
1503 backends = request.config.option.backends
1499 return backends[:]
1504 return backends[:]
1500
1505
1501
1506
1502 @pytest.fixture()
1507 @pytest.fixture()
1503 def settings_util(request, db_connection):
1508 def settings_util(request, db_connection):
1504 """
1509 """
1505 Provides a wired instance of `SettingsUtility` with integrated cleanup.
1510 Provides a wired instance of `SettingsUtility` with integrated cleanup.
1506 """
1511 """
1507 utility = SettingsUtility()
1512 utility = SettingsUtility()
1508 request.addfinalizer(utility.cleanup)
1513 request.addfinalizer(utility.cleanup)
1509 return utility
1514 return utility
1510
1515
1511
1516
1512 class SettingsUtility(object):
1517 class SettingsUtility(object):
1513 def __init__(self):
1518 def __init__(self):
1514 self.rhodecode_ui_ids = []
1519 self.rhodecode_ui_ids = []
1515 self.rhodecode_setting_ids = []
1520 self.rhodecode_setting_ids = []
1516 self.repo_rhodecode_ui_ids = []
1521 self.repo_rhodecode_ui_ids = []
1517 self.repo_rhodecode_setting_ids = []
1522 self.repo_rhodecode_setting_ids = []
1518
1523
1519 def create_repo_rhodecode_ui(
1524 def create_repo_rhodecode_ui(
1520 self, repo, section, value, key=None, active=True, cleanup=True):
1525 self, repo, section, value, key=None, active=True, cleanup=True):
1521 key = key or hashlib.sha1(
1526 key = key or hashlib.sha1(
1522 '{}{}{}'.format(section, value, repo.repo_id)).hexdigest()
1527 '{}{}{}'.format(section, value, repo.repo_id)).hexdigest()
1523
1528
1524 setting = RepoRhodeCodeUi()
1529 setting = RepoRhodeCodeUi()
1525 setting.repository_id = repo.repo_id
1530 setting.repository_id = repo.repo_id
1526 setting.ui_section = section
1531 setting.ui_section = section
1527 setting.ui_value = value
1532 setting.ui_value = value
1528 setting.ui_key = key
1533 setting.ui_key = key
1529 setting.ui_active = active
1534 setting.ui_active = active
1530 Session().add(setting)
1535 Session().add(setting)
1531 Session().commit()
1536 Session().commit()
1532
1537
1533 if cleanup:
1538 if cleanup:
1534 self.repo_rhodecode_ui_ids.append(setting.ui_id)
1539 self.repo_rhodecode_ui_ids.append(setting.ui_id)
1535 return setting
1540 return setting
1536
1541
1537 def create_rhodecode_ui(
1542 def create_rhodecode_ui(
1538 self, section, value, key=None, active=True, cleanup=True):
1543 self, section, value, key=None, active=True, cleanup=True):
1539 key = key or hashlib.sha1('{}{}'.format(section, value)).hexdigest()
1544 key = key or hashlib.sha1('{}{}'.format(section, value)).hexdigest()
1540
1545
1541 setting = RhodeCodeUi()
1546 setting = RhodeCodeUi()
1542 setting.ui_section = section
1547 setting.ui_section = section
1543 setting.ui_value = value
1548 setting.ui_value = value
1544 setting.ui_key = key
1549 setting.ui_key = key
1545 setting.ui_active = active
1550 setting.ui_active = active
1546 Session().add(setting)
1551 Session().add(setting)
1547 Session().commit()
1552 Session().commit()
1548
1553
1549 if cleanup:
1554 if cleanup:
1550 self.rhodecode_ui_ids.append(setting.ui_id)
1555 self.rhodecode_ui_ids.append(setting.ui_id)
1551 return setting
1556 return setting
1552
1557
1553 def create_repo_rhodecode_setting(
1558 def create_repo_rhodecode_setting(
1554 self, repo, name, value, type_, cleanup=True):
1559 self, repo, name, value, type_, cleanup=True):
1555 setting = RepoRhodeCodeSetting(
1560 setting = RepoRhodeCodeSetting(
1556 repo.repo_id, key=name, val=value, type=type_)
1561 repo.repo_id, key=name, val=value, type=type_)
1557 Session().add(setting)
1562 Session().add(setting)
1558 Session().commit()
1563 Session().commit()
1559
1564
1560 if cleanup:
1565 if cleanup:
1561 self.repo_rhodecode_setting_ids.append(setting.app_settings_id)
1566 self.repo_rhodecode_setting_ids.append(setting.app_settings_id)
1562 return setting
1567 return setting
1563
1568
1564 def create_rhodecode_setting(self, name, value, type_, cleanup=True):
1569 def create_rhodecode_setting(self, name, value, type_, cleanup=True):
1565 setting = RhodeCodeSetting(key=name, val=value, type=type_)
1570 setting = RhodeCodeSetting(key=name, val=value, type=type_)
1566 Session().add(setting)
1571 Session().add(setting)
1567 Session().commit()
1572 Session().commit()
1568
1573
1569 if cleanup:
1574 if cleanup:
1570 self.rhodecode_setting_ids.append(setting.app_settings_id)
1575 self.rhodecode_setting_ids.append(setting.app_settings_id)
1571
1576
1572 return setting
1577 return setting
1573
1578
1574 def cleanup(self):
1579 def cleanup(self):
1575 for id_ in self.rhodecode_ui_ids:
1580 for id_ in self.rhodecode_ui_ids:
1576 setting = RhodeCodeUi.get(id_)
1581 setting = RhodeCodeUi.get(id_)
1577 Session().delete(setting)
1582 Session().delete(setting)
1578
1583
1579 for id_ in self.rhodecode_setting_ids:
1584 for id_ in self.rhodecode_setting_ids:
1580 setting = RhodeCodeSetting.get(id_)
1585 setting = RhodeCodeSetting.get(id_)
1581 Session().delete(setting)
1586 Session().delete(setting)
1582
1587
1583 for id_ in self.repo_rhodecode_ui_ids:
1588 for id_ in self.repo_rhodecode_ui_ids:
1584 setting = RepoRhodeCodeUi.get(id_)
1589 setting = RepoRhodeCodeUi.get(id_)
1585 Session().delete(setting)
1590 Session().delete(setting)
1586
1591
1587 for id_ in self.repo_rhodecode_setting_ids:
1592 for id_ in self.repo_rhodecode_setting_ids:
1588 setting = RepoRhodeCodeSetting.get(id_)
1593 setting = RepoRhodeCodeSetting.get(id_)
1589 Session().delete(setting)
1594 Session().delete(setting)
1590
1595
1591 Session().commit()
1596 Session().commit()
1592
1597
1593
1598
1594 @pytest.fixture()
1599 @pytest.fixture()
1595 def no_notifications(request):
1600 def no_notifications(request):
1596 notification_patcher = mock.patch(
1601 notification_patcher = mock.patch(
1597 'rhodecode.model.notification.NotificationModel.create')
1602 'rhodecode.model.notification.NotificationModel.create')
1598 notification_patcher.start()
1603 notification_patcher.start()
1599 request.addfinalizer(notification_patcher.stop)
1604 request.addfinalizer(notification_patcher.stop)
1600
1605
1601
1606
1602 @pytest.fixture(scope='session')
1607 @pytest.fixture(scope='session')
1603 def repeat(request):
1608 def repeat(request):
1604 """
1609 """
1605 The number of repetitions is based on this fixture.
1610 The number of repetitions is based on this fixture.
1606
1611
1607 Slower calls may divide it by 10 or 100. It is chosen in a way so that the
1612 Slower calls may divide it by 10 or 100. It is chosen in a way so that the
1608 tests are not too slow in our default test suite.
1613 tests are not too slow in our default test suite.
1609 """
1614 """
1610 return request.config.getoption('--repeat')
1615 return request.config.getoption('--repeat')
1611
1616
1612
1617
1613 @pytest.fixture()
1618 @pytest.fixture()
1614 def rhodecode_fixtures():
1619 def rhodecode_fixtures():
1615 return Fixture()
1620 return Fixture()
1616
1621
1617
1622
1618 @pytest.fixture()
1623 @pytest.fixture()
1619 def context_stub():
1624 def context_stub():
1620 """
1625 """
1621 Stub context object.
1626 Stub context object.
1622 """
1627 """
1623 context = pyramid.testing.DummyResource()
1628 context = pyramid.testing.DummyResource()
1624 return context
1629 return context
1625
1630
1626
1631
1627 @pytest.fixture()
1632 @pytest.fixture()
1628 def request_stub():
1633 def request_stub():
1629 """
1634 """
1630 Stub request object.
1635 Stub request object.
1631 """
1636 """
1632 from rhodecode.lib.base import bootstrap_request
1637 from rhodecode.lib.base import bootstrap_request
1633 request = bootstrap_request(scheme='https')
1638 request = bootstrap_request(scheme='https')
1634 return request
1639 return request
1635
1640
1636
1641
1637 @pytest.fixture()
1642 @pytest.fixture()
1638 def config_stub(request, request_stub):
1643 def config_stub(request, request_stub):
1639 """
1644 """
1640 Set up pyramid.testing and return the Configurator.
1645 Set up pyramid.testing and return the Configurator.
1641 """
1646 """
1642 from rhodecode.lib.base import bootstrap_config
1647 from rhodecode.lib.base import bootstrap_config
1643 config = bootstrap_config(request=request_stub)
1648 config = bootstrap_config(request=request_stub)
1644
1649
1645 @request.addfinalizer
1650 @request.addfinalizer
1646 def cleanup():
1651 def cleanup():
1647 pyramid.testing.tearDown()
1652 pyramid.testing.tearDown()
1648
1653
1649 return config
1654 return config
1650
1655
1651
1656
1652 @pytest.fixture()
1657 @pytest.fixture()
1653 def StubIntegrationType():
1658 def StubIntegrationType():
1654 class _StubIntegrationType(IntegrationTypeBase):
1659 class _StubIntegrationType(IntegrationTypeBase):
1655 """ Test integration type class """
1660 """ Test integration type class """
1656
1661
1657 key = 'test'
1662 key = 'test'
1658 display_name = 'Test integration type'
1663 display_name = 'Test integration type'
1659 description = 'A test integration type for testing'
1664 description = 'A test integration type for testing'
1660
1665
1661 @classmethod
1666 @classmethod
1662 def icon(cls):
1667 def icon(cls):
1663 return 'test_icon_html_image'
1668 return 'test_icon_html_image'
1664
1669
1665 def __init__(self, settings):
1670 def __init__(self, settings):
1666 super(_StubIntegrationType, self).__init__(settings)
1671 super(_StubIntegrationType, self).__init__(settings)
1667 self.sent_events = [] # for testing
1672 self.sent_events = [] # for testing
1668
1673
1669 def send_event(self, event):
1674 def send_event(self, event):
1670 self.sent_events.append(event)
1675 self.sent_events.append(event)
1671
1676
1672 def settings_schema(self):
1677 def settings_schema(self):
1673 class SettingsSchema(colander.Schema):
1678 class SettingsSchema(colander.Schema):
1674 test_string_field = colander.SchemaNode(
1679 test_string_field = colander.SchemaNode(
1675 colander.String(),
1680 colander.String(),
1676 missing=colander.required,
1681 missing=colander.required,
1677 title='test string field',
1682 title='test string field',
1678 )
1683 )
1679 test_int_field = colander.SchemaNode(
1684 test_int_field = colander.SchemaNode(
1680 colander.Int(),
1685 colander.Int(),
1681 title='some integer setting',
1686 title='some integer setting',
1682 )
1687 )
1683 return SettingsSchema()
1688 return SettingsSchema()
1684
1689
1685
1690
1686 integration_type_registry.register_integration_type(_StubIntegrationType)
1691 integration_type_registry.register_integration_type(_StubIntegrationType)
1687 return _StubIntegrationType
1692 return _StubIntegrationType
1688
1693
1689 @pytest.fixture()
1694 @pytest.fixture()
1690 def stub_integration_settings():
1695 def stub_integration_settings():
1691 return {
1696 return {
1692 'test_string_field': 'some data',
1697 'test_string_field': 'some data',
1693 'test_int_field': 100,
1698 'test_int_field': 100,
1694 }
1699 }
1695
1700
1696
1701
1697 @pytest.fixture()
1702 @pytest.fixture()
1698 def repo_integration_stub(request, repo_stub, StubIntegrationType,
1703 def repo_integration_stub(request, repo_stub, StubIntegrationType,
1699 stub_integration_settings):
1704 stub_integration_settings):
1700 integration = IntegrationModel().create(
1705 integration = IntegrationModel().create(
1701 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1706 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1702 name='test repo integration',
1707 name='test repo integration',
1703 repo=repo_stub, repo_group=None, child_repos_only=None)
1708 repo=repo_stub, repo_group=None, child_repos_only=None)
1704
1709
1705 @request.addfinalizer
1710 @request.addfinalizer
1706 def cleanup():
1711 def cleanup():
1707 IntegrationModel().delete(integration)
1712 IntegrationModel().delete(integration)
1708
1713
1709 return integration
1714 return integration
1710
1715
1711
1716
1712 @pytest.fixture()
1717 @pytest.fixture()
1713 def repogroup_integration_stub(request, test_repo_group, StubIntegrationType,
1718 def repogroup_integration_stub(request, test_repo_group, StubIntegrationType,
1714 stub_integration_settings):
1719 stub_integration_settings):
1715 integration = IntegrationModel().create(
1720 integration = IntegrationModel().create(
1716 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1721 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1717 name='test repogroup integration',
1722 name='test repogroup integration',
1718 repo=None, repo_group=test_repo_group, child_repos_only=True)
1723 repo=None, repo_group=test_repo_group, child_repos_only=True)
1719
1724
1720 @request.addfinalizer
1725 @request.addfinalizer
1721 def cleanup():
1726 def cleanup():
1722 IntegrationModel().delete(integration)
1727 IntegrationModel().delete(integration)
1723
1728
1724 return integration
1729 return integration
1725
1730
1726
1731
1727 @pytest.fixture()
1732 @pytest.fixture()
1728 def repogroup_recursive_integration_stub(request, test_repo_group,
1733 def repogroup_recursive_integration_stub(request, test_repo_group,
1729 StubIntegrationType, stub_integration_settings):
1734 StubIntegrationType, stub_integration_settings):
1730 integration = IntegrationModel().create(
1735 integration = IntegrationModel().create(
1731 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1736 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1732 name='test recursive repogroup integration',
1737 name='test recursive repogroup integration',
1733 repo=None, repo_group=test_repo_group, child_repos_only=False)
1738 repo=None, repo_group=test_repo_group, child_repos_only=False)
1734
1739
1735 @request.addfinalizer
1740 @request.addfinalizer
1736 def cleanup():
1741 def cleanup():
1737 IntegrationModel().delete(integration)
1742 IntegrationModel().delete(integration)
1738
1743
1739 return integration
1744 return integration
1740
1745
1741
1746
1742 @pytest.fixture()
1747 @pytest.fixture()
1743 def global_integration_stub(request, StubIntegrationType,
1748 def global_integration_stub(request, StubIntegrationType,
1744 stub_integration_settings):
1749 stub_integration_settings):
1745 integration = IntegrationModel().create(
1750 integration = IntegrationModel().create(
1746 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1751 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1747 name='test global integration',
1752 name='test global integration',
1748 repo=None, repo_group=None, child_repos_only=None)
1753 repo=None, repo_group=None, child_repos_only=None)
1749
1754
1750 @request.addfinalizer
1755 @request.addfinalizer
1751 def cleanup():
1756 def cleanup():
1752 IntegrationModel().delete(integration)
1757 IntegrationModel().delete(integration)
1753
1758
1754 return integration
1759 return integration
1755
1760
1756
1761
1757 @pytest.fixture()
1762 @pytest.fixture()
1758 def root_repos_integration_stub(request, StubIntegrationType,
1763 def root_repos_integration_stub(request, StubIntegrationType,
1759 stub_integration_settings):
1764 stub_integration_settings):
1760 integration = IntegrationModel().create(
1765 integration = IntegrationModel().create(
1761 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1766 StubIntegrationType, settings=stub_integration_settings, enabled=True,
1762 name='test global integration',
1767 name='test global integration',
1763 repo=None, repo_group=None, child_repos_only=True)
1768 repo=None, repo_group=None, child_repos_only=True)
1764
1769
1765 @request.addfinalizer
1770 @request.addfinalizer
1766 def cleanup():
1771 def cleanup():
1767 IntegrationModel().delete(integration)
1772 IntegrationModel().delete(integration)
1768
1773
1769 return integration
1774 return integration
1770
1775
1771
1776
1772 @pytest.fixture()
1777 @pytest.fixture()
1773 def local_dt_to_utc():
1778 def local_dt_to_utc():
1774 def _factory(dt):
1779 def _factory(dt):
1775 return dt.replace(tzinfo=dateutil.tz.tzlocal()).astimezone(
1780 return dt.replace(tzinfo=dateutil.tz.tzlocal()).astimezone(
1776 dateutil.tz.tzutc()).replace(tzinfo=None)
1781 dateutil.tz.tzutc()).replace(tzinfo=None)
1777 return _factory
1782 return _factory
1778
1783
1779
1784
1780 @pytest.fixture()
1785 @pytest.fixture()
1781 def disable_anonymous_user(request, baseapp):
1786 def disable_anonymous_user(request, baseapp):
1782 set_anonymous_access(False)
1787 set_anonymous_access(False)
1783
1788
1784 @request.addfinalizer
1789 @request.addfinalizer
1785 def cleanup():
1790 def cleanup():
1786 set_anonymous_access(True)
1791 set_anonymous_access(True)
1787
1792
1788
1793
1789 @pytest.fixture(scope='module')
1794 @pytest.fixture(scope='module')
1790 def rc_fixture(request):
1795 def rc_fixture(request):
1791 return Fixture()
1796 return Fixture()
1792
1797
1793
1798
1794 @pytest.fixture()
1799 @pytest.fixture()
1795 def repo_groups(request):
1800 def repo_groups(request):
1796 fixture = Fixture()
1801 fixture = Fixture()
1797
1802
1798 session = Session()
1803 session = Session()
1799 zombie_group = fixture.create_repo_group('zombie')
1804 zombie_group = fixture.create_repo_group('zombie')
1800 parent_group = fixture.create_repo_group('parent')
1805 parent_group = fixture.create_repo_group('parent')
1801 child_group = fixture.create_repo_group('parent/child')
1806 child_group = fixture.create_repo_group('parent/child')
1802 groups_in_db = session.query(RepoGroup).all()
1807 groups_in_db = session.query(RepoGroup).all()
1803 assert len(groups_in_db) == 3
1808 assert len(groups_in_db) == 3
1804 assert child_group.group_parent_id == parent_group.group_id
1809 assert child_group.group_parent_id == parent_group.group_id
1805
1810
1806 @request.addfinalizer
1811 @request.addfinalizer
1807 def cleanup():
1812 def cleanup():
1808 fixture.destroy_repo_group(zombie_group)
1813 fixture.destroy_repo_group(zombie_group)
1809 fixture.destroy_repo_group(child_group)
1814 fixture.destroy_repo_group(child_group)
1810 fixture.destroy_repo_group(parent_group)
1815 fixture.destroy_repo_group(parent_group)
1811
1816
1812 return zombie_group, parent_group, child_group
1817 return zombie_group, parent_group, child_group
1813
1814
1815 @pytest.fixture(scope="session")
1816 def tmp_path_factory(request):
1817 """Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session.
1818 """
1819
1820 class TempPathFactory:
1821
1822 def mktemp(self, basename):
1823 import tempfile
1824 return tempfile.mktemp(basename)
1825
1826 return TempPathFactory()
@@ -1,1274 +1,1274 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2019 RhodeCode GmbH
3 # Copyright (C) 2010-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
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 Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import datetime
21 import datetime
22 import mock
22 import mock
23 import os
23 import os
24 import sys
24 import sys
25 import shutil
25 import shutil
26
26
27 import pytest
27 import pytest
28
28
29 from rhodecode.lib.utils import make_db_config
29 from rhodecode.lib.utils import make_db_config
30 from rhodecode.lib.vcs.backends.base import Reference
30 from rhodecode.lib.vcs.backends.base import Reference
31 from rhodecode.lib.vcs.backends.git import (
31 from rhodecode.lib.vcs.backends.git import (
32 GitRepository, GitCommit, discover_git_version)
32 GitRepository, GitCommit, discover_git_version)
33 from rhodecode.lib.vcs.exceptions import (
33 from rhodecode.lib.vcs.exceptions import (
34 RepositoryError, VCSError, NodeDoesNotExistError)
34 RepositoryError, VCSError, NodeDoesNotExistError)
35 from rhodecode.lib.vcs.nodes import (
35 from rhodecode.lib.vcs.nodes import (
36 NodeKind, FileNode, DirNode, NodeState, SubModuleNode)
36 NodeKind, FileNode, DirNode, NodeState, SubModuleNode)
37 from rhodecode.tests import TEST_GIT_REPO, TEST_GIT_REPO_CLONE, get_new_dir
37 from rhodecode.tests import TEST_GIT_REPO, TEST_GIT_REPO_CLONE, get_new_dir
38 from rhodecode.tests.vcs.conftest import BackendTestMixin
38 from rhodecode.tests.vcs.conftest import BackendTestMixin
39
39
40
40
41 pytestmark = pytest.mark.backends("git")
41 pytestmark = pytest.mark.backends("git")
42
42
43
43
44 class TestGitRepository(object):
44 class TestGitRepository(object):
45
45
46 @pytest.fixture(autouse=True)
46 @pytest.fixture(autouse=True)
47 def prepare(self, request, baseapp):
47 def prepare(self, request, baseapp):
48 self.repo = GitRepository(TEST_GIT_REPO, bare=True)
48 self.repo = GitRepository(TEST_GIT_REPO, bare=True)
49 self.repo.count()
49 self.repo.count()
50
50
51 def get_clone_repo(self, tmp_path_factory):
51 def get_clone_repo(self, tmpdir):
52 """
52 """
53 Return a non bare clone of the base repo.
53 Return a non bare clone of the base repo.
54 """
54 """
55 clone_path = tmp_path_factory.mktemp('clone-url')
55 clone_path = str(tmpdir.join('clone-repo'))
56 repo_clone = GitRepository(
56 repo_clone = GitRepository(
57 clone_path, create=True, src_url=self.repo.path, bare=False)
57 clone_path, create=True, src_url=self.repo.path, bare=False)
58
58
59 return repo_clone
59 return repo_clone
60
60
61 def get_empty_repo(self, tmp_path_factory, bare=False):
61 def get_empty_repo(self, tmpdir, bare=False):
62 """
62 """
63 Return a non bare empty repo.
63 Return a non bare empty repo.
64 """
64 """
65 clone_path = tmp_path_factory.mktemp('empty-repo')
65 clone_path = str(tmpdir.join('empty-repo'))
66 return GitRepository(clone_path, create=True, bare=bare)
66 return GitRepository(clone_path, create=True, bare=bare)
67
67
68 def test_wrong_repo_path(self):
68 def test_wrong_repo_path(self):
69 wrong_repo_path = '/tmp/errorrepo_git'
69 wrong_repo_path = '/tmp/errorrepo_git'
70 with pytest.raises(RepositoryError):
70 with pytest.raises(RepositoryError):
71 GitRepository(wrong_repo_path)
71 GitRepository(wrong_repo_path)
72
72
73 def test_repo_clone(self, tmp_path_factory):
73 def test_repo_clone(self, tmp_path_factory):
74 repo = GitRepository(TEST_GIT_REPO)
74 repo = GitRepository(TEST_GIT_REPO)
75 clone_path = tmp_path_factory.mktemp('_') + '_' + TEST_GIT_REPO_CLONE
75 clone_path = '{}_{}'.format(tmp_path_factory.mktemp('_'), TEST_GIT_REPO_CLONE)
76 repo_clone = GitRepository(
76 repo_clone = GitRepository(
77 clone_path,
77 clone_path,
78 src_url=TEST_GIT_REPO, create=True, do_workspace_checkout=True)
78 src_url=TEST_GIT_REPO, create=True, do_workspace_checkout=True)
79
79
80 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
80 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
81 # Checking hashes of commits should be enough
81 # Checking hashes of commits should be enough
82 for commit in repo.get_commits():
82 for commit in repo.get_commits():
83 raw_id = commit.raw_id
83 raw_id = commit.raw_id
84 assert raw_id == repo_clone.get_commit(raw_id).raw_id
84 assert raw_id == repo_clone.get_commit(raw_id).raw_id
85
85
86 def test_repo_clone_without_create(self):
86 def test_repo_clone_without_create(self):
87 with pytest.raises(RepositoryError):
87 with pytest.raises(RepositoryError):
88 GitRepository(
88 GitRepository(
89 TEST_GIT_REPO_CLONE + '_wo_create', src_url=TEST_GIT_REPO)
89 TEST_GIT_REPO_CLONE + '_wo_create', src_url=TEST_GIT_REPO)
90
90
91 def test_repo_clone_with_update(self, tmp_path_factory):
91 def test_repo_clone_with_update(self, tmp_path_factory):
92 repo = GitRepository(TEST_GIT_REPO)
92 repo = GitRepository(TEST_GIT_REPO)
93 clone_path = tmp_path_factory.mktemp('_') + '_' + TEST_GIT_REPO_CLONE + '_update'
93 clone_path = '{}_{}_update'.format(tmp_path_factory.mktemp('_'), TEST_GIT_REPO_CLONE)
94
94
95 repo_clone = GitRepository(
95 repo_clone = GitRepository(
96 clone_path,
96 clone_path,
97 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=True)
97 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=True)
98 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
98 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
99
99
100 # check if current workdir was updated
100 # check if current workdir was updated
101 fpath = os.path.join(clone_path, 'MANIFEST.in')
101 fpath = os.path.join(clone_path, 'MANIFEST.in')
102 assert os.path.isfile(fpath)
102 assert os.path.isfile(fpath)
103
103
104 def test_repo_clone_without_update(self, tmp_path_factory):
104 def test_repo_clone_without_update(self, tmp_path_factory):
105 repo = GitRepository(TEST_GIT_REPO)
105 repo = GitRepository(TEST_GIT_REPO)
106 clone_path = tmp_path_factory.mktemp('_') + '_' + TEST_GIT_REPO_CLONE + '_without_update'
106 clone_path = '{}_{}_without_update'.format(tmp_path_factory.mktemp('_'), TEST_GIT_REPO_CLONE)
107 repo_clone = GitRepository(
107 repo_clone = GitRepository(
108 clone_path,
108 clone_path,
109 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=False)
109 create=True, src_url=TEST_GIT_REPO, do_workspace_checkout=False)
110 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
110 assert len(repo.commit_ids) == len(repo_clone.commit_ids)
111 # check if current workdir was *NOT* updated
111 # check if current workdir was *NOT* updated
112 fpath = os.path.join(clone_path, 'MANIFEST.in')
112 fpath = os.path.join(clone_path, 'MANIFEST.in')
113 # Make sure it's not bare repo
113 # Make sure it's not bare repo
114 assert not repo_clone.bare
114 assert not repo_clone.bare
115 assert not os.path.isfile(fpath)
115 assert not os.path.isfile(fpath)
116
116
117 def test_repo_clone_into_bare_repo(self, tmp_path_factory):
117 def test_repo_clone_into_bare_repo(self, tmp_path_factory):
118 repo = GitRepository(TEST_GIT_REPO)
118 repo = GitRepository(TEST_GIT_REPO)
119 clone_path = tmp_path_factory.mktemp('_') + '_' + TEST_GIT_REPO_CLONE + '_bare.git'
119 clone_path = '{}_{}_bare.git'.format(tmp_path_factory.mktemp('_'), TEST_GIT_REPO_CLONE)
120 repo_clone = GitRepository(
120 repo_clone = GitRepository(
121 clone_path, create=True, src_url=repo.path, bare=True)
121 clone_path, create=True, src_url=repo.path, bare=True)
122 assert repo_clone.bare
122 assert repo_clone.bare
123
123
124 def test_create_repo_is_not_bare_by_default(self):
124 def test_create_repo_is_not_bare_by_default(self):
125 repo = GitRepository(get_new_dir('not-bare-by-default'), create=True)
125 repo = GitRepository(get_new_dir('not-bare-by-default'), create=True)
126 assert not repo.bare
126 assert not repo.bare
127
127
128 def test_create_bare_repo(self):
128 def test_create_bare_repo(self):
129 repo = GitRepository(get_new_dir('bare-repo'), create=True, bare=True)
129 repo = GitRepository(get_new_dir('bare-repo'), create=True, bare=True)
130 assert repo.bare
130 assert repo.bare
131
131
132 def test_update_server_info(self):
132 def test_update_server_info(self):
133 self.repo._update_server_info()
133 self.repo._update_server_info()
134
134
135 def test_fetch(self, vcsbackend_git):
135 def test_fetch(self, vcsbackend_git):
136 # Note: This is a git specific part of the API, it's only implemented
136 # Note: This is a git specific part of the API, it's only implemented
137 # by the git backend.
137 # by the git backend.
138 source_repo = vcsbackend_git.repo
138 source_repo = vcsbackend_git.repo
139 target_repo = vcsbackend_git.create_repo(bare=True)
139 target_repo = vcsbackend_git.create_repo(bare=True)
140 target_repo.fetch(source_repo.path)
140 target_repo.fetch(source_repo.path)
141 # Note: Get a fresh instance, avoids caching trouble
141 # Note: Get a fresh instance, avoids caching trouble
142 target_repo = vcsbackend_git.backend(target_repo.path)
142 target_repo = vcsbackend_git.backend(target_repo.path)
143 assert len(source_repo.commit_ids) == len(target_repo.commit_ids)
143 assert len(source_repo.commit_ids) == len(target_repo.commit_ids)
144
144
145 def test_commit_ids(self):
145 def test_commit_ids(self):
146 # there are 112 commits (by now)
146 # there are 112 commits (by now)
147 # so we can assume they would be available from now on
147 # so we can assume they would be available from now on
148 subset = {'c1214f7e79e02fc37156ff215cd71275450cffc3',
148 subset = {'c1214f7e79e02fc37156ff215cd71275450cffc3',
149 '38b5fe81f109cb111f549bfe9bb6b267e10bc557',
149 '38b5fe81f109cb111f549bfe9bb6b267e10bc557',
150 'fa6600f6848800641328adbf7811fd2372c02ab2',
150 'fa6600f6848800641328adbf7811fd2372c02ab2',
151 '102607b09cdd60e2793929c4f90478be29f85a17',
151 '102607b09cdd60e2793929c4f90478be29f85a17',
152 '49d3fd156b6f7db46313fac355dca1a0b94a0017',
152 '49d3fd156b6f7db46313fac355dca1a0b94a0017',
153 '2d1028c054665b962fa3d307adfc923ddd528038',
153 '2d1028c054665b962fa3d307adfc923ddd528038',
154 'd7e0d30fbcae12c90680eb095a4f5f02505ce501',
154 'd7e0d30fbcae12c90680eb095a4f5f02505ce501',
155 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
155 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
156 'dd80b0f6cf5052f17cc738c2951c4f2070200d7f',
156 'dd80b0f6cf5052f17cc738c2951c4f2070200d7f',
157 '8430a588b43b5d6da365400117c89400326e7992',
157 '8430a588b43b5d6da365400117c89400326e7992',
158 'd955cd312c17b02143c04fa1099a352b04368118',
158 'd955cd312c17b02143c04fa1099a352b04368118',
159 'f67b87e5c629c2ee0ba58f85197e423ff28d735b',
159 'f67b87e5c629c2ee0ba58f85197e423ff28d735b',
160 'add63e382e4aabc9e1afdc4bdc24506c269b7618',
160 'add63e382e4aabc9e1afdc4bdc24506c269b7618',
161 'f298fe1189f1b69779a4423f40b48edf92a703fc',
161 'f298fe1189f1b69779a4423f40b48edf92a703fc',
162 'bd9b619eb41994cac43d67cf4ccc8399c1125808',
162 'bd9b619eb41994cac43d67cf4ccc8399c1125808',
163 '6e125e7c890379446e98980d8ed60fba87d0f6d1',
163 '6e125e7c890379446e98980d8ed60fba87d0f6d1',
164 'd4a54db9f745dfeba6933bf5b1e79e15d0af20bd',
164 'd4a54db9f745dfeba6933bf5b1e79e15d0af20bd',
165 '0b05e4ed56c802098dfc813cbe779b2f49e92500',
165 '0b05e4ed56c802098dfc813cbe779b2f49e92500',
166 '191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
166 '191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
167 '45223f8f114c64bf4d6f853e3c35a369a6305520',
167 '45223f8f114c64bf4d6f853e3c35a369a6305520',
168 'ca1eb7957a54bce53b12d1a51b13452f95bc7c7e',
168 'ca1eb7957a54bce53b12d1a51b13452f95bc7c7e',
169 'f5ea29fc42ef67a2a5a7aecff10e1566699acd68',
169 'f5ea29fc42ef67a2a5a7aecff10e1566699acd68',
170 '27d48942240f5b91dfda77accd2caac94708cc7d',
170 '27d48942240f5b91dfda77accd2caac94708cc7d',
171 '622f0eb0bafd619d2560c26f80f09e3b0b0d78af',
171 '622f0eb0bafd619d2560c26f80f09e3b0b0d78af',
172 'e686b958768ee96af8029fe19c6050b1a8dd3b2b'}
172 'e686b958768ee96af8029fe19c6050b1a8dd3b2b'}
173 assert subset.issubset(set(self.repo.commit_ids))
173 assert subset.issubset(set(self.repo.commit_ids))
174
174
175 def test_slicing(self):
175 def test_slicing(self):
176 # 4 1 5 10 95
176 # 4 1 5 10 95
177 for sfrom, sto, size in [(0, 4, 4), (1, 2, 1), (10, 15, 5),
177 for sfrom, sto, size in [(0, 4, 4), (1, 2, 1), (10, 15, 5),
178 (10, 20, 10), (5, 100, 95)]:
178 (10, 20, 10), (5, 100, 95)]:
179 commit_ids = list(self.repo[sfrom:sto])
179 commit_ids = list(self.repo[sfrom:sto])
180 assert len(commit_ids) == size
180 assert len(commit_ids) == size
181 assert commit_ids[0] == self.repo.get_commit(commit_idx=sfrom)
181 assert commit_ids[0] == self.repo.get_commit(commit_idx=sfrom)
182 assert commit_ids[-1] == self.repo.get_commit(commit_idx=sto - 1)
182 assert commit_ids[-1] == self.repo.get_commit(commit_idx=sto - 1)
183
183
184 def test_branches(self):
184 def test_branches(self):
185 # TODO: Need more tests here
185 # TODO: Need more tests here
186 # Removed (those are 'remotes' branches for cloned repo)
186 # Removed (those are 'remotes' branches for cloned repo)
187 # assert 'master' in self.repo.branches
187 # assert 'master' in self.repo.branches
188 # assert 'gittree' in self.repo.branches
188 # assert 'gittree' in self.repo.branches
189 # assert 'web-branch' in self.repo.branches
189 # assert 'web-branch' in self.repo.branches
190 for __, commit_id in self.repo.branches.items():
190 for __, commit_id in self.repo.branches.items():
191 assert isinstance(self.repo.get_commit(commit_id), GitCommit)
191 assert isinstance(self.repo.get_commit(commit_id), GitCommit)
192
192
193 def test_tags(self):
193 def test_tags(self):
194 # TODO: Need more tests here
194 # TODO: Need more tests here
195 assert 'v0.1.1' in self.repo.tags
195 assert 'v0.1.1' in self.repo.tags
196 assert 'v0.1.2' in self.repo.tags
196 assert 'v0.1.2' in self.repo.tags
197 for __, commit_id in self.repo.tags.items():
197 for __, commit_id in self.repo.tags.items():
198 assert isinstance(self.repo.get_commit(commit_id), GitCommit)
198 assert isinstance(self.repo.get_commit(commit_id), GitCommit)
199
199
200 def _test_single_commit_cache(self, commit_id):
200 def _test_single_commit_cache(self, commit_id):
201 commit = self.repo.get_commit(commit_id)
201 commit = self.repo.get_commit(commit_id)
202 assert commit_id in self.repo.commits
202 assert commit_id in self.repo.commits
203 assert commit is self.repo.commits[commit_id]
203 assert commit is self.repo.commits[commit_id]
204
204
205 def test_initial_commit(self):
205 def test_initial_commit(self):
206 commit_id = self.repo.commit_ids[0]
206 commit_id = self.repo.commit_ids[0]
207 init_commit = self.repo.get_commit(commit_id)
207 init_commit = self.repo.get_commit(commit_id)
208 init_author = init_commit.author
208 init_author = init_commit.author
209
209
210 assert init_commit.message == 'initial import\n'
210 assert init_commit.message == 'initial import\n'
211 assert init_author == 'Marcin Kuzminski <marcin@python-blog.com>'
211 assert init_author == 'Marcin Kuzminski <marcin@python-blog.com>'
212 assert init_author == init_commit.committer
212 assert init_author == init_commit.committer
213 for path in ('vcs/__init__.py',
213 for path in ('vcs/__init__.py',
214 'vcs/backends/BaseRepository.py',
214 'vcs/backends/BaseRepository.py',
215 'vcs/backends/__init__.py'):
215 'vcs/backends/__init__.py'):
216 assert isinstance(init_commit.get_node(path), FileNode)
216 assert isinstance(init_commit.get_node(path), FileNode)
217 for path in ('', 'vcs', 'vcs/backends'):
217 for path in ('', 'vcs', 'vcs/backends'):
218 assert isinstance(init_commit.get_node(path), DirNode)
218 assert isinstance(init_commit.get_node(path), DirNode)
219
219
220 with pytest.raises(NodeDoesNotExistError):
220 with pytest.raises(NodeDoesNotExistError):
221 init_commit.get_node(path='foobar')
221 init_commit.get_node(path='foobar')
222
222
223 node = init_commit.get_node('vcs/')
223 node = init_commit.get_node('vcs/')
224 assert hasattr(node, 'kind')
224 assert hasattr(node, 'kind')
225 assert node.kind == NodeKind.DIR
225 assert node.kind == NodeKind.DIR
226
226
227 node = init_commit.get_node('vcs')
227 node = init_commit.get_node('vcs')
228 assert hasattr(node, 'kind')
228 assert hasattr(node, 'kind')
229 assert node.kind == NodeKind.DIR
229 assert node.kind == NodeKind.DIR
230
230
231 node = init_commit.get_node('vcs/__init__.py')
231 node = init_commit.get_node('vcs/__init__.py')
232 assert hasattr(node, 'kind')
232 assert hasattr(node, 'kind')
233 assert node.kind == NodeKind.FILE
233 assert node.kind == NodeKind.FILE
234
234
235 def test_not_existing_commit(self):
235 def test_not_existing_commit(self):
236 with pytest.raises(RepositoryError):
236 with pytest.raises(RepositoryError):
237 self.repo.get_commit('f' * 40)
237 self.repo.get_commit('f' * 40)
238
238
239 def test_commit10(self):
239 def test_commit10(self):
240
240
241 commit10 = self.repo.get_commit(self.repo.commit_ids[9])
241 commit10 = self.repo.get_commit(self.repo.commit_ids[9])
242 README = """===
242 README = """===
243 VCS
243 VCS
244 ===
244 ===
245
245
246 Various Version Control System management abstraction layer for Python.
246 Various Version Control System management abstraction layer for Python.
247
247
248 Introduction
248 Introduction
249 ------------
249 ------------
250
250
251 TODO: To be written...
251 TODO: To be written...
252
252
253 """
253 """
254 node = commit10.get_node('README.rst')
254 node = commit10.get_node('README.rst')
255 assert node.kind == NodeKind.FILE
255 assert node.kind == NodeKind.FILE
256 assert node.content == README
256 assert node.content == README
257
257
258 def test_head(self):
258 def test_head(self):
259 assert self.repo.head == self.repo.get_commit().raw_id
259 assert self.repo.head == self.repo.get_commit().raw_id
260
260
261 def test_checkout_with_create(self, tmp_path_factory):
261 def test_checkout_with_create(self, tmpdir):
262 repo_clone = self.get_clone_repo(tmp_path_factory)
262 repo_clone = self.get_clone_repo(tmpdir)
263
263
264 new_branch = 'new_branch'
264 new_branch = 'new_branch'
265 assert repo_clone._current_branch() == 'master'
265 assert repo_clone._current_branch() == 'master'
266 assert set(repo_clone.branches) == {'master'}
266 assert set(repo_clone.branches) == {'master'}
267 repo_clone._checkout(new_branch, create=True)
267 repo_clone._checkout(new_branch, create=True)
268
268
269 # Branches is a lazy property so we need to recrete the Repo object.
269 # Branches is a lazy property so we need to recrete the Repo object.
270 repo_clone = GitRepository(repo_clone.path)
270 repo_clone = GitRepository(repo_clone.path)
271 assert set(repo_clone.branches) == {'master', new_branch}
271 assert set(repo_clone.branches) == {'master', new_branch}
272 assert repo_clone._current_branch() == new_branch
272 assert repo_clone._current_branch() == new_branch
273
273
274 def test_checkout(self, tmp_path_factory):
274 def test_checkout(self, tmpdir):
275 repo_clone = self.get_clone_repo(tmp_path_factory)
275 repo_clone = self.get_clone_repo(tmpdir)
276
276
277 repo_clone._checkout('new_branch', create=True)
277 repo_clone._checkout('new_branch', create=True)
278 repo_clone._checkout('master')
278 repo_clone._checkout('master')
279
279
280 assert repo_clone._current_branch() == 'master'
280 assert repo_clone._current_branch() == 'master'
281
281
282 def test_checkout_same_branch(self, tmp_path_factory):
282 def test_checkout_same_branch(self, tmpdir):
283 repo_clone = self.get_clone_repo(tmp_path_factory)
283 repo_clone = self.get_clone_repo(tmpdir)
284
284
285 repo_clone._checkout('master')
285 repo_clone._checkout('master')
286 assert repo_clone._current_branch() == 'master'
286 assert repo_clone._current_branch() == 'master'
287
287
288 def test_checkout_branch_already_exists(self, tmp_path_factory):
288 def test_checkout_branch_already_exists(self, tmpdir):
289 repo_clone = self.get_clone_repo(tmp_path_factory)
289 repo_clone = self.get_clone_repo(tmpdir)
290
290
291 with pytest.raises(RepositoryError):
291 with pytest.raises(RepositoryError):
292 repo_clone._checkout('master', create=True)
292 repo_clone._checkout('master', create=True)
293
293
294 def test_checkout_bare_repo(self):
294 def test_checkout_bare_repo(self):
295 with pytest.raises(RepositoryError):
295 with pytest.raises(RepositoryError):
296 self.repo._checkout('master')
296 self.repo._checkout('master')
297
297
298 def test_current_branch_bare_repo(self):
298 def test_current_branch_bare_repo(self):
299 with pytest.raises(RepositoryError):
299 with pytest.raises(RepositoryError):
300 self.repo._current_branch()
300 self.repo._current_branch()
301
301
302 def test_current_branch_empty_repo(self, tmp_path_factory):
302 def test_current_branch_empty_repo(self, tmpdir):
303 repo = self.get_empty_repo(tmp_path_factory)
303 repo = self.get_empty_repo(tmpdir)
304 assert repo._current_branch() is None
304 assert repo._current_branch() is None
305
305
306 def test_local_clone(self, tmp_path_factory):
306 def test_local_clone(self, tmp_path_factory):
307 clone_path = tmp_path_factory.mktemp('test-local-clone')
307 clone_path = str(tmp_path_factory.mktemp('test-local-clone'))
308 self.repo._local_clone(clone_path, 'master')
308 self.repo._local_clone(clone_path, 'master')
309 repo_clone = GitRepository(clone_path)
309 repo_clone = GitRepository(clone_path)
310
310
311 assert self.repo.commit_ids == repo_clone.commit_ids
311 assert self.repo.commit_ids == repo_clone.commit_ids
312
312
313 def test_local_clone_with_specific_branch(self, tmp_path_factory):
313 def test_local_clone_with_specific_branch(self, tmpdir):
314 source_repo = self.get_clone_repo(tmp_path_factory)
314 source_repo = self.get_clone_repo(tmpdir)
315
315
316 # Create a new branch in source repo
316 # Create a new branch in source repo
317 new_branch_commit = source_repo.commit_ids[-3]
317 new_branch_commit = source_repo.commit_ids[-3]
318 source_repo._checkout(new_branch_commit)
318 source_repo._checkout(new_branch_commit)
319 source_repo._checkout('new_branch', create=True)
319 source_repo._checkout('new_branch', create=True)
320
320
321 clone_path = tmp_path_factory.mktemp('git-clone-path-1')
321 clone_path = str(tmpdir.join('git-clone-path-1'))
322 source_repo._local_clone(clone_path, 'new_branch')
322 source_repo._local_clone(clone_path, 'new_branch')
323 repo_clone = GitRepository(clone_path)
323 repo_clone = GitRepository(clone_path)
324
324
325 assert source_repo.commit_ids[:-3 + 1] == repo_clone.commit_ids
325 assert source_repo.commit_ids[:-3 + 1] == repo_clone.commit_ids
326
326
327 clone_path = tmp_path_factory.mktemp('git-clone-path-2')
327 clone_path = str(tmpdir.join('git-clone-path-2'))
328 source_repo._local_clone(clone_path, 'master')
328 source_repo._local_clone(clone_path, 'master')
329 repo_clone = GitRepository(clone_path)
329 repo_clone = GitRepository(clone_path)
330
330
331 assert source_repo.commit_ids == repo_clone.commit_ids
331 assert source_repo.commit_ids == repo_clone.commit_ids
332
332
333 def test_local_clone_fails_if_target_exists(self):
333 def test_local_clone_fails_if_target_exists(self):
334 with pytest.raises(RepositoryError):
334 with pytest.raises(RepositoryError):
335 self.repo._local_clone(self.repo.path, 'master')
335 self.repo._local_clone(self.repo.path, 'master')
336
336
337 def test_local_fetch(self, tmp_path_factory):
337 def test_local_fetch(self, tmpdir):
338 target_repo = self.get_empty_repo(tmp_path_factory)
338 target_repo = self.get_empty_repo(tmpdir)
339 source_repo = self.get_clone_repo(tmp_path_factory)
339 source_repo = self.get_clone_repo(tmpdir)
340
340
341 # Create a new branch in source repo
341 # Create a new branch in source repo
342 master_commit = source_repo.commit_ids[-1]
342 master_commit = source_repo.commit_ids[-1]
343 new_branch_commit = source_repo.commit_ids[-3]
343 new_branch_commit = source_repo.commit_ids[-3]
344 source_repo._checkout(new_branch_commit)
344 source_repo._checkout(new_branch_commit)
345 source_repo._checkout('new_branch', create=True)
345 source_repo._checkout('new_branch', create=True)
346
346
347 target_repo._local_fetch(source_repo.path, 'new_branch')
347 target_repo._local_fetch(source_repo.path, 'new_branch')
348 assert target_repo._last_fetch_heads() == [new_branch_commit]
348 assert target_repo._last_fetch_heads() == [new_branch_commit]
349
349
350 target_repo._local_fetch(source_repo.path, 'master')
350 target_repo._local_fetch(source_repo.path, 'master')
351 assert target_repo._last_fetch_heads() == [master_commit]
351 assert target_repo._last_fetch_heads() == [master_commit]
352
352
353 def test_local_fetch_from_bare_repo(self, tmp_path_factory):
353 def test_local_fetch_from_bare_repo(self, tmpdir):
354 target_repo = self.get_empty_repo(tmp_path_factory)
354 target_repo = self.get_empty_repo(tmpdir)
355 target_repo._local_fetch(self.repo.path, 'master')
355 target_repo._local_fetch(self.repo.path, 'master')
356
356
357 master_commit = self.repo.commit_ids[-1]
357 master_commit = self.repo.commit_ids[-1]
358 assert target_repo._last_fetch_heads() == [master_commit]
358 assert target_repo._last_fetch_heads() == [master_commit]
359
359
360 def test_local_fetch_from_same_repo(self):
360 def test_local_fetch_from_same_repo(self):
361 with pytest.raises(ValueError):
361 with pytest.raises(ValueError):
362 self.repo._local_fetch(self.repo.path, 'master')
362 self.repo._local_fetch(self.repo.path, 'master')
363
363
364 def test_local_fetch_branch_does_not_exist(self, tmp_path_factory):
364 def test_local_fetch_branch_does_not_exist(self, tmpdir):
365 target_repo = self.get_empty_repo(tmp_path_factory)
365 target_repo = self.get_empty_repo(tmpdir)
366
366
367 with pytest.raises(RepositoryError):
367 with pytest.raises(RepositoryError):
368 target_repo._local_fetch(self.repo.path, 'new_branch')
368 target_repo._local_fetch(self.repo.path, 'new_branch')
369
369
370 def test_local_pull(self, tmp_path_factory):
370 def test_local_pull(self, tmpdir):
371 target_repo = self.get_empty_repo(tmp_path_factory)
371 target_repo = self.get_empty_repo(tmpdir)
372 source_repo = self.get_clone_repo(tmp_path_factory)
372 source_repo = self.get_clone_repo(tmpdir)
373
373
374 # Create a new branch in source repo
374 # Create a new branch in source repo
375 master_commit = source_repo.commit_ids[-1]
375 master_commit = source_repo.commit_ids[-1]
376 new_branch_commit = source_repo.commit_ids[-3]
376 new_branch_commit = source_repo.commit_ids[-3]
377 source_repo._checkout(new_branch_commit)
377 source_repo._checkout(new_branch_commit)
378 source_repo._checkout('new_branch', create=True)
378 source_repo._checkout('new_branch', create=True)
379
379
380 target_repo._local_pull(source_repo.path, 'new_branch')
380 target_repo._local_pull(source_repo.path, 'new_branch')
381 target_repo = GitRepository(target_repo.path)
381 target_repo = GitRepository(target_repo.path)
382 assert target_repo.head == new_branch_commit
382 assert target_repo.head == new_branch_commit
383
383
384 target_repo._local_pull(source_repo.path, 'master')
384 target_repo._local_pull(source_repo.path, 'master')
385 target_repo = GitRepository(target_repo.path)
385 target_repo = GitRepository(target_repo.path)
386 assert target_repo.head == master_commit
386 assert target_repo.head == master_commit
387
387
388 def test_local_pull_in_bare_repo(self):
388 def test_local_pull_in_bare_repo(self):
389 with pytest.raises(RepositoryError):
389 with pytest.raises(RepositoryError):
390 self.repo._local_pull(self.repo.path, 'master')
390 self.repo._local_pull(self.repo.path, 'master')
391
391
392 def test_local_merge(self, tmp_path_factory):
392 def test_local_merge(self, tmpdir):
393 target_repo = self.get_empty_repo(tmp_path_factory)
393 target_repo = self.get_empty_repo(tmpdir)
394 source_repo = self.get_clone_repo(tmp_path_factory)
394 source_repo = self.get_clone_repo(tmpdir)
395
395
396 # Create a new branch in source repo
396 # Create a new branch in source repo
397 master_commit = source_repo.commit_ids[-1]
397 master_commit = source_repo.commit_ids[-1]
398 new_branch_commit = source_repo.commit_ids[-3]
398 new_branch_commit = source_repo.commit_ids[-3]
399 source_repo._checkout(new_branch_commit)
399 source_repo._checkout(new_branch_commit)
400 source_repo._checkout('new_branch', create=True)
400 source_repo._checkout('new_branch', create=True)
401
401
402 # This is required as one cannot do a -ff-only merge in an empty repo.
402 # This is required as one cannot do a -ff-only merge in an empty repo.
403 target_repo._local_pull(source_repo.path, 'new_branch')
403 target_repo._local_pull(source_repo.path, 'new_branch')
404
404
405 target_repo._local_fetch(source_repo.path, 'master')
405 target_repo._local_fetch(source_repo.path, 'master')
406 merge_message = 'Merge message\n\nDescription:...'
406 merge_message = 'Merge message\n\nDescription:...'
407 user_name = 'Albert Einstein'
407 user_name = 'Albert Einstein'
408 user_email = 'albert@einstein.com'
408 user_email = 'albert@einstein.com'
409 target_repo._local_merge(merge_message, user_name, user_email,
409 target_repo._local_merge(merge_message, user_name, user_email,
410 target_repo._last_fetch_heads())
410 target_repo._last_fetch_heads())
411
411
412 target_repo = GitRepository(target_repo.path)
412 target_repo = GitRepository(target_repo.path)
413 assert target_repo.commit_ids[-2] == master_commit
413 assert target_repo.commit_ids[-2] == master_commit
414 last_commit = target_repo.get_commit(target_repo.head)
414 last_commit = target_repo.get_commit(target_repo.head)
415 assert last_commit.message.strip() == merge_message
415 assert last_commit.message.strip() == merge_message
416 assert last_commit.author == '%s <%s>' % (user_name, user_email)
416 assert last_commit.author == '%s <%s>' % (user_name, user_email)
417
417
418 assert not os.path.exists(
418 assert not os.path.exists(
419 os.path.join(target_repo.path, '.git', 'MERGE_HEAD'))
419 os.path.join(target_repo.path, '.git', 'MERGE_HEAD'))
420
420
421 def test_local_merge_raises_exception_on_conflict(self, vcsbackend_git):
421 def test_local_merge_raises_exception_on_conflict(self, vcsbackend_git):
422 target_repo = vcsbackend_git.create_repo(number_of_commits=1)
422 target_repo = vcsbackend_git.create_repo(number_of_commits=1)
423 vcsbackend_git.ensure_file('README', 'I will conflict with you!!!')
423 vcsbackend_git.ensure_file('README', 'I will conflict with you!!!')
424
424
425 target_repo._local_fetch(self.repo.path, 'master')
425 target_repo._local_fetch(self.repo.path, 'master')
426 with pytest.raises(RepositoryError):
426 with pytest.raises(RepositoryError):
427 target_repo._local_merge(
427 target_repo._local_merge(
428 'merge_message', 'user name', 'user@name.com',
428 'merge_message', 'user name', 'user@name.com',
429 target_repo._last_fetch_heads())
429 target_repo._last_fetch_heads())
430
430
431 # Check we are not left in an intermediate merge state
431 # Check we are not left in an intermediate merge state
432 assert not os.path.exists(
432 assert not os.path.exists(
433 os.path.join(target_repo.path, '.git', 'MERGE_HEAD'))
433 os.path.join(target_repo.path, '.git', 'MERGE_HEAD'))
434
434
435 def test_local_merge_into_empty_repo(self, tmp_path_factory):
435 def test_local_merge_into_empty_repo(self, tmpdir):
436 target_repo = self.get_empty_repo(tmp_path_factory)
436 target_repo = self.get_empty_repo(tmpdir)
437
437
438 # This is required as one cannot do a -ff-only merge in an empty repo.
438 # This is required as one cannot do a -ff-only merge in an empty repo.
439 target_repo._local_fetch(self.repo.path, 'master')
439 target_repo._local_fetch(self.repo.path, 'master')
440 with pytest.raises(RepositoryError):
440 with pytest.raises(RepositoryError):
441 target_repo._local_merge(
441 target_repo._local_merge(
442 'merge_message', 'user name', 'user@name.com',
442 'merge_message', 'user name', 'user@name.com',
443 target_repo._last_fetch_heads())
443 target_repo._last_fetch_heads())
444
444
445 def test_local_merge_in_bare_repo(self):
445 def test_local_merge_in_bare_repo(self):
446 with pytest.raises(RepositoryError):
446 with pytest.raises(RepositoryError):
447 self.repo._local_merge(
447 self.repo._local_merge(
448 'merge_message', 'user name', 'user@name.com', None)
448 'merge_message', 'user name', 'user@name.com', None)
449
449
450 def test_local_push_non_bare(self, tmp_path_factory):
450 def test_local_push_non_bare(self, tmpdir):
451 target_repo = self.get_empty_repo(tmp_path_factory)
451 target_repo = self.get_empty_repo(tmpdir)
452
452
453 pushed_branch = 'pushed_branch'
453 pushed_branch = 'pushed_branch'
454 self.repo._local_push('master', target_repo.path, pushed_branch)
454 self.repo._local_push('master', target_repo.path, pushed_branch)
455 # Fix the HEAD of the target repo, or otherwise GitRepository won't
455 # Fix the HEAD of the target repo, or otherwise GitRepository won't
456 # report any branches.
456 # report any branches.
457 with open(os.path.join(target_repo.path, '.git', 'HEAD'), 'w') as f:
457 with open(os.path.join(target_repo.path, '.git', 'HEAD'), 'w') as f:
458 f.write('ref: refs/heads/%s' % pushed_branch)
458 f.write('ref: refs/heads/%s' % pushed_branch)
459
459
460 target_repo = GitRepository(target_repo.path)
460 target_repo = GitRepository(target_repo.path)
461
461
462 assert (target_repo.branches[pushed_branch] ==
462 assert (target_repo.branches[pushed_branch] ==
463 self.repo.branches['master'])
463 self.repo.branches['master'])
464
464
465 def test_local_push_bare(self, tmp_path_factory):
465 def test_local_push_bare(self, tmpdir):
466 target_repo = self.get_empty_repo(tmp_path_factory, bare=True)
466 target_repo = self.get_empty_repo(tmpdir, bare=True)
467
467
468 pushed_branch = 'pushed_branch'
468 pushed_branch = 'pushed_branch'
469 self.repo._local_push('master', target_repo.path, pushed_branch)
469 self.repo._local_push('master', target_repo.path, pushed_branch)
470 # Fix the HEAD of the target repo, or otherwise GitRepository won't
470 # Fix the HEAD of the target repo, or otherwise GitRepository won't
471 # report any branches.
471 # report any branches.
472 with open(os.path.join(target_repo.path, 'HEAD'), 'w') as f:
472 with open(os.path.join(target_repo.path, 'HEAD'), 'w') as f:
473 f.write('ref: refs/heads/%s' % pushed_branch)
473 f.write('ref: refs/heads/%s' % pushed_branch)
474
474
475 target_repo = GitRepository(target_repo.path)
475 target_repo = GitRepository(target_repo.path)
476
476
477 assert (target_repo.branches[pushed_branch] ==
477 assert (target_repo.branches[pushed_branch] ==
478 self.repo.branches['master'])
478 self.repo.branches['master'])
479
479
480 def test_local_push_non_bare_target_branch_is_checked_out(self, tmp_path_factory):
480 def test_local_push_non_bare_target_branch_is_checked_out(self, tmpdir):
481 target_repo = self.get_clone_repo(tmp_path_factory)
481 target_repo = self.get_clone_repo(tmpdir)
482
482
483 pushed_branch = 'pushed_branch'
483 pushed_branch = 'pushed_branch'
484 # Create a new branch in source repo
484 # Create a new branch in source repo
485 new_branch_commit = target_repo.commit_ids[-3]
485 new_branch_commit = target_repo.commit_ids[-3]
486 target_repo._checkout(new_branch_commit)
486 target_repo._checkout(new_branch_commit)
487 target_repo._checkout(pushed_branch, create=True)
487 target_repo._checkout(pushed_branch, create=True)
488
488
489 self.repo._local_push('master', target_repo.path, pushed_branch)
489 self.repo._local_push('master', target_repo.path, pushed_branch)
490
490
491 target_repo = GitRepository(target_repo.path)
491 target_repo = GitRepository(target_repo.path)
492
492
493 assert (target_repo.branches[pushed_branch] ==
493 assert (target_repo.branches[pushed_branch] ==
494 self.repo.branches['master'])
494 self.repo.branches['master'])
495
495
496 def test_local_push_raises_exception_on_conflict(self, vcsbackend_git):
496 def test_local_push_raises_exception_on_conflict(self, vcsbackend_git):
497 target_repo = vcsbackend_git.create_repo(number_of_commits=1)
497 target_repo = vcsbackend_git.create_repo(number_of_commits=1)
498 with pytest.raises(RepositoryError):
498 with pytest.raises(RepositoryError):
499 self.repo._local_push('master', target_repo.path, 'master')
499 self.repo._local_push('master', target_repo.path, 'master')
500
500
501 def test_hooks_can_be_enabled_via_env_variable_for_local_push(self, tmp_path_factory):
501 def test_hooks_can_be_enabled_via_env_variable_for_local_push(self, tmpdir):
502 target_repo = self.get_empty_repo(tmp_path_factory, bare=True)
502 target_repo = self.get_empty_repo(tmpdir, bare=True)
503
503
504 with mock.patch.object(self.repo, 'run_git_command') as run_mock:
504 with mock.patch.object(self.repo, 'run_git_command') as run_mock:
505 self.repo._local_push(
505 self.repo._local_push(
506 'master', target_repo.path, 'master', enable_hooks=True)
506 'master', target_repo.path, 'master', enable_hooks=True)
507 env = run_mock.call_args[1]['extra_env']
507 env = run_mock.call_args[1]['extra_env']
508 assert 'RC_SKIP_HOOKS' not in env
508 assert 'RC_SKIP_HOOKS' not in env
509
509
510 def _add_failing_hook(self, repo_path, hook_name, bare=False):
510 def _add_failing_hook(self, repo_path, hook_name, bare=False):
511 path_components = (
511 path_components = (
512 ['hooks', hook_name] if bare else ['.git', 'hooks', hook_name])
512 ['hooks', hook_name] if bare else ['.git', 'hooks', hook_name])
513 hook_path = os.path.join(repo_path, *path_components)
513 hook_path = os.path.join(repo_path, *path_components)
514 with open(hook_path, 'w') as f:
514 with open(hook_path, 'w') as f:
515 script_lines = [
515 script_lines = [
516 '#!%s' % sys.executable,
516 '#!%s' % sys.executable,
517 'import os',
517 'import os',
518 'import sys',
518 'import sys',
519 'if os.environ.get("RC_SKIP_HOOKS"):',
519 'if os.environ.get("RC_SKIP_HOOKS"):',
520 ' sys.exit(0)',
520 ' sys.exit(0)',
521 'sys.exit(1)',
521 'sys.exit(1)',
522 ]
522 ]
523 f.write('\n'.join(script_lines))
523 f.write('\n'.join(script_lines))
524 os.chmod(hook_path, 0o755)
524 os.chmod(hook_path, 0o755)
525
525
526 def test_local_push_does_not_execute_hook(self, tmp_path_factory):
526 def test_local_push_does_not_execute_hook(self, tmpdir):
527 target_repo = self.get_empty_repo(tmp_path_factory)
527 target_repo = self.get_empty_repo(tmpdir)
528
528
529 pushed_branch = 'pushed_branch'
529 pushed_branch = 'pushed_branch'
530 self._add_failing_hook(target_repo.path, 'pre-receive')
530 self._add_failing_hook(target_repo.path, 'pre-receive')
531 self.repo._local_push('master', target_repo.path, pushed_branch)
531 self.repo._local_push('master', target_repo.path, pushed_branch)
532 # Fix the HEAD of the target repo, or otherwise GitRepository won't
532 # Fix the HEAD of the target repo, or otherwise GitRepository won't
533 # report any branches.
533 # report any branches.
534 with open(os.path.join(target_repo.path, '.git', 'HEAD'), 'w') as f:
534 with open(os.path.join(target_repo.path, '.git', 'HEAD'), 'w') as f:
535 f.write('ref: refs/heads/%s' % pushed_branch)
535 f.write('ref: refs/heads/%s' % pushed_branch)
536
536
537 target_repo = GitRepository(target_repo.path)
537 target_repo = GitRepository(target_repo.path)
538
538
539 assert (target_repo.branches[pushed_branch] ==
539 assert (target_repo.branches[pushed_branch] ==
540 self.repo.branches['master'])
540 self.repo.branches['master'])
541
541
542 def test_local_push_executes_hook(self, tmp_path_factory):
542 def test_local_push_executes_hook(self, tmpdir):
543 target_repo = self.get_empty_repo(tmp_path_factory, bare=True)
543 target_repo = self.get_empty_repo(tmpdir, bare=True)
544 self._add_failing_hook(target_repo.path, 'pre-receive', bare=True)
544 self._add_failing_hook(target_repo.path, 'pre-receive', bare=True)
545 with pytest.raises(RepositoryError):
545 with pytest.raises(RepositoryError):
546 self.repo._local_push(
546 self.repo._local_push(
547 'master', target_repo.path, 'master', enable_hooks=True)
547 'master', target_repo.path, 'master', enable_hooks=True)
548
548
549 def test_maybe_prepare_merge_workspace(self):
549 def test_maybe_prepare_merge_workspace(self):
550 workspace = self.repo._maybe_prepare_merge_workspace(
550 workspace = self.repo._maybe_prepare_merge_workspace(
551 2, 'pr2', Reference('branch', 'master', 'unused'),
551 2, 'pr2', Reference('branch', 'master', 'unused'),
552 Reference('branch', 'master', 'unused'))
552 Reference('branch', 'master', 'unused'))
553
553
554 assert os.path.isdir(workspace)
554 assert os.path.isdir(workspace)
555 workspace_repo = GitRepository(workspace)
555 workspace_repo = GitRepository(workspace)
556 assert workspace_repo.branches == self.repo.branches
556 assert workspace_repo.branches == self.repo.branches
557
557
558 # Calling it a second time should also succeed
558 # Calling it a second time should also succeed
559 workspace = self.repo._maybe_prepare_merge_workspace(
559 workspace = self.repo._maybe_prepare_merge_workspace(
560 2, 'pr2', Reference('branch', 'master', 'unused'),
560 2, 'pr2', Reference('branch', 'master', 'unused'),
561 Reference('branch', 'master', 'unused'))
561 Reference('branch', 'master', 'unused'))
562 assert os.path.isdir(workspace)
562 assert os.path.isdir(workspace)
563
563
564 def test_maybe_prepare_merge_workspace_different_refs(self):
564 def test_maybe_prepare_merge_workspace_different_refs(self):
565 workspace = self.repo._maybe_prepare_merge_workspace(
565 workspace = self.repo._maybe_prepare_merge_workspace(
566 2, 'pr2', Reference('branch', 'master', 'unused'),
566 2, 'pr2', Reference('branch', 'master', 'unused'),
567 Reference('branch', 'develop', 'unused'))
567 Reference('branch', 'develop', 'unused'))
568
568
569 assert os.path.isdir(workspace)
569 assert os.path.isdir(workspace)
570 workspace_repo = GitRepository(workspace)
570 workspace_repo = GitRepository(workspace)
571 assert workspace_repo.branches == self.repo.branches
571 assert workspace_repo.branches == self.repo.branches
572
572
573 # Calling it a second time should also succeed
573 # Calling it a second time should also succeed
574 workspace = self.repo._maybe_prepare_merge_workspace(
574 workspace = self.repo._maybe_prepare_merge_workspace(
575 2, 'pr2', Reference('branch', 'master', 'unused'),
575 2, 'pr2', Reference('branch', 'master', 'unused'),
576 Reference('branch', 'develop', 'unused'))
576 Reference('branch', 'develop', 'unused'))
577 assert os.path.isdir(workspace)
577 assert os.path.isdir(workspace)
578
578
579 def test_cleanup_merge_workspace(self):
579 def test_cleanup_merge_workspace(self):
580 workspace = self.repo._maybe_prepare_merge_workspace(
580 workspace = self.repo._maybe_prepare_merge_workspace(
581 2, 'pr3', Reference('branch', 'master', 'unused'),
581 2, 'pr3', Reference('branch', 'master', 'unused'),
582 Reference('branch', 'master', 'unused'))
582 Reference('branch', 'master', 'unused'))
583 self.repo.cleanup_merge_workspace(2, 'pr3')
583 self.repo.cleanup_merge_workspace(2, 'pr3')
584
584
585 assert not os.path.exists(workspace)
585 assert not os.path.exists(workspace)
586
586
587 def test_cleanup_merge_workspace_invalid_workspace_id(self):
587 def test_cleanup_merge_workspace_invalid_workspace_id(self):
588 # No assert: because in case of an inexistent workspace this function
588 # No assert: because in case of an inexistent workspace this function
589 # should still succeed.
589 # should still succeed.
590 self.repo.cleanup_merge_workspace(1, 'pr4')
590 self.repo.cleanup_merge_workspace(1, 'pr4')
591
591
592 def test_set_refs(self):
592 def test_set_refs(self):
593 test_ref = 'refs/test-refs/abcde'
593 test_ref = 'refs/test-refs/abcde'
594 test_commit_id = 'ecb86e1f424f2608262b130db174a7dfd25a6623'
594 test_commit_id = 'ecb86e1f424f2608262b130db174a7dfd25a6623'
595
595
596 self.repo.set_refs(test_ref, test_commit_id)
596 self.repo.set_refs(test_ref, test_commit_id)
597 stdout, _ = self.repo.run_git_command(['show-ref'])
597 stdout, _ = self.repo.run_git_command(['show-ref'])
598 assert test_ref in stdout
598 assert test_ref in stdout
599 assert test_commit_id in stdout
599 assert test_commit_id in stdout
600
600
601 def test_remove_ref(self):
601 def test_remove_ref(self):
602 test_ref = 'refs/test-refs/abcde'
602 test_ref = 'refs/test-refs/abcde'
603 test_commit_id = 'ecb86e1f424f2608262b130db174a7dfd25a6623'
603 test_commit_id = 'ecb86e1f424f2608262b130db174a7dfd25a6623'
604 self.repo.set_refs(test_ref, test_commit_id)
604 self.repo.set_refs(test_ref, test_commit_id)
605 stdout, _ = self.repo.run_git_command(['show-ref'])
605 stdout, _ = self.repo.run_git_command(['show-ref'])
606 assert test_ref in stdout
606 assert test_ref in stdout
607 assert test_commit_id in stdout
607 assert test_commit_id in stdout
608
608
609 self.repo.remove_ref(test_ref)
609 self.repo.remove_ref(test_ref)
610 stdout, _ = self.repo.run_git_command(['show-ref'])
610 stdout, _ = self.repo.run_git_command(['show-ref'])
611 assert test_ref not in stdout
611 assert test_ref not in stdout
612 assert test_commit_id not in stdout
612 assert test_commit_id not in stdout
613
613
614
614
615 class TestGitCommit(object):
615 class TestGitCommit(object):
616
616
617 @pytest.fixture(autouse=True)
617 @pytest.fixture(autouse=True)
618 def prepare(self):
618 def prepare(self):
619 self.repo = GitRepository(TEST_GIT_REPO)
619 self.repo = GitRepository(TEST_GIT_REPO)
620
620
621 def test_default_commit(self):
621 def test_default_commit(self):
622 tip = self.repo.get_commit()
622 tip = self.repo.get_commit()
623 assert tip == self.repo.get_commit(None)
623 assert tip == self.repo.get_commit(None)
624 assert tip == self.repo.get_commit('tip')
624 assert tip == self.repo.get_commit('tip')
625
625
626 def test_root_node(self):
626 def test_root_node(self):
627 tip = self.repo.get_commit()
627 tip = self.repo.get_commit()
628 assert tip.root is tip.get_node('')
628 assert tip.root is tip.get_node('')
629
629
630 def test_lazy_fetch(self):
630 def test_lazy_fetch(self):
631 """
631 """
632 Test if commit's nodes expands and are cached as we walk through
632 Test if commit's nodes expands and are cached as we walk through
633 the commit. This test is somewhat hard to write as order of tests
633 the commit. This test is somewhat hard to write as order of tests
634 is a key here. Written by running command after command in a shell.
634 is a key here. Written by running command after command in a shell.
635 """
635 """
636 commit_id = '2a13f185e4525f9d4b59882791a2d397b90d5ddc'
636 commit_id = '2a13f185e4525f9d4b59882791a2d397b90d5ddc'
637 assert commit_id in self.repo.commit_ids
637 assert commit_id in self.repo.commit_ids
638 commit = self.repo.get_commit(commit_id)
638 commit = self.repo.get_commit(commit_id)
639 assert len(commit.nodes) == 0
639 assert len(commit.nodes) == 0
640 root = commit.root
640 root = commit.root
641 assert len(commit.nodes) == 1
641 assert len(commit.nodes) == 1
642 assert len(root.nodes) == 8
642 assert len(root.nodes) == 8
643 # accessing root.nodes updates commit.nodes
643 # accessing root.nodes updates commit.nodes
644 assert len(commit.nodes) == 9
644 assert len(commit.nodes) == 9
645
645
646 docs = root.get_node('docs')
646 docs = root.get_node('docs')
647 # we haven't yet accessed anything new as docs dir was already cached
647 # we haven't yet accessed anything new as docs dir was already cached
648 assert len(commit.nodes) == 9
648 assert len(commit.nodes) == 9
649 assert len(docs.nodes) == 8
649 assert len(docs.nodes) == 8
650 # accessing docs.nodes updates commit.nodes
650 # accessing docs.nodes updates commit.nodes
651 assert len(commit.nodes) == 17
651 assert len(commit.nodes) == 17
652
652
653 assert docs is commit.get_node('docs')
653 assert docs is commit.get_node('docs')
654 assert docs is root.nodes[0]
654 assert docs is root.nodes[0]
655 assert docs is root.dirs[0]
655 assert docs is root.dirs[0]
656 assert docs is commit.get_node('docs')
656 assert docs is commit.get_node('docs')
657
657
658 def test_nodes_with_commit(self):
658 def test_nodes_with_commit(self):
659 commit_id = '2a13f185e4525f9d4b59882791a2d397b90d5ddc'
659 commit_id = '2a13f185e4525f9d4b59882791a2d397b90d5ddc'
660 commit = self.repo.get_commit(commit_id)
660 commit = self.repo.get_commit(commit_id)
661 root = commit.root
661 root = commit.root
662 docs = root.get_node('docs')
662 docs = root.get_node('docs')
663 assert docs is commit.get_node('docs')
663 assert docs is commit.get_node('docs')
664 api = docs.get_node('api')
664 api = docs.get_node('api')
665 assert api is commit.get_node('docs/api')
665 assert api is commit.get_node('docs/api')
666 index = api.get_node('index.rst')
666 index = api.get_node('index.rst')
667 assert index is commit.get_node('docs/api/index.rst')
667 assert index is commit.get_node('docs/api/index.rst')
668 assert index is commit.get_node('docs')\
668 assert index is commit.get_node('docs')\
669 .get_node('api')\
669 .get_node('api')\
670 .get_node('index.rst')
670 .get_node('index.rst')
671
671
672 def test_branch_and_tags(self):
672 def test_branch_and_tags(self):
673 """
673 """
674 rev0 = self.repo.commit_ids[0]
674 rev0 = self.repo.commit_ids[0]
675 commit0 = self.repo.get_commit(rev0)
675 commit0 = self.repo.get_commit(rev0)
676 assert commit0.branch == 'master'
676 assert commit0.branch == 'master'
677 assert commit0.tags == []
677 assert commit0.tags == []
678
678
679 rev10 = self.repo.commit_ids[10]
679 rev10 = self.repo.commit_ids[10]
680 commit10 = self.repo.get_commit(rev10)
680 commit10 = self.repo.get_commit(rev10)
681 assert commit10.branch == 'master'
681 assert commit10.branch == 'master'
682 assert commit10.tags == []
682 assert commit10.tags == []
683
683
684 rev44 = self.repo.commit_ids[44]
684 rev44 = self.repo.commit_ids[44]
685 commit44 = self.repo.get_commit(rev44)
685 commit44 = self.repo.get_commit(rev44)
686 assert commit44.branch == 'web-branch'
686 assert commit44.branch == 'web-branch'
687
687
688 tip = self.repo.get_commit('tip')
688 tip = self.repo.get_commit('tip')
689 assert 'tip' in tip.tags
689 assert 'tip' in tip.tags
690 """
690 """
691 # Those tests would fail - branches are now going
691 # Those tests would fail - branches are now going
692 # to be changed at main API in order to support git backend
692 # to be changed at main API in order to support git backend
693 pass
693 pass
694
694
695 def test_file_size(self):
695 def test_file_size(self):
696 to_check = (
696 to_check = (
697 ('c1214f7e79e02fc37156ff215cd71275450cffc3',
697 ('c1214f7e79e02fc37156ff215cd71275450cffc3',
698 'vcs/backends/BaseRepository.py', 502),
698 'vcs/backends/BaseRepository.py', 502),
699 ('d7e0d30fbcae12c90680eb095a4f5f02505ce501',
699 ('d7e0d30fbcae12c90680eb095a4f5f02505ce501',
700 'vcs/backends/hg.py', 854),
700 'vcs/backends/hg.py', 854),
701 ('6e125e7c890379446e98980d8ed60fba87d0f6d1',
701 ('6e125e7c890379446e98980d8ed60fba87d0f6d1',
702 'setup.py', 1068),
702 'setup.py', 1068),
703
703
704 ('d955cd312c17b02143c04fa1099a352b04368118',
704 ('d955cd312c17b02143c04fa1099a352b04368118',
705 'vcs/backends/base.py', 2921),
705 'vcs/backends/base.py', 2921),
706 ('ca1eb7957a54bce53b12d1a51b13452f95bc7c7e',
706 ('ca1eb7957a54bce53b12d1a51b13452f95bc7c7e',
707 'vcs/backends/base.py', 3936),
707 'vcs/backends/base.py', 3936),
708 ('f50f42baeed5af6518ef4b0cb2f1423f3851a941',
708 ('f50f42baeed5af6518ef4b0cb2f1423f3851a941',
709 'vcs/backends/base.py', 6189),
709 'vcs/backends/base.py', 6189),
710 )
710 )
711 for commit_id, path, size in to_check:
711 for commit_id, path, size in to_check:
712 node = self.repo.get_commit(commit_id).get_node(path)
712 node = self.repo.get_commit(commit_id).get_node(path)
713 assert node.is_file()
713 assert node.is_file()
714 assert node.size == size
714 assert node.size == size
715
715
716 def test_file_history_from_commits(self):
716 def test_file_history_from_commits(self):
717 node = self.repo[10].get_node('setup.py')
717 node = self.repo[10].get_node('setup.py')
718 commit_ids = [commit.raw_id for commit in node.history]
718 commit_ids = [commit.raw_id for commit in node.history]
719 assert ['ff7ca51e58c505fec0dd2491de52c622bb7a806b'] == commit_ids
719 assert ['ff7ca51e58c505fec0dd2491de52c622bb7a806b'] == commit_ids
720
720
721 node = self.repo[20].get_node('setup.py')
721 node = self.repo[20].get_node('setup.py')
722 node_ids = [commit.raw_id for commit in node.history]
722 node_ids = [commit.raw_id for commit in node.history]
723 assert ['191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
723 assert ['191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
724 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'] == node_ids
724 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'] == node_ids
725
725
726 # special case we check history from commit that has this particular
726 # special case we check history from commit that has this particular
727 # file changed this means we check if it's included as well
727 # file changed this means we check if it's included as well
728 node = self.repo.get_commit('191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e') \
728 node = self.repo.get_commit('191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e') \
729 .get_node('setup.py')
729 .get_node('setup.py')
730 node_ids = [commit.raw_id for commit in node.history]
730 node_ids = [commit.raw_id for commit in node.history]
731 assert ['191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
731 assert ['191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
732 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'] == node_ids
732 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'] == node_ids
733
733
734 def test_file_history(self):
734 def test_file_history(self):
735 # we can only check if those commits are present in the history
735 # we can only check if those commits are present in the history
736 # as we cannot update this test every time file is changed
736 # as we cannot update this test every time file is changed
737 files = {
737 files = {
738 'setup.py': [
738 'setup.py': [
739 '54386793436c938cff89326944d4c2702340037d',
739 '54386793436c938cff89326944d4c2702340037d',
740 '51d254f0ecf5df2ce50c0b115741f4cf13985dab',
740 '51d254f0ecf5df2ce50c0b115741f4cf13985dab',
741 '998ed409c795fec2012b1c0ca054d99888b22090',
741 '998ed409c795fec2012b1c0ca054d99888b22090',
742 '5e0eb4c47f56564395f76333f319d26c79e2fb09',
742 '5e0eb4c47f56564395f76333f319d26c79e2fb09',
743 '0115510b70c7229dbc5dc49036b32e7d91d23acd',
743 '0115510b70c7229dbc5dc49036b32e7d91d23acd',
744 '7cb3fd1b6d8c20ba89e2264f1c8baebc8a52d36e',
744 '7cb3fd1b6d8c20ba89e2264f1c8baebc8a52d36e',
745 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
745 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
746 '191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
746 '191caa5b2c81ed17c0794bf7bb9958f4dcb0b87e',
747 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
747 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
748 ],
748 ],
749 'vcs/nodes.py': [
749 'vcs/nodes.py': [
750 '33fa3223355104431402a888fa77a4e9956feb3e',
750 '33fa3223355104431402a888fa77a4e9956feb3e',
751 'fa014c12c26d10ba682fadb78f2a11c24c8118e1',
751 'fa014c12c26d10ba682fadb78f2a11c24c8118e1',
752 'e686b958768ee96af8029fe19c6050b1a8dd3b2b',
752 'e686b958768ee96af8029fe19c6050b1a8dd3b2b',
753 'ab5721ca0a081f26bf43d9051e615af2cc99952f',
753 'ab5721ca0a081f26bf43d9051e615af2cc99952f',
754 'c877b68d18e792a66b7f4c529ea02c8f80801542',
754 'c877b68d18e792a66b7f4c529ea02c8f80801542',
755 '4313566d2e417cb382948f8d9d7c765330356054',
755 '4313566d2e417cb382948f8d9d7c765330356054',
756 '6c2303a793671e807d1cfc70134c9ca0767d98c2',
756 '6c2303a793671e807d1cfc70134c9ca0767d98c2',
757 '54386793436c938cff89326944d4c2702340037d',
757 '54386793436c938cff89326944d4c2702340037d',
758 '54000345d2e78b03a99d561399e8e548de3f3203',
758 '54000345d2e78b03a99d561399e8e548de3f3203',
759 '1c6b3677b37ea064cb4b51714d8f7498f93f4b2b',
759 '1c6b3677b37ea064cb4b51714d8f7498f93f4b2b',
760 '2d03ca750a44440fb5ea8b751176d1f36f8e8f46',
760 '2d03ca750a44440fb5ea8b751176d1f36f8e8f46',
761 '2a08b128c206db48c2f0b8f70df060e6db0ae4f8',
761 '2a08b128c206db48c2f0b8f70df060e6db0ae4f8',
762 '30c26513ff1eb8e5ce0e1c6b477ee5dc50e2f34b',
762 '30c26513ff1eb8e5ce0e1c6b477ee5dc50e2f34b',
763 'ac71e9503c2ca95542839af0ce7b64011b72ea7c',
763 'ac71e9503c2ca95542839af0ce7b64011b72ea7c',
764 '12669288fd13adba2a9b7dd5b870cc23ffab92d2',
764 '12669288fd13adba2a9b7dd5b870cc23ffab92d2',
765 '5a0c84f3e6fe3473e4c8427199d5a6fc71a9b382',
765 '5a0c84f3e6fe3473e4c8427199d5a6fc71a9b382',
766 '12f2f5e2b38e6ff3fbdb5d722efed9aa72ecb0d5',
766 '12f2f5e2b38e6ff3fbdb5d722efed9aa72ecb0d5',
767 '5eab1222a7cd4bfcbabc218ca6d04276d4e27378',
767 '5eab1222a7cd4bfcbabc218ca6d04276d4e27378',
768 'f50f42baeed5af6518ef4b0cb2f1423f3851a941',
768 'f50f42baeed5af6518ef4b0cb2f1423f3851a941',
769 'd7e390a45f6aa96f04f5e7f583ad4f867431aa25',
769 'd7e390a45f6aa96f04f5e7f583ad4f867431aa25',
770 'f15c21f97864b4f071cddfbf2750ec2e23859414',
770 'f15c21f97864b4f071cddfbf2750ec2e23859414',
771 'e906ef056cf539a4e4e5fc8003eaf7cf14dd8ade',
771 'e906ef056cf539a4e4e5fc8003eaf7cf14dd8ade',
772 'ea2b108b48aa8f8c9c4a941f66c1a03315ca1c3b',
772 'ea2b108b48aa8f8c9c4a941f66c1a03315ca1c3b',
773 '84dec09632a4458f79f50ddbbd155506c460b4f9',
773 '84dec09632a4458f79f50ddbbd155506c460b4f9',
774 '0115510b70c7229dbc5dc49036b32e7d91d23acd',
774 '0115510b70c7229dbc5dc49036b32e7d91d23acd',
775 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
775 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
776 '3bf1c5868e570e39569d094f922d33ced2fa3b2b',
776 '3bf1c5868e570e39569d094f922d33ced2fa3b2b',
777 'b8d04012574729d2c29886e53b1a43ef16dd00a1',
777 'b8d04012574729d2c29886e53b1a43ef16dd00a1',
778 '6970b057cffe4aab0a792aa634c89f4bebf01441',
778 '6970b057cffe4aab0a792aa634c89f4bebf01441',
779 'dd80b0f6cf5052f17cc738c2951c4f2070200d7f',
779 'dd80b0f6cf5052f17cc738c2951c4f2070200d7f',
780 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
780 'ff7ca51e58c505fec0dd2491de52c622bb7a806b',
781 ],
781 ],
782 'vcs/backends/git.py': [
782 'vcs/backends/git.py': [
783 '4cf116ad5a457530381135e2f4c453e68a1b0105',
783 '4cf116ad5a457530381135e2f4c453e68a1b0105',
784 '9a751d84d8e9408e736329767387f41b36935153',
784 '9a751d84d8e9408e736329767387f41b36935153',
785 'cb681fb539c3faaedbcdf5ca71ca413425c18f01',
785 'cb681fb539c3faaedbcdf5ca71ca413425c18f01',
786 '428f81bb652bcba8d631bce926e8834ff49bdcc6',
786 '428f81bb652bcba8d631bce926e8834ff49bdcc6',
787 '180ab15aebf26f98f714d8c68715e0f05fa6e1c7',
787 '180ab15aebf26f98f714d8c68715e0f05fa6e1c7',
788 '2b8e07312a2e89e92b90426ab97f349f4bce2a3a',
788 '2b8e07312a2e89e92b90426ab97f349f4bce2a3a',
789 '50e08c506174d8645a4bb517dd122ac946a0f3bf',
789 '50e08c506174d8645a4bb517dd122ac946a0f3bf',
790 '54000345d2e78b03a99d561399e8e548de3f3203',
790 '54000345d2e78b03a99d561399e8e548de3f3203',
791 ],
791 ],
792 }
792 }
793 for path, commit_ids in files.items():
793 for path, commit_ids in files.items():
794 node = self.repo.get_commit(commit_ids[0]).get_node(path)
794 node = self.repo.get_commit(commit_ids[0]).get_node(path)
795 node_ids = [commit.raw_id for commit in node.history]
795 node_ids = [commit.raw_id for commit in node.history]
796 assert set(commit_ids).issubset(set(node_ids)), (
796 assert set(commit_ids).issubset(set(node_ids)), (
797 "We assumed that %s is subset of commit_ids for which file %s "
797 "We assumed that %s is subset of commit_ids for which file %s "
798 "has been changed, and history of that node returned: %s"
798 "has been changed, and history of that node returned: %s"
799 % (commit_ids, path, node_ids))
799 % (commit_ids, path, node_ids))
800
800
801 def test_file_annotate(self):
801 def test_file_annotate(self):
802 files = {
802 files = {
803 'vcs/backends/__init__.py': {
803 'vcs/backends/__init__.py': {
804 'c1214f7e79e02fc37156ff215cd71275450cffc3': {
804 'c1214f7e79e02fc37156ff215cd71275450cffc3': {
805 'lines_no': 1,
805 'lines_no': 1,
806 'commits': [
806 'commits': [
807 'c1214f7e79e02fc37156ff215cd71275450cffc3',
807 'c1214f7e79e02fc37156ff215cd71275450cffc3',
808 ],
808 ],
809 },
809 },
810 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647': {
810 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647': {
811 'lines_no': 21,
811 'lines_no': 21,
812 'commits': [
812 'commits': [
813 '49d3fd156b6f7db46313fac355dca1a0b94a0017',
813 '49d3fd156b6f7db46313fac355dca1a0b94a0017',
814 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
814 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
815 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
815 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
816 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
816 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
817 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
817 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
818 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
818 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
819 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
819 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
820 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
820 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
821 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
821 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
822 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
822 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
823 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
823 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
824 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
824 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
825 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
825 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
826 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
826 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
827 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
827 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
828 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
828 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
829 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
829 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
830 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
830 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
831 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
831 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
832 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
832 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
833 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
833 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
834 ],
834 ],
835 },
835 },
836 'e29b67bd158580fc90fc5e9111240b90e6e86064': {
836 'e29b67bd158580fc90fc5e9111240b90e6e86064': {
837 'lines_no': 32,
837 'lines_no': 32,
838 'commits': [
838 'commits': [
839 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
839 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
840 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
840 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
841 '5eab1222a7cd4bfcbabc218ca6d04276d4e27378',
841 '5eab1222a7cd4bfcbabc218ca6d04276d4e27378',
842 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
842 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
843 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
843 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
844 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
844 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
845 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
845 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
846 '54000345d2e78b03a99d561399e8e548de3f3203',
846 '54000345d2e78b03a99d561399e8e548de3f3203',
847 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
847 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
848 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
848 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
849 '78c3f0c23b7ee935ec276acb8b8212444c33c396',
849 '78c3f0c23b7ee935ec276acb8b8212444c33c396',
850 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
850 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
851 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
851 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
852 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
852 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
853 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
853 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
854 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
854 '2a13f185e4525f9d4b59882791a2d397b90d5ddc',
855 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
855 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
856 '78c3f0c23b7ee935ec276acb8b8212444c33c396',
856 '78c3f0c23b7ee935ec276acb8b8212444c33c396',
857 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
857 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
858 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
858 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
859 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
859 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
860 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
860 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
861 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
861 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
862 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
862 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
863 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
863 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
864 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
864 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
865 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
865 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
866 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
866 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
867 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
867 '992f38217b979d0b0987d0bae3cc26dac85d9b19',
868 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
868 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
869 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
869 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
870 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
870 '16fba1ae9334d79b66d7afed2c2dfbfa2ae53647',
871 ],
871 ],
872 },
872 },
873 },
873 },
874 }
874 }
875
875
876 for fname, commit_dict in files.items():
876 for fname, commit_dict in files.items():
877 for commit_id, __ in commit_dict.items():
877 for commit_id, __ in commit_dict.items():
878 commit = self.repo.get_commit(commit_id)
878 commit = self.repo.get_commit(commit_id)
879
879
880 l1_1 = [x[1] for x in commit.get_file_annotate(fname)]
880 l1_1 = [x[1] for x in commit.get_file_annotate(fname)]
881 l1_2 = [x[2]().raw_id for x in commit.get_file_annotate(fname)]
881 l1_2 = [x[2]().raw_id for x in commit.get_file_annotate(fname)]
882 assert l1_1 == l1_2
882 assert l1_1 == l1_2
883 l1 = l1_1
883 l1 = l1_1
884 l2 = files[fname][commit_id]['commits']
884 l2 = files[fname][commit_id]['commits']
885 assert l1 == l2, (
885 assert l1 == l2, (
886 "The lists of commit_ids for %s@commit_id %s"
886 "The lists of commit_ids for %s@commit_id %s"
887 "from annotation list should match each other, "
887 "from annotation list should match each other, "
888 "got \n%s \nvs \n%s " % (fname, commit_id, l1, l2))
888 "got \n%s \nvs \n%s " % (fname, commit_id, l1, l2))
889
889
890 def test_files_state(self):
890 def test_files_state(self):
891 """
891 """
892 Tests state of FileNodes.
892 Tests state of FileNodes.
893 """
893 """
894 node = self.repo\
894 node = self.repo\
895 .get_commit('e6ea6d16e2f26250124a1f4b4fe37a912f9d86a0')\
895 .get_commit('e6ea6d16e2f26250124a1f4b4fe37a912f9d86a0')\
896 .get_node('vcs/utils/diffs.py')
896 .get_node('vcs/utils/diffs.py')
897 assert node.state, NodeState.ADDED
897 assert node.state, NodeState.ADDED
898 assert node.added
898 assert node.added
899 assert not node.changed
899 assert not node.changed
900 assert not node.not_changed
900 assert not node.not_changed
901 assert not node.removed
901 assert not node.removed
902
902
903 node = self.repo\
903 node = self.repo\
904 .get_commit('33fa3223355104431402a888fa77a4e9956feb3e')\
904 .get_commit('33fa3223355104431402a888fa77a4e9956feb3e')\
905 .get_node('.hgignore')
905 .get_node('.hgignore')
906 assert node.state, NodeState.CHANGED
906 assert node.state, NodeState.CHANGED
907 assert not node.added
907 assert not node.added
908 assert node.changed
908 assert node.changed
909 assert not node.not_changed
909 assert not node.not_changed
910 assert not node.removed
910 assert not node.removed
911
911
912 node = self.repo\
912 node = self.repo\
913 .get_commit('e29b67bd158580fc90fc5e9111240b90e6e86064')\
913 .get_commit('e29b67bd158580fc90fc5e9111240b90e6e86064')\
914 .get_node('setup.py')
914 .get_node('setup.py')
915 assert node.state, NodeState.NOT_CHANGED
915 assert node.state, NodeState.NOT_CHANGED
916 assert not node.added
916 assert not node.added
917 assert not node.changed
917 assert not node.changed
918 assert node.not_changed
918 assert node.not_changed
919 assert not node.removed
919 assert not node.removed
920
920
921 # If node has REMOVED state then trying to fetch it would raise
921 # If node has REMOVED state then trying to fetch it would raise
922 # CommitError exception
922 # CommitError exception
923 commit = self.repo.get_commit(
923 commit = self.repo.get_commit(
924 'fa6600f6848800641328adbf7811fd2372c02ab2')
924 'fa6600f6848800641328adbf7811fd2372c02ab2')
925 path = 'vcs/backends/BaseRepository.py'
925 path = 'vcs/backends/BaseRepository.py'
926 with pytest.raises(NodeDoesNotExistError):
926 with pytest.raises(NodeDoesNotExistError):
927 commit.get_node(path)
927 commit.get_node(path)
928 # but it would be one of ``removed`` (commit's attribute)
928 # but it would be one of ``removed`` (commit's attribute)
929 assert path in [rf.path for rf in commit.removed]
929 assert path in [rf.path for rf in commit.removed]
930
930
931 commit = self.repo.get_commit(
931 commit = self.repo.get_commit(
932 '54386793436c938cff89326944d4c2702340037d')
932 '54386793436c938cff89326944d4c2702340037d')
933 changed = [
933 changed = [
934 'setup.py', 'tests/test_nodes.py', 'vcs/backends/hg.py',
934 'setup.py', 'tests/test_nodes.py', 'vcs/backends/hg.py',
935 'vcs/nodes.py']
935 'vcs/nodes.py']
936 assert set(changed) == set([f.path for f in commit.changed])
936 assert set(changed) == set([f.path for f in commit.changed])
937
937
938 def test_unicode_branch_refs(self):
938 def test_unicode_branch_refs(self):
939 unicode_branches = {
939 unicode_branches = {
940 'refs/heads/unicode': '6c0ce52b229aa978889e91b38777f800e85f330b',
940 'refs/heads/unicode': '6c0ce52b229aa978889e91b38777f800e85f330b',
941 u'refs/heads/uniΓ§ΓΆβˆ‚e': 'ΓΌrl',
941 u'refs/heads/uniΓ§ΓΆβˆ‚e': 'ΓΌrl',
942 }
942 }
943 with mock.patch(
943 with mock.patch(
944 ("rhodecode.lib.vcs.backends.git.repository"
944 ("rhodecode.lib.vcs.backends.git.repository"
945 ".GitRepository._refs"),
945 ".GitRepository._refs"),
946 unicode_branches):
946 unicode_branches):
947 branches = self.repo.branches
947 branches = self.repo.branches
948
948
949 assert 'unicode' in branches
949 assert 'unicode' in branches
950 assert u'uniΓ§ΓΆβˆ‚e' in branches
950 assert u'uniΓ§ΓΆβˆ‚e' in branches
951
951
952 def test_unicode_tag_refs(self):
952 def test_unicode_tag_refs(self):
953 unicode_tags = {
953 unicode_tags = {
954 'refs/tags/unicode': '6c0ce52b229aa978889e91b38777f800e85f330b',
954 'refs/tags/unicode': '6c0ce52b229aa978889e91b38777f800e85f330b',
955 u'refs/tags/uniΓ§ΓΆβˆ‚e': '6c0ce52b229aa978889e91b38777f800e85f330b',
955 u'refs/tags/uniΓ§ΓΆβˆ‚e': '6c0ce52b229aa978889e91b38777f800e85f330b',
956 }
956 }
957 with mock.patch(
957 with mock.patch(
958 ("rhodecode.lib.vcs.backends.git.repository"
958 ("rhodecode.lib.vcs.backends.git.repository"
959 ".GitRepository._refs"),
959 ".GitRepository._refs"),
960 unicode_tags):
960 unicode_tags):
961 tags = self.repo.tags
961 tags = self.repo.tags
962
962
963 assert 'unicode' in tags
963 assert 'unicode' in tags
964 assert u'uniΓ§ΓΆβˆ‚e' in tags
964 assert u'uniΓ§ΓΆβˆ‚e' in tags
965
965
966 def test_commit_message_is_unicode(self):
966 def test_commit_message_is_unicode(self):
967 for commit in self.repo:
967 for commit in self.repo:
968 assert type(commit.message) == unicode
968 assert type(commit.message) == unicode
969
969
970 def test_commit_author_is_unicode(self):
970 def test_commit_author_is_unicode(self):
971 for commit in self.repo:
971 for commit in self.repo:
972 assert type(commit.author) == unicode
972 assert type(commit.author) == unicode
973
973
974 def test_repo_files_content_is_unicode(self):
974 def test_repo_files_content_is_unicode(self):
975 commit = self.repo.get_commit()
975 commit = self.repo.get_commit()
976 for node in commit.get_node('/'):
976 for node in commit.get_node('/'):
977 if node.is_file():
977 if node.is_file():
978 assert type(node.content) == unicode
978 assert type(node.content) == unicode
979
979
980 def test_wrong_path(self):
980 def test_wrong_path(self):
981 # There is 'setup.py' in the root dir but not there:
981 # There is 'setup.py' in the root dir but not there:
982 path = 'foo/bar/setup.py'
982 path = 'foo/bar/setup.py'
983 tip = self.repo.get_commit()
983 tip = self.repo.get_commit()
984 with pytest.raises(VCSError):
984 with pytest.raises(VCSError):
985 tip.get_node(path)
985 tip.get_node(path)
986
986
987 @pytest.mark.parametrize("author_email, commit_id", [
987 @pytest.mark.parametrize("author_email, commit_id", [
988 ('marcin@python-blog.com', 'c1214f7e79e02fc37156ff215cd71275450cffc3'),
988 ('marcin@python-blog.com', 'c1214f7e79e02fc37156ff215cd71275450cffc3'),
989 ('lukasz.balcerzak@python-center.pl',
989 ('lukasz.balcerzak@python-center.pl',
990 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'),
990 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'),
991 ('none@none', '8430a588b43b5d6da365400117c89400326e7992'),
991 ('none@none', '8430a588b43b5d6da365400117c89400326e7992'),
992 ])
992 ])
993 def test_author_email(self, author_email, commit_id):
993 def test_author_email(self, author_email, commit_id):
994 commit = self.repo.get_commit(commit_id)
994 commit = self.repo.get_commit(commit_id)
995 assert author_email == commit.author_email
995 assert author_email == commit.author_email
996
996
997 @pytest.mark.parametrize("author, commit_id", [
997 @pytest.mark.parametrize("author, commit_id", [
998 ('Marcin Kuzminski', 'c1214f7e79e02fc37156ff215cd71275450cffc3'),
998 ('Marcin Kuzminski', 'c1214f7e79e02fc37156ff215cd71275450cffc3'),
999 ('Lukasz Balcerzak', 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'),
999 ('Lukasz Balcerzak', 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'),
1000 ('marcink', '8430a588b43b5d6da365400117c89400326e7992'),
1000 ('marcink', '8430a588b43b5d6da365400117c89400326e7992'),
1001 ])
1001 ])
1002 def test_author_username(self, author, commit_id):
1002 def test_author_username(self, author, commit_id):
1003 commit = self.repo.get_commit(commit_id)
1003 commit = self.repo.get_commit(commit_id)
1004 assert author == commit.author_name
1004 assert author == commit.author_name
1005
1005
1006
1006
1007 class TestLargeFileRepo(object):
1007 class TestLargeFileRepo(object):
1008
1008
1009 def test_large_file(self, backend_git):
1009 def test_large_file(self, backend_git):
1010 conf = make_db_config()
1010 conf = make_db_config()
1011 repo = backend_git.create_test_repo('largefiles', conf)
1011 repo = backend_git.create_test_repo('largefiles', conf)
1012
1012
1013 tip = repo.scm_instance().get_commit()
1013 tip = repo.scm_instance().get_commit()
1014
1014
1015 # extract stored LF node into the origin cache
1015 # extract stored LF node into the origin cache
1016 lfs_store = os.path.join(repo.repo_path, repo.repo_name, 'lfs_store')
1016 lfs_store = os.path.join(repo.repo_path, repo.repo_name, 'lfs_store')
1017
1017
1018 oid = '7b331c02e313c7599d5a90212e17e6d3cb729bd2e1c9b873c302a63c95a2f9bf'
1018 oid = '7b331c02e313c7599d5a90212e17e6d3cb729bd2e1c9b873c302a63c95a2f9bf'
1019 oid_path = os.path.join(lfs_store, oid)
1019 oid_path = os.path.join(lfs_store, oid)
1020 oid_destination = os.path.join(
1020 oid_destination = os.path.join(
1021 conf.get('vcs_git_lfs', 'store_location'), oid)
1021 conf.get('vcs_git_lfs', 'store_location'), oid)
1022 shutil.copy(oid_path, oid_destination)
1022 shutil.copy(oid_path, oid_destination)
1023
1023
1024 node = tip.get_node('1MB.zip')
1024 node = tip.get_node('1MB.zip')
1025
1025
1026 lf_node = node.get_largefile_node()
1026 lf_node = node.get_largefile_node()
1027
1027
1028 assert lf_node.is_largefile() is True
1028 assert lf_node.is_largefile() is True
1029 assert lf_node.size == 1024000
1029 assert lf_node.size == 1024000
1030 assert lf_node.name == '1MB.zip'
1030 assert lf_node.name == '1MB.zip'
1031
1031
1032
1032
1033 @pytest.mark.usefixtures("vcs_repository_support")
1033 @pytest.mark.usefixtures("vcs_repository_support")
1034 class TestGitSpecificWithRepo(BackendTestMixin):
1034 class TestGitSpecificWithRepo(BackendTestMixin):
1035
1035
1036 @classmethod
1036 @classmethod
1037 def _get_commits(cls):
1037 def _get_commits(cls):
1038 return [
1038 return [
1039 {
1039 {
1040 'message': 'Initial',
1040 'message': 'Initial',
1041 'author': 'Joe Doe <joe.doe@example.com>',
1041 'author': 'Joe Doe <joe.doe@example.com>',
1042 'date': datetime.datetime(2010, 1, 1, 20),
1042 'date': datetime.datetime(2010, 1, 1, 20),
1043 'added': [
1043 'added': [
1044 FileNode('foobar/static/js/admin/base.js', content='base'),
1044 FileNode('foobar/static/js/admin/base.js', content='base'),
1045 FileNode(
1045 FileNode(
1046 'foobar/static/admin', content='admin',
1046 'foobar/static/admin', content='admin',
1047 mode=0o120000), # this is a link
1047 mode=0o120000), # this is a link
1048 FileNode('foo', content='foo'),
1048 FileNode('foo', content='foo'),
1049 ],
1049 ],
1050 },
1050 },
1051 {
1051 {
1052 'message': 'Second',
1052 'message': 'Second',
1053 'author': 'Joe Doe <joe.doe@example.com>',
1053 'author': 'Joe Doe <joe.doe@example.com>',
1054 'date': datetime.datetime(2010, 1, 1, 22),
1054 'date': datetime.datetime(2010, 1, 1, 22),
1055 'added': [
1055 'added': [
1056 FileNode('foo2', content='foo2'),
1056 FileNode('foo2', content='foo2'),
1057 ],
1057 ],
1058 },
1058 },
1059 ]
1059 ]
1060
1060
1061 def test_paths_slow_traversing(self):
1061 def test_paths_slow_traversing(self):
1062 commit = self.repo.get_commit()
1062 commit = self.repo.get_commit()
1063 assert commit.get_node('foobar').get_node('static').get_node('js')\
1063 assert commit.get_node('foobar').get_node('static').get_node('js')\
1064 .get_node('admin').get_node('base.js').content == 'base'
1064 .get_node('admin').get_node('base.js').content == 'base'
1065
1065
1066 def test_paths_fast_traversing(self):
1066 def test_paths_fast_traversing(self):
1067 commit = self.repo.get_commit()
1067 commit = self.repo.get_commit()
1068 assert commit.get_node('foobar/static/js/admin/base.js').content == 'base'
1068 assert commit.get_node('foobar/static/js/admin/base.js').content == 'base'
1069
1069
1070 def test_get_diff_runs_git_command_with_hashes(self):
1070 def test_get_diff_runs_git_command_with_hashes(self):
1071 comm1 = self.repo[0]
1071 comm1 = self.repo[0]
1072 comm2 = self.repo[1]
1072 comm2 = self.repo[1]
1073
1073
1074 with mock.patch.object(self.repo, '_remote') as remote_mock:
1074 with mock.patch.object(self.repo, '_remote') as remote_mock:
1075 self.repo.get_diff(comm1, comm2)
1075 self.repo.get_diff(comm1, comm2)
1076
1076
1077 remote_mock.diff.assert_called_once_with(
1077 remote_mock.diff.assert_called_once_with(
1078 comm1.raw_id, comm2.raw_id,
1078 comm1.raw_id, comm2.raw_id,
1079 file_filter=None, opt_ignorews=False, context=3)
1079 file_filter=None, opt_ignorews=False, context=3)
1080
1080
1081 def test_get_diff_runs_git_command_with_str_hashes(self):
1081 def test_get_diff_runs_git_command_with_str_hashes(self):
1082 comm2 = self.repo[1]
1082 comm2 = self.repo[1]
1083 with mock.patch.object(self.repo, '_remote') as remote_mock:
1083 with mock.patch.object(self.repo, '_remote') as remote_mock:
1084 self.repo.get_diff(self.repo.EMPTY_COMMIT, comm2)
1084 self.repo.get_diff(self.repo.EMPTY_COMMIT, comm2)
1085 remote_mock.diff.assert_called_once_with(
1085 remote_mock.diff.assert_called_once_with(
1086 self.repo.EMPTY_COMMIT.raw_id, comm2.raw_id,
1086 self.repo.EMPTY_COMMIT.raw_id, comm2.raw_id,
1087 file_filter=None, opt_ignorews=False, context=3)
1087 file_filter=None, opt_ignorews=False, context=3)
1088
1088
1089 def test_get_diff_runs_git_command_with_path_if_its_given(self):
1089 def test_get_diff_runs_git_command_with_path_if_its_given(self):
1090 comm1 = self.repo[0]
1090 comm1 = self.repo[0]
1091 comm2 = self.repo[1]
1091 comm2 = self.repo[1]
1092 with mock.patch.object(self.repo, '_remote') as remote_mock:
1092 with mock.patch.object(self.repo, '_remote') as remote_mock:
1093 self.repo.get_diff(comm1, comm2, 'foo')
1093 self.repo.get_diff(comm1, comm2, 'foo')
1094 remote_mock.diff.assert_called_once_with(
1094 remote_mock.diff.assert_called_once_with(
1095 self.repo._lookup_commit(0), comm2.raw_id,
1095 self.repo._lookup_commit(0), comm2.raw_id,
1096 file_filter='foo', opt_ignorews=False, context=3)
1096 file_filter='foo', opt_ignorews=False, context=3)
1097
1097
1098
1098
1099 @pytest.mark.usefixtures("vcs_repository_support")
1099 @pytest.mark.usefixtures("vcs_repository_support")
1100 class TestGitRegression(BackendTestMixin):
1100 class TestGitRegression(BackendTestMixin):
1101
1101
1102 @classmethod
1102 @classmethod
1103 def _get_commits(cls):
1103 def _get_commits(cls):
1104 return [
1104 return [
1105 {
1105 {
1106 'message': 'Initial',
1106 'message': 'Initial',
1107 'author': 'Joe Doe <joe.doe@example.com>',
1107 'author': 'Joe Doe <joe.doe@example.com>',
1108 'date': datetime.datetime(2010, 1, 1, 20),
1108 'date': datetime.datetime(2010, 1, 1, 20),
1109 'added': [
1109 'added': [
1110 FileNode('bot/__init__.py', content='base'),
1110 FileNode('bot/__init__.py', content='base'),
1111 FileNode('bot/templates/404.html', content='base'),
1111 FileNode('bot/templates/404.html', content='base'),
1112 FileNode('bot/templates/500.html', content='base'),
1112 FileNode('bot/templates/500.html', content='base'),
1113 ],
1113 ],
1114 },
1114 },
1115 {
1115 {
1116 'message': 'Second',
1116 'message': 'Second',
1117 'author': 'Joe Doe <joe.doe@example.com>',
1117 'author': 'Joe Doe <joe.doe@example.com>',
1118 'date': datetime.datetime(2010, 1, 1, 22),
1118 'date': datetime.datetime(2010, 1, 1, 22),
1119 'added': [
1119 'added': [
1120 FileNode('bot/build/migrations/1.py', content='foo2'),
1120 FileNode('bot/build/migrations/1.py', content='foo2'),
1121 FileNode('bot/build/migrations/2.py', content='foo2'),
1121 FileNode('bot/build/migrations/2.py', content='foo2'),
1122 FileNode(
1122 FileNode(
1123 'bot/build/static/templates/f.html', content='foo2'),
1123 'bot/build/static/templates/f.html', content='foo2'),
1124 FileNode(
1124 FileNode(
1125 'bot/build/static/templates/f1.html', content='foo2'),
1125 'bot/build/static/templates/f1.html', content='foo2'),
1126 FileNode('bot/build/templates/err.html', content='foo2'),
1126 FileNode('bot/build/templates/err.html', content='foo2'),
1127 FileNode('bot/build/templates/err2.html', content='foo2'),
1127 FileNode('bot/build/templates/err2.html', content='foo2'),
1128 ],
1128 ],
1129 },
1129 },
1130 ]
1130 ]
1131
1131
1132 @pytest.mark.parametrize("path, expected_paths", [
1132 @pytest.mark.parametrize("path, expected_paths", [
1133 ('bot', [
1133 ('bot', [
1134 'bot/build',
1134 'bot/build',
1135 'bot/templates',
1135 'bot/templates',
1136 'bot/__init__.py']),
1136 'bot/__init__.py']),
1137 ('bot/build', [
1137 ('bot/build', [
1138 'bot/build/migrations',
1138 'bot/build/migrations',
1139 'bot/build/static',
1139 'bot/build/static',
1140 'bot/build/templates']),
1140 'bot/build/templates']),
1141 ('bot/build/static', [
1141 ('bot/build/static', [
1142 'bot/build/static/templates']),
1142 'bot/build/static/templates']),
1143 ('bot/build/static/templates', [
1143 ('bot/build/static/templates', [
1144 'bot/build/static/templates/f.html',
1144 'bot/build/static/templates/f.html',
1145 'bot/build/static/templates/f1.html']),
1145 'bot/build/static/templates/f1.html']),
1146 ('bot/build/templates', [
1146 ('bot/build/templates', [
1147 'bot/build/templates/err.html',
1147 'bot/build/templates/err.html',
1148 'bot/build/templates/err2.html']),
1148 'bot/build/templates/err2.html']),
1149 ('bot/templates/', [
1149 ('bot/templates/', [
1150 'bot/templates/404.html',
1150 'bot/templates/404.html',
1151 'bot/templates/500.html']),
1151 'bot/templates/500.html']),
1152 ])
1152 ])
1153 def test_similar_paths(self, path, expected_paths):
1153 def test_similar_paths(self, path, expected_paths):
1154 commit = self.repo.get_commit()
1154 commit = self.repo.get_commit()
1155 paths = [n.path for n in commit.get_nodes(path)]
1155 paths = [n.path for n in commit.get_nodes(path)]
1156 assert paths == expected_paths
1156 assert paths == expected_paths
1157
1157
1158
1158
1159 class TestDiscoverGitVersion(object):
1159 class TestDiscoverGitVersion(object):
1160
1160
1161 def test_returns_git_version(self, baseapp):
1161 def test_returns_git_version(self, baseapp):
1162 version = discover_git_version()
1162 version = discover_git_version()
1163 assert version
1163 assert version
1164
1164
1165 def test_returns_empty_string_without_vcsserver(self):
1165 def test_returns_empty_string_without_vcsserver(self):
1166 mock_connection = mock.Mock()
1166 mock_connection = mock.Mock()
1167 mock_connection.discover_git_version = mock.Mock(
1167 mock_connection.discover_git_version = mock.Mock(
1168 side_effect=Exception)
1168 side_effect=Exception)
1169 with mock.patch('rhodecode.lib.vcs.connection.Git', mock_connection):
1169 with mock.patch('rhodecode.lib.vcs.connection.Git', mock_connection):
1170 version = discover_git_version()
1170 version = discover_git_version()
1171 assert version == ''
1171 assert version == ''
1172
1172
1173
1173
1174 class TestGetSubmoduleUrl(object):
1174 class TestGetSubmoduleUrl(object):
1175 def test_submodules_file_found(self):
1175 def test_submodules_file_found(self):
1176 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1176 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1177 node = mock.Mock()
1177 node = mock.Mock()
1178 with mock.patch.object(
1178 with mock.patch.object(
1179 commit, 'get_node', return_value=node) as get_node_mock:
1179 commit, 'get_node', return_value=node) as get_node_mock:
1180 node.content = (
1180 node.content = (
1181 '[submodule "subrepo1"]\n'
1181 '[submodule "subrepo1"]\n'
1182 '\tpath = subrepo1\n'
1182 '\tpath = subrepo1\n'
1183 '\turl = https://code.rhodecode.com/dulwich\n'
1183 '\turl = https://code.rhodecode.com/dulwich\n'
1184 )
1184 )
1185 result = commit._get_submodule_url('subrepo1')
1185 result = commit._get_submodule_url('subrepo1')
1186 get_node_mock.assert_called_once_with('.gitmodules')
1186 get_node_mock.assert_called_once_with('.gitmodules')
1187 assert result == 'https://code.rhodecode.com/dulwich'
1187 assert result == 'https://code.rhodecode.com/dulwich'
1188
1188
1189 def test_complex_submodule_path(self):
1189 def test_complex_submodule_path(self):
1190 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1190 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1191 node = mock.Mock()
1191 node = mock.Mock()
1192 with mock.patch.object(
1192 with mock.patch.object(
1193 commit, 'get_node', return_value=node) as get_node_mock:
1193 commit, 'get_node', return_value=node) as get_node_mock:
1194 node.content = (
1194 node.content = (
1195 '[submodule "complex/subrepo/path"]\n'
1195 '[submodule "complex/subrepo/path"]\n'
1196 '\tpath = complex/subrepo/path\n'
1196 '\tpath = complex/subrepo/path\n'
1197 '\turl = https://code.rhodecode.com/dulwich\n'
1197 '\turl = https://code.rhodecode.com/dulwich\n'
1198 )
1198 )
1199 result = commit._get_submodule_url('complex/subrepo/path')
1199 result = commit._get_submodule_url('complex/subrepo/path')
1200 get_node_mock.assert_called_once_with('.gitmodules')
1200 get_node_mock.assert_called_once_with('.gitmodules')
1201 assert result == 'https://code.rhodecode.com/dulwich'
1201 assert result == 'https://code.rhodecode.com/dulwich'
1202
1202
1203 def test_submodules_file_not_found(self):
1203 def test_submodules_file_not_found(self):
1204 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1204 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1205 with mock.patch.object(
1205 with mock.patch.object(
1206 commit, 'get_node', side_effect=NodeDoesNotExistError):
1206 commit, 'get_node', side_effect=NodeDoesNotExistError):
1207 result = commit._get_submodule_url('complex/subrepo/path')
1207 result = commit._get_submodule_url('complex/subrepo/path')
1208 assert result is None
1208 assert result is None
1209
1209
1210 def test_path_not_found(self):
1210 def test_path_not_found(self):
1211 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1211 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1212 node = mock.Mock()
1212 node = mock.Mock()
1213 with mock.patch.object(
1213 with mock.patch.object(
1214 commit, 'get_node', return_value=node) as get_node_mock:
1214 commit, 'get_node', return_value=node) as get_node_mock:
1215 node.content = (
1215 node.content = (
1216 '[submodule "subrepo1"]\n'
1216 '[submodule "subrepo1"]\n'
1217 '\tpath = subrepo1\n'
1217 '\tpath = subrepo1\n'
1218 '\turl = https://code.rhodecode.com/dulwich\n'
1218 '\turl = https://code.rhodecode.com/dulwich\n'
1219 )
1219 )
1220 result = commit._get_submodule_url('subrepo2')
1220 result = commit._get_submodule_url('subrepo2')
1221 get_node_mock.assert_called_once_with('.gitmodules')
1221 get_node_mock.assert_called_once_with('.gitmodules')
1222 assert result is None
1222 assert result is None
1223
1223
1224 def test_returns_cached_values(self):
1224 def test_returns_cached_values(self):
1225 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1225 commit = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1)
1226 node = mock.Mock()
1226 node = mock.Mock()
1227 with mock.patch.object(
1227 with mock.patch.object(
1228 commit, 'get_node', return_value=node) as get_node_mock:
1228 commit, 'get_node', return_value=node) as get_node_mock:
1229 node.content = (
1229 node.content = (
1230 '[submodule "subrepo1"]\n'
1230 '[submodule "subrepo1"]\n'
1231 '\tpath = subrepo1\n'
1231 '\tpath = subrepo1\n'
1232 '\turl = https://code.rhodecode.com/dulwich\n'
1232 '\turl = https://code.rhodecode.com/dulwich\n'
1233 )
1233 )
1234 for _ in range(3):
1234 for _ in range(3):
1235 commit._get_submodule_url('subrepo1')
1235 commit._get_submodule_url('subrepo1')
1236 get_node_mock.assert_called_once_with('.gitmodules')
1236 get_node_mock.assert_called_once_with('.gitmodules')
1237
1237
1238 def test_get_node_returns_a_link(self):
1238 def test_get_node_returns_a_link(self):
1239 repository = mock.Mock()
1239 repository = mock.Mock()
1240 repository.alias = 'git'
1240 repository.alias = 'git'
1241 commit = GitCommit(repository=repository, raw_id='abcdef12', idx=1)
1241 commit = GitCommit(repository=repository, raw_id='abcdef12', idx=1)
1242 submodule_url = 'https://code.rhodecode.com/dulwich'
1242 submodule_url = 'https://code.rhodecode.com/dulwich'
1243 get_id_patch = mock.patch.object(
1243 get_id_patch = mock.patch.object(
1244 commit, '_get_tree_id_for_path', return_value=(1, 'link'))
1244 commit, '_get_tree_id_for_path', return_value=(1, 'link'))
1245 get_submodule_patch = mock.patch.object(
1245 get_submodule_patch = mock.patch.object(
1246 commit, '_get_submodule_url', return_value=submodule_url)
1246 commit, '_get_submodule_url', return_value=submodule_url)
1247
1247
1248 with get_id_patch, get_submodule_patch as submodule_mock:
1248 with get_id_patch, get_submodule_patch as submodule_mock:
1249 node = commit.get_node('/abcde')
1249 node = commit.get_node('/abcde')
1250
1250
1251 submodule_mock.assert_called_once_with('/abcde')
1251 submodule_mock.assert_called_once_with('/abcde')
1252 assert type(node) == SubModuleNode
1252 assert type(node) == SubModuleNode
1253 assert node.url == submodule_url
1253 assert node.url == submodule_url
1254
1254
1255 def test_get_nodes_returns_links(self):
1255 def test_get_nodes_returns_links(self):
1256 repository = mock.MagicMock()
1256 repository = mock.MagicMock()
1257 repository.alias = 'git'
1257 repository.alias = 'git'
1258 repository._remote.tree_items.return_value = [
1258 repository._remote.tree_items.return_value = [
1259 ('subrepo', 'stat', 1, 'link')
1259 ('subrepo', 'stat', 1, 'link')
1260 ]
1260 ]
1261 commit = GitCommit(repository=repository, raw_id='abcdef12', idx=1)
1261 commit = GitCommit(repository=repository, raw_id='abcdef12', idx=1)
1262 submodule_url = 'https://code.rhodecode.com/dulwich'
1262 submodule_url = 'https://code.rhodecode.com/dulwich'
1263 get_id_patch = mock.patch.object(
1263 get_id_patch = mock.patch.object(
1264 commit, '_get_tree_id_for_path', return_value=(1, 'tree'))
1264 commit, '_get_tree_id_for_path', return_value=(1, 'tree'))
1265 get_submodule_patch = mock.patch.object(
1265 get_submodule_patch = mock.patch.object(
1266 commit, '_get_submodule_url', return_value=submodule_url)
1266 commit, '_get_submodule_url', return_value=submodule_url)
1267
1267
1268 with get_id_patch, get_submodule_patch as submodule_mock:
1268 with get_id_patch, get_submodule_patch as submodule_mock:
1269 nodes = commit.get_nodes('/abcde')
1269 nodes = commit.get_nodes('/abcde')
1270
1270
1271 submodule_mock.assert_called_once_with('/abcde/subrepo')
1271 submodule_mock.assert_called_once_with('/abcde/subrepo')
1272 assert len(nodes) == 1
1272 assert len(nodes) == 1
1273 assert type(nodes[0]) == SubModuleNode
1273 assert type(nodes[0]) == SubModuleNode
1274 assert nodes[0].url == submodule_url
1274 assert nodes[0].url == submodule_url
General Comments 0
You need to be logged in to leave comments. Login now