Show More
@@ -0,0 +1,26 b'' | |||||
|
1 | diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt | |||
|
2 | --- a/Documentation/git-send-email.txt | |||
|
3 | +++ b/Documentation/git-send-email.txt | |||
|
4 | @@ -208,8 +208,7 @@ a password is obtained using 'git-credential'. | |||
|
5 | specify a full pathname of a sendmail-like program instead; | |||
|
6 | the program must support the `-i` option. Default value can | |||
|
7 | be specified by the `sendemail.smtpServer` configuration | |||
|
8 | - option; the built-in default is to search for `sendmail` in | |||
|
9 | - `/usr/sbin`, `/usr/lib` and $PATH if such program is | |||
|
10 | + option; the built-in default is to search in $PATH if such program is | |||
|
11 | available, falling back to `localhost` otherwise. | |||
|
12 | ||||
|
13 | --smtp-server-port=<port>:: | |||
|
14 | diff --git a/git-send-email.perl b/git-send-email.perl | |||
|
15 | --- a/git-send-email.perl | |||
|
16 | +++ b/git-send-email.perl | |||
|
17 | @@ -944,8 +944,7 @@ if (defined $reply_to) { | |||
|
18 | } | |||
|
19 | ||||
|
20 | if (!defined $smtp_server) { | |||
|
21 | - my @sendmail_paths = qw( /usr/sbin/sendmail /usr/lib/sendmail ); | |||
|
22 | - push @sendmail_paths, map {"$_/sendmail"} split /:/, $ENV{PATH}; | |||
|
23 | + my @sendmail_paths = map {"$_/sendmail"} split /:/, $ENV{PATH}; | |||
|
24 | foreach (@sendmail_paths) { | |||
|
25 | if (-x $_) { | |||
|
26 | $smtp_server = $_; |
@@ -0,0 +1,12 b'' | |||||
|
1 | diff --git a/t/test-lib.sh b/t/test-lib.sh | |||
|
2 | --- a/t/test-lib.sh | |||
|
3 | +++ b/t/test-lib.sh | |||
|
4 | @@ -923,7 +923,7 @@ | |||
|
5 | then | |||
|
6 | GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path) || | |||
|
7 | error "Cannot run git from $GIT_TEST_INSTALLED." | |||
|
8 | - PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH | |||
|
9 | + PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$GIT_BUILD_DIR:$PATH | |||
|
10 | GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH} | |||
|
11 | else # normal case, use ../bin-wrappers only unless $with_dashes: | |||
|
12 | git_bin_dir="$GIT_BUILD_DIR/bin-wrappers" |
@@ -1,5 +1,5 b'' | |||||
1 | [bumpversion] |
|
1 | [bumpversion] | |
2 |
current_version = 4.1 |
|
2 | current_version = 4.15.0 | |
3 | message = release: Bump version {current_version} to {new_version} |
|
3 | message = release: Bump version {current_version} to {new_version} | |
4 |
|
4 | |||
5 | [bumpversion:file:vcsserver/VERSION] |
|
5 | [bumpversion:file:vcsserver/VERSION] |
@@ -5,12 +5,10 b' done = false' | |||||
5 | done = true |
|
5 | done = true | |
6 |
|
6 | |||
7 | [task:fixes_on_stable] |
|
7 | [task:fixes_on_stable] | |
8 | done = true |
|
|||
9 |
|
8 | |||
10 | [task:pip2nix_generated] |
|
9 | [task:pip2nix_generated] | |
11 | done = true |
|
|||
12 |
|
10 | |||
13 | [release] |
|
11 | [release] | |
14 |
state = |
|
12 | state = in_progress | |
15 |
version = 4.1 |
|
13 | version = 4.15.0 | |
16 |
|
14 |
@@ -1,17 +1,19 b'' | |||||
1 | self: super: { |
|
1 | self: super: { | |
2 | # bump GIT version |
|
2 | # bump GIT version | |
3 | git = super.lib.overrideDerivation super.git (oldAttrs: { |
|
3 | git = super.lib.overrideDerivation super.git (oldAttrs: { | |
4 |
name = "git-2.1 |
|
4 | name = "git-2.19.1"; | |
5 | src = self.fetchurl { |
|
5 | src = self.fetchurl { | |
6 |
url = "https://www.kernel.org/pub/software/scm/git/git-2.1 |
|
6 | url = "https://www.kernel.org/pub/software/scm/git/git-2.19.1.tar.xz"; | |
7 | sha256 = "1ghljlxmyqphx13qspy382cpl2pbkbwbhqm7w7z57r9mkhswx668"; |
|
7 | sha256 = "1dfv43lmdnxz42504jc89sihbv1d4d6kgqcz3c5ji140kfm5cl1l"; | |
8 | }; |
|
8 | }; | |
9 |
|
9 | |||
|
10 | # patches come from: https://github.com/NixOS/nixpkgs/tree/master/pkgs/applications/version-management/git-and-tools/git | |||
10 | patches = [ |
|
11 | patches = [ | |
11 | ./patches/git/docbook2texi.patch |
|
12 | ./patches/git/docbook2texi.patch | |
12 | ./patches/git/symlinks-in-bin.patch |
|
|||
13 | ./patches/git/git-sh-i18n.patch |
|
13 | ./patches/git/git-sh-i18n.patch | |
14 | ./patches/git/ssh-path.patch |
|
14 | ./patches/git/ssh-path.patch | |
|
15 | ./patches/git/git-send-email-honor-PATH.patch | |||
|
16 | ./patches/git/installCheck-path.patch | |||
15 | ]; |
|
17 | ]; | |
16 |
|
18 | |||
17 | }); |
|
19 | }); |
@@ -2,29 +2,29 b' This patch does two things: (1) use the ' | |||||
2 | and (2) make sure `gitman.info' isn't produced since it's broken (duplicate |
|
2 | and (2) make sure `gitman.info' isn't produced since it's broken (duplicate | |
3 | node names). |
|
3 | node names). | |
4 |
|
4 | |||
5 |
diff - |
|
5 | diff --git a/Documentation/Makefile b/Documentation/Makefile | |
6 | --- git-1.8.4-orig/Documentation/Makefile 2013-08-23 21:38:43.000000000 +0200 |
|
6 | --- a/Documentation/Makefile | |
7 | +++ git-1.8.4/Documentation/Makefile 2013-09-30 14:48:51.532890378 +0200 |
|
7 | +++ b/Documentation/Makefile | |
8 |
@@ -1 |
|
8 | @@ -122,7 +122,7 @@ | |
9 |
|
9 | |||
10 | MAKEINFO = makeinfo |
|
10 | MAKEINFO = makeinfo | |
11 | INSTALL_INFO = install-info |
|
11 | INSTALL_INFO = install-info | |
12 | -DOCBOOK2X_TEXI = docbook2x-texi |
|
12 | -DOCBOOK2X_TEXI = docbook2x-texi | |
13 | +DOCBOOK2X_TEXI = docbook2texi |
|
13 | +DOCBOOK2X_TEXI = docbook2texi | |
14 | DBLATEX = dblatex |
|
14 | DBLATEX = dblatex | |
15 | ifndef PERL_PATH |
|
15 | ASCIIDOC_DBLATEX_DIR = /etc/asciidoc/dblatex | |
16 | PERL_PATH = /usr/bin/perl |
|
16 | DBLATEX_COMMON = -p $(ASCIIDOC_DBLATEX_DIR)/asciidoc-dblatex.xsl -s $(ASCIIDOC_DBLATEX_DIR)/asciidoc-dblatex.sty | |
17 |
@@ -20 |
|
17 | @@ -240,7 +240,7 @@ | |
18 | man5: $(DOC_MAN5) |
|
18 | man5: $(DOC_MAN5) | |
19 | man7: $(DOC_MAN7) |
|
19 | man7: $(DOC_MAN7) | |
20 |
|
20 | |||
21 | -info: git.info gitman.info |
|
21 | -info: git.info gitman.info | |
22 | +info: git.info |
|
22 | +info: git.info | |
23 |
|
23 | |||
24 | pdf: user-manual.pdf |
|
24 | pdf: user-manual.pdf | |
25 |
|
25 | |||
26 |
@@ -2 |
|
26 | @@ -256,10 +256,9 @@ | |
27 |
|
27 | |||
28 | install-info: info |
|
28 | install-info: info | |
29 | $(INSTALL) -d -m 755 $(DESTDIR)$(infodir) |
|
29 | $(INSTALL) -d -m 755 $(DESTDIR)$(infodir) | |
30 | - $(INSTALL) -m 644 git.info gitman.info $(DESTDIR)$(infodir) |
|
30 | - $(INSTALL) -m 644 git.info gitman.info $(DESTDIR)$(infodir) |
@@ -154,14 +154,14 b' self: super: {' | |||||
154 | }; |
|
154 | }; | |
155 | }; |
|
155 | }; | |
156 | "gevent" = super.buildPythonPackage { |
|
156 | "gevent" = super.buildPythonPackage { | |
157 |
name = "gevent-1.3. |
|
157 | name = "gevent-1.3.7"; | |
158 | doCheck = false; |
|
158 | doCheck = false; | |
159 | propagatedBuildInputs = [ |
|
159 | propagatedBuildInputs = [ | |
160 | self."greenlet" |
|
160 | self."greenlet" | |
161 | ]; |
|
161 | ]; | |
162 | src = fetchurl { |
|
162 | src = fetchurl { | |
163 |
url = "https://files.pythonhosted.org/packages/49 |
|
163 | url = "https://files.pythonhosted.org/packages/10/c1/9499b146bfa43aa4f1e0ed1bab1bd3209a4861d25650c11725036c731cf5/gevent-1.3.7.tar.gz"; | |
164 | sha256 = "1ih4k73dqz2zb561hda99vbanja3m6cdch3mgxxn1mla3qwkqhbv"; |
|
164 | sha256 = "0b0fr04qdk1p4sniv87fh8z5psac60x01pv054kpgi94520g81iz"; | |
165 | }; |
|
165 | }; | |
166 | meta = { |
|
166 | meta = { | |
167 | license = [ pkgs.lib.licenses.mit ]; |
|
167 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -212,26 +212,26 b' self: super: {' | |||||
212 | }; |
|
212 | }; | |
213 | }; |
|
213 | }; | |
214 | "hgsubversion" = super.buildPythonPackage { |
|
214 | "hgsubversion" = super.buildPythonPackage { | |
215 |
name = "hgsubversion-1.9. |
|
215 | name = "hgsubversion-1.9.3"; | |
216 | doCheck = false; |
|
216 | doCheck = false; | |
217 | propagatedBuildInputs = [ |
|
217 | propagatedBuildInputs = [ | |
218 | self."mercurial" |
|
218 | self."mercurial" | |
219 | self."subvertpy" |
|
219 | self."subvertpy" | |
220 | ]; |
|
220 | ]; | |
221 | src = fetchurl { |
|
221 | src = fetchurl { | |
222 |
url = "https://files.pythonhosted.org/packages/05 |
|
222 | url = "https://files.pythonhosted.org/packages/a3/53/6d205e641f3e09abcf1ddaed66e5e4b20da22d0145566d440a02c9e35f0d/hgsubversion-1.9.3.tar.gz"; | |
223 | sha256 = "16490narhq14vskml3dam8g5y3w3hdqj3g8bgm2b0c0i85l1xvcz"; |
|
223 | sha256 = "0nymcjlch8c4zjbncrs30p2nrbylsf25g3h6mr0zzzxr141h3sig"; | |
224 | }; |
|
224 | }; | |
225 | meta = { |
|
225 | meta = { | |
226 | license = [ pkgs.lib.licenses.gpl1 ]; |
|
226 | license = [ pkgs.lib.licenses.gpl1 ]; | |
227 | }; |
|
227 | }; | |
228 | }; |
|
228 | }; | |
229 | "hupper" = super.buildPythonPackage { |
|
229 | "hupper" = super.buildPythonPackage { | |
230 |
name = "hupper-1. |
|
230 | name = "hupper-1.4.2"; | |
231 | doCheck = false; |
|
231 | doCheck = false; | |
232 | src = fetchurl { |
|
232 | src = fetchurl { | |
233 | url = "https://files.pythonhosted.org/packages/cf/4b/467b826a84c8594b81f414b5ab6794e981951dac90ca40abaf9ea1cb36b0/hupper-1.3.1.tar.gz"; |
|
233 | url = "https://files.pythonhosted.org/packages/f1/75/1915dc7650b4867fa3049256e24ca8eddb5989998fcec788cf52b9812dfc/hupper-1.4.2.tar.gz"; | |
234 | sha256 = "03mf13n6i4dd60wlb9m99ddl4m3lmly70cjp7f82vdkibfl1v6l9"; |
|
234 | sha256 = "16vb9fkiaakdpcp6pn56h3w0dwvm67bxq2k2dv4i382qhqwphdzb"; | |
235 | }; |
|
235 | }; | |
236 | meta = { |
|
236 | meta = { | |
237 | license = [ pkgs.lib.licenses.mit ]; |
|
237 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -502,11 +502,11 b' self: super: {' | |||||
502 | }; |
|
502 | }; | |
503 | }; |
|
503 | }; | |
504 | "pygments" = super.buildPythonPackage { |
|
504 | "pygments" = super.buildPythonPackage { | |
505 |
name = "pygments-2. |
|
505 | name = "pygments-2.3.0"; | |
506 | doCheck = false; |
|
506 | doCheck = false; | |
507 | src = fetchurl { |
|
507 | src = fetchurl { | |
508 |
url = "https://files.pythonhosted.org/packages/ |
|
508 | url = "https://files.pythonhosted.org/packages/63/a2/91c31c4831853dedca2a08a0f94d788fc26a48f7281c99a303769ad2721b/Pygments-2.3.0.tar.gz"; | |
509 | sha256 = "1k78qdvir1yb1c634nkv6rbga8wv4289xarghmsbbvzhvr311bnv"; |
|
509 | sha256 = "1z34ms51dh4jq4h3cizp7vd1dmsxcbvffkjsd2xxfav22nn6lrl2"; | |
510 | }; |
|
510 | }; | |
511 | meta = { |
|
511 | meta = { | |
512 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
512 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -656,7 +656,7 b' self: super: {' | |||||
656 | }; |
|
656 | }; | |
657 | }; |
|
657 | }; | |
658 | "rhodecode-vcsserver" = super.buildPythonPackage { |
|
658 | "rhodecode-vcsserver" = super.buildPythonPackage { | |
659 |
name = "rhodecode-vcsserver-4.1 |
|
659 | name = "rhodecode-vcsserver-4.15.0"; | |
660 | buildInputs = [ |
|
660 | buildInputs = [ | |
661 | self."pytest" |
|
661 | self."pytest" | |
662 | self."py" |
|
662 | self."py" | |
@@ -750,11 +750,11 b' self: super: {' | |||||
750 | }; |
|
750 | }; | |
751 | }; |
|
751 | }; | |
752 | "setuptools" = super.buildPythonPackage { |
|
752 | "setuptools" = super.buildPythonPackage { | |
753 |
name = "setuptools-40. |
|
753 | name = "setuptools-40.6.2"; | |
754 | doCheck = false; |
|
754 | doCheck = false; | |
755 | src = fetchurl { |
|
755 | src = fetchurl { | |
756 |
url = "https://files.pythonhosted.org/packages/6 |
|
756 | url = "https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip"; | |
757 | sha256 = "058v6zns4634n4al2nmmvp15j8nrgwn8wjrbdks47wk3vm05gg5c"; |
|
757 | sha256 = "0r2c5hapirlzm34h7pl1lgkm6gk7bcrlrdj28qgsvaqg3f74vfw6"; | |
758 | }; |
|
758 | }; | |
759 | meta = { |
|
759 | meta = { | |
760 | license = [ pkgs.lib.licenses.mit ]; |
|
760 | license = [ pkgs.lib.licenses.mit ]; |
@@ -8,7 +8,7 b' dogpile.cache==0.6.7' | |||||
8 | dogpile.core==0.4.1 |
|
8 | dogpile.core==0.4.1 | |
9 | decorator==4.1.2 |
|
9 | decorator==4.1.2 | |
10 | dulwich==0.13.0 |
|
10 | dulwich==0.13.0 | |
11 |
hgsubversion==1.9. |
|
11 | hgsubversion==1.9.3 | |
12 | hg-evolve==8.0.1 |
|
12 | hg-evolve==8.0.1 | |
13 | mako==1.0.7 |
|
13 | mako==1.0.7 | |
14 | markupsafe==1.0.0 |
|
14 | markupsafe==1.0.0 | |
@@ -20,7 +20,7 b' psutil==5.4.7' | |||||
20 | pyramid==1.9.2 |
|
20 | pyramid==1.9.2 | |
21 | pyramid-mako==1.0.2 |
|
21 | pyramid-mako==1.0.2 | |
22 |
|
22 | |||
23 |
pygments==2. |
|
23 | pygments==2.3.0 | |
24 | pathlib2==2.3.2 |
|
24 | pathlib2==2.3.2 | |
25 | repoze.lru==0.7 |
|
25 | repoze.lru==0.7 | |
26 | simplejson==3.11.1 |
|
26 | simplejson==3.11.1 | |
@@ -34,7 +34,7 b' zope.deprecation==4.3.0' | |||||
34 | zope.interface==4.5.0 |
|
34 | zope.interface==4.5.0 | |
35 |
|
35 | |||
36 | ## http servers |
|
36 | ## http servers | |
37 |
gevent==1.3. |
|
37 | gevent==1.3.7 | |
38 | greenlet==0.4.15 |
|
38 | greenlet==0.4.15 | |
39 | gunicorn==19.9.0 |
|
39 | gunicorn==19.9.0 | |
40 | waitress==1.1.0 |
|
40 | waitress==1.1.0 |
@@ -518,15 +518,6 b' class GitRemote(object):' | |||||
518 | return repo.get_description() |
|
518 | return repo.get_description() | |
519 |
|
519 | |||
520 | @reraise_safe_exceptions |
|
520 | @reraise_safe_exceptions | |
521 | def get_file_history(self, wire, file_path, commit_id, limit): |
|
|||
522 | repo = self._factory.repo(wire) |
|
|||
523 | include = [commit_id] |
|
|||
524 | paths = [file_path] |
|
|||
525 |
|
||||
526 | walker = repo.get_walker(include, paths=paths, max_entries=limit) |
|
|||
527 | return [x.commit.id for x in walker] |
|
|||
528 |
|
||||
529 | @reraise_safe_exceptions |
|
|||
530 | def get_missing_revs(self, wire, rev1, rev2, path2): |
|
521 | def get_missing_revs(self, wire, rev1, rev2, path2): | |
531 | repo = self._factory.repo(wire) |
|
522 | repo = self._factory.repo(wire) | |
532 | LocalGitClient(thin_packs=False).fetch(path2, repo) |
|
523 | LocalGitClient(thin_packs=False).fetch(path2, repo) |
@@ -417,7 +417,7 b' class HgRemote(object):' | |||||
417 | raise exceptions.LookupException(e)() |
|
417 | raise exceptions.LookupException(e)() | |
418 |
|
418 | |||
419 | @reraise_safe_exceptions |
|
419 | @reraise_safe_exceptions | |
420 |
def |
|
420 | def node_history(self, wire, revision, path, limit): | |
421 | repo = self._factory.repo(wire) |
|
421 | repo = self._factory.repo(wire) | |
422 |
|
422 | |||
423 | ctx = repo[revision] |
|
423 | ctx = repo[revision] | |
@@ -439,7 +439,7 b' class HgRemote(object):' | |||||
439 | return [x for x in history] |
|
439 | return [x for x in history] | |
440 |
|
440 | |||
441 | @reraise_safe_exceptions |
|
441 | @reraise_safe_exceptions | |
442 |
def |
|
442 | def node_history_untill(self, wire, revision, path, limit): | |
443 | repo = self._factory.repo(wire) |
|
443 | repo = self._factory.repo(wire) | |
444 | ctx = repo[revision] |
|
444 | ctx = repo[revision] | |
445 | fctx = ctx.filectx(path) |
|
445 | fctx = ctx.filectx(path) |
@@ -42,7 +42,7 b' def install_git_hooks(repo_path, bare, e' | |||||
42 | if not bare: |
|
42 | if not bare: | |
43 | hooks_path = os.path.join(repo_path, '.git', 'hooks') |
|
43 | hooks_path = os.path.join(repo_path, '.git', 'hooks') | |
44 | if not os.path.isdir(hooks_path): |
|
44 | if not os.path.isdir(hooks_path): | |
45 | os.makedirs(hooks_path, mode=0777) |
|
45 | os.makedirs(hooks_path, mode=0o777) | |
46 |
|
46 | |||
47 | tmpl_post = pkg_resources.resource_string( |
|
47 | tmpl_post = pkg_resources.resource_string( | |
48 | 'vcsserver', '/'.join( |
|
48 | 'vcsserver', '/'.join( | |
@@ -69,7 +69,7 b' def install_git_hooks(repo_path, bare, e' | |||||
69 | template = template.replace('_ENV_', executable) |
|
69 | template = template.replace('_ENV_', executable) | |
70 | template = template.replace('_PATH_', path) |
|
70 | template = template.replace('_PATH_', path) | |
71 | f.write(template) |
|
71 | f.write(template) | |
72 | os.chmod(_hook_file, 0755) |
|
72 | os.chmod(_hook_file, 0o755) | |
73 | except IOError: |
|
73 | except IOError: | |
74 | log.exception('error writing hook file %s', _hook_file) |
|
74 | log.exception('error writing hook file %s', _hook_file) | |
75 | else: |
|
75 | else: | |
@@ -89,7 +89,7 b' def install_svn_hooks(repo_path, executa' | |||||
89 | executable = executable or sys.executable |
|
89 | executable = executable or sys.executable | |
90 | hooks_path = os.path.join(repo_path, 'hooks') |
|
90 | hooks_path = os.path.join(repo_path, 'hooks') | |
91 | if not os.path.isdir(hooks_path): |
|
91 | if not os.path.isdir(hooks_path): | |
92 | os.makedirs(hooks_path, mode=0777) |
|
92 | os.makedirs(hooks_path, mode=0o777) | |
93 |
|
93 | |||
94 | tmpl_post = pkg_resources.resource_string( |
|
94 | tmpl_post = pkg_resources.resource_string( | |
95 | 'vcsserver', '/'.join( |
|
95 | 'vcsserver', '/'.join( | |
@@ -118,7 +118,7 b' def install_svn_hooks(repo_path, executa' | |||||
118 | template = template.replace('_PATH_', path) |
|
118 | template = template.replace('_PATH_', path) | |
119 |
|
119 | |||
120 | f.write(template) |
|
120 | f.write(template) | |
121 | os.chmod(_hook_file, 0755) |
|
121 | os.chmod(_hook_file, 0o755) | |
122 | except IOError: |
|
122 | except IOError: | |
123 | log.exception('error writing hook file %s', _hook_file) |
|
123 | log.exception('error writing hook file %s', _hook_file) | |
124 | else: |
|
124 | else: |
@@ -52,7 +52,16 b' class HooksHttpClient(object):' | |||||
52 | log.error('Connection failed on %s', connection) |
|
52 | log.error('Connection failed on %s', connection) | |
53 | raise |
|
53 | raise | |
54 | response = connection.getresponse() |
|
54 | response = connection.getresponse() | |
55 | return json.loads(response.read()) |
|
55 | ||
|
56 | response_data = response.read() | |||
|
57 | ||||
|
58 | try: | |||
|
59 | return json.loads(response_data) | |||
|
60 | except Exception: | |||
|
61 | log.exception('Failed to decode hook response json data. ' | |||
|
62 | 'response_code:%s, raw_data:%s', | |||
|
63 | response.status, response_data) | |||
|
64 | raise | |||
56 |
|
65 | |||
57 | def _serialize(self, hook_name, extras): |
|
66 | def _serialize(self, hook_name, extras): | |
58 | data = { |
|
67 | data = { |
@@ -197,6 +197,28 b' class WsgiProxy(object):' | |||||
197 | yield msgpack.packb(d) |
|
197 | yield msgpack.packb(d) | |
198 |
|
198 | |||
199 |
|
199 | |||
|
200 | def not_found(request): | |||
|
201 | return {'status': '404 NOT FOUND'} | |||
|
202 | ||||
|
203 | ||||
|
204 | class VCSViewPredicate(object): | |||
|
205 | def __init__(self, val, config): | |||
|
206 | self.remotes = val | |||
|
207 | ||||
|
208 | def text(self): | |||
|
209 | return 'vcs view method = %s' % (self.remotes.keys(),) | |||
|
210 | ||||
|
211 | phash = text | |||
|
212 | ||||
|
213 | def __call__(self, context, request): | |||
|
214 | """ | |||
|
215 | View predicate that returns true if given backend is supported by | |||
|
216 | defined remotes. | |||
|
217 | """ | |||
|
218 | backend = request.matchdict.get('backend') | |||
|
219 | return backend in self.remotes | |||
|
220 | ||||
|
221 | ||||
200 | class HTTPApplication(object): |
|
222 | class HTTPApplication(object): | |
201 | ALLOWED_EXCEPTIONS = ('KeyError', 'URLError') |
|
223 | ALLOWED_EXCEPTIONS = ('KeyError', 'URLError') | |
202 |
|
224 | |||
@@ -256,7 +278,7 b' class HTTPApplication(object):' | |||||
256 |
|
278 | |||
257 | # ensure we have our dir created |
|
279 | # ensure we have our dir created | |
258 | if not os.path.isdir(default_cache_dir): |
|
280 | if not os.path.isdir(default_cache_dir): | |
259 | os.makedirs(default_cache_dir, mode=0755) |
|
281 | os.makedirs(default_cache_dir, mode=0o755) | |
260 |
|
282 | |||
261 | # exception store cache |
|
283 | # exception store cache | |
262 | _string_setting( |
|
284 | _string_setting( | |
@@ -279,9 +301,7 b' class HTTPApplication(object):' | |||||
279 | 1024) |
|
301 | 1024) | |
280 |
|
302 | |||
281 | def _configure(self): |
|
303 | def _configure(self): | |
282 | self.config.add_renderer( |
|
304 | self.config.add_renderer(name='msgpack', factory=self._msgpack_renderer_factory) | |
283 | name='msgpack', |
|
|||
284 | factory=self._msgpack_renderer_factory) |
|
|||
285 |
|
305 | |||
286 | self.config.add_route('service', '/_service') |
|
306 | self.config.add_route('service', '/_service') | |
287 | self.config.add_route('status', '/status') |
|
307 | self.config.add_route('status', '/status') | |
@@ -291,23 +311,20 b' class HTTPApplication(object):' | |||||
291 | self.config.add_route('stream_git', '/stream/git/*repo_name') |
|
311 | self.config.add_route('stream_git', '/stream/git/*repo_name') | |
292 | self.config.add_route('stream_hg', '/stream/hg/*repo_name') |
|
312 | self.config.add_route('stream_hg', '/stream/hg/*repo_name') | |
293 |
|
313 | |||
294 | self.config.add_view( |
|
314 | self.config.add_view(self.status_view, route_name='status', renderer='json') | |
295 |
|
|
315 | self.config.add_view(self.service_view, route_name='service', renderer='msgpack') | |
296 | self.config.add_view( |
|
|||
297 | self.service_view, route_name='service', renderer='msgpack') |
|
|||
298 |
|
316 | |||
299 | self.config.add_view(self.hg_proxy(), route_name='hg_proxy') |
|
317 | self.config.add_view(self.hg_proxy(), route_name='hg_proxy') | |
300 | self.config.add_view(self.git_proxy(), route_name='git_proxy') |
|
318 | self.config.add_view(self.git_proxy(), route_name='git_proxy') | |
301 | self.config.add_view( |
|
319 | self.config.add_view(self.vcs_view, route_name='vcs', renderer='msgpack', | |
302 | self.vcs_view, route_name='vcs', renderer='msgpack', |
|
320 | vcs_view=self._remotes) | |
303 | custom_predicates=[self.is_vcs_view]) |
|
|||
304 |
|
321 | |||
305 | self.config.add_view(self.hg_stream(), route_name='stream_hg') |
|
322 | self.config.add_view(self.hg_stream(), route_name='stream_hg') | |
306 | self.config.add_view(self.git_stream(), route_name='stream_git') |
|
323 | self.config.add_view(self.git_stream(), route_name='stream_git') | |
307 |
|
324 | |||
308 | def notfound(request): |
|
325 | self.config.add_view_predicate('vcs_view', VCSViewPredicate) | |
309 | return {'status': '404 NOT FOUND'} |
|
326 | ||
310 | self.config.add_notfound_view(notfound, renderer='json') |
|
327 | self.config.add_notfound_view(not_found, renderer='json') | |
311 |
|
328 | |||
312 | self.config.add_view(self.handle_vcs_exception, context=Exception) |
|
329 | self.config.add_view(self.handle_vcs_exception, context=Exception) | |
313 |
|
330 | |||
@@ -543,14 +560,6 b' class HTTPApplication(object):' | |||||
543 |
|
560 | |||
544 | return _git_stream |
|
561 | return _git_stream | |
545 |
|
562 | |||
546 | def is_vcs_view(self, context, request): |
|
|||
547 | """ |
|
|||
548 | View predicate that returns true if given backend is supported by |
|
|||
549 | defined remotes. |
|
|||
550 | """ |
|
|||
551 | backend = request.matchdict.get('backend') |
|
|||
552 | return backend in self._remotes |
|
|||
553 |
|
||||
554 | def handle_vcs_exception(self, exception, request): |
|
563 | def handle_vcs_exception(self, exception, request): | |
555 | _vcs_kind = getattr(exception, '_vcs_kind', '') |
|
564 | _vcs_kind = getattr(exception, '_vcs_kind', '') | |
556 | if _vcs_kind == 'repo_locked': |
|
565 | if _vcs_kind == 'repo_locked': |
@@ -36,8 +36,7 b' def environ():' | |||||
36 |
|
36 | |||
37 |
|
37 | |||
38 | def _get_python_args(script): |
|
38 | def _get_python_args(script): | |
39 | return [sys.executable, '-c', |
|
39 | return [sys.executable, '-c', 'import sys; import time; import shutil; ' + script] | |
40 | 'import sys; import time; import shutil; ' + script] |
|
|||
41 |
|
40 | |||
42 |
|
41 | |||
43 | def test_raise_exception_on_non_zero_return_code(environ): |
|
42 | def test_raise_exception_on_non_zero_return_code(environ): | |
@@ -48,8 +47,11 b' def test_raise_exception_on_non_zero_ret' | |||||
48 |
|
47 | |||
49 | def test_does_not_fail_on_non_zero_return_code(environ): |
|
48 | def test_does_not_fail_on_non_zero_return_code(environ): | |
50 | args = _get_python_args('sys.exit(1)') |
|
49 | args = _get_python_args('sys.exit(1)') | |
51 | output = ''.join(subprocessio.SubprocessIOChunker( |
|
50 | output = ''.join( | |
52 | args, shell=False, fail_on_return_code=False, env=environ)) |
|
51 | subprocessio.SubprocessIOChunker( | |
|
52 | args, shell=False, fail_on_return_code=False, env=environ | |||
|
53 | ) | |||
|
54 | ) | |||
53 |
|
55 | |||
54 | assert output == '' |
|
56 | assert output == '' | |
55 |
|
57 | |||
@@ -64,49 +66,56 b' def test_raise_exception_on_stderr(envir' | |||||
64 |
|
66 | |||
65 | def test_does_not_fail_on_stderr(environ): |
|
67 | def test_does_not_fail_on_stderr(environ): | |
66 | args = _get_python_args('sys.stderr.write("X"); time.sleep(1);') |
|
68 | args = _get_python_args('sys.stderr.write("X"); time.sleep(1);') | |
67 | output = ''.join(subprocessio.SubprocessIOChunker( |
|
69 | output = ''.join( | |
68 | args, shell=False, fail_on_stderr=False, env=environ)) |
|
70 | subprocessio.SubprocessIOChunker( | |
|
71 | args, shell=False, fail_on_stderr=False, env=environ | |||
|
72 | ) | |||
|
73 | ) | |||
69 |
|
74 | |||
70 | assert output == '' |
|
75 | assert output == '' | |
71 |
|
76 | |||
72 |
|
77 | |||
73 | @pytest.mark.parametrize('size', [1, 10**5]) |
|
78 | @pytest.mark.parametrize('size', [1, 10 ** 5]) | |
74 | def test_output_with_no_input(size, environ): |
|
79 | def test_output_with_no_input(size, environ): | |
75 |
print |
|
80 | print(type(environ)) | |
76 | data = 'X' |
|
81 | data = 'X' | |
77 | args = _get_python_args('sys.stdout.write("%s" * %d)' % (data, size)) |
|
82 | args = _get_python_args('sys.stdout.write("%s" * %d)' % (data, size)) | |
78 | output = ''.join(subprocessio.SubprocessIOChunker( |
|
83 | output = ''.join(subprocessio.SubprocessIOChunker(args, shell=False, env=environ)) | |
79 | args, shell=False, env=environ)) |
|
|||
80 |
|
84 | |||
81 | assert output == data * size |
|
85 | assert output == data * size | |
82 |
|
86 | |||
83 |
|
87 | |||
84 | @pytest.mark.parametrize('size', [1, 10**5]) |
|
88 | @pytest.mark.parametrize('size', [1, 10 ** 5]) | |
85 | def test_output_with_no_input_does_not_fail(size, environ): |
|
89 | def test_output_with_no_input_does_not_fail(size, environ): | |
86 | data = 'X' |
|
90 | data = 'X' | |
87 | args = _get_python_args( |
|
91 | args = _get_python_args('sys.stdout.write("%s" * %d); sys.exit(1)' % (data, size)) | |
88 | 'sys.stdout.write("%s" * %d); sys.exit(1)' % (data, size)) |
|
92 | output = ''.join( | |
89 |
|
|
93 | subprocessio.SubprocessIOChunker( | |
90 |
args, shell=False, fail_on_return_code=False, env=environ |
|
94 | args, shell=False, fail_on_return_code=False, env=environ | |
|
95 | ) | |||
|
96 | ) | |||
91 |
|
97 | |||
92 | print len(data * size), len(output) |
|
98 | print("{} {}".format(len(data * size), len(output))) | |
93 | assert output == data * size |
|
99 | assert output == data * size | |
94 |
|
100 | |||
95 |
|
101 | |||
96 | @pytest.mark.parametrize('size', [1, 10**5]) |
|
102 | @pytest.mark.parametrize('size', [1, 10 ** 5]) | |
97 | def test_output_with_input(size, environ): |
|
103 | def test_output_with_input(size, environ): | |
98 | data = 'X' * size |
|
104 | data = 'X' * size | |
99 | inputstream = io.BytesIO(data) |
|
105 | inputstream = io.BytesIO(data) | |
100 | # This acts like the cat command. |
|
106 | # This acts like the cat command. | |
101 | args = _get_python_args('shutil.copyfileobj(sys.stdin, sys.stdout)') |
|
107 | args = _get_python_args('shutil.copyfileobj(sys.stdin, sys.stdout)') | |
102 | output = ''.join(subprocessio.SubprocessIOChunker( |
|
108 | output = ''.join( | |
103 | args, shell=False, inputstream=inputstream, env=environ)) |
|
109 | subprocessio.SubprocessIOChunker( | |
|
110 | args, shell=False, inputstream=inputstream, env=environ | |||
|
111 | ) | |||
|
112 | ) | |||
104 |
|
113 | |||
105 | print len(data), len(output) |
|
114 | print("{} {}".format(len(data * size), len(output))) | |
106 | assert output == data |
|
115 | assert output == data | |
107 |
|
116 | |||
108 |
|
117 | |||
109 | @pytest.mark.parametrize('size', [1, 10**5]) |
|
118 | @pytest.mark.parametrize('size', [1, 10 ** 5]) | |
110 | def test_output_with_input_skipping_iterator(size, environ): |
|
119 | def test_output_with_input_skipping_iterator(size, environ): | |
111 | data = 'X' * size |
|
120 | data = 'X' * size | |
112 | inputstream = io.BytesIO(data) |
|
121 | inputstream = io.BytesIO(data) | |
@@ -115,8 +124,9 b' def test_output_with_input_skipping_iter' | |||||
115 |
|
124 | |||
116 | # Note: assigning the chunker makes sure that it is not deleted too early |
|
125 | # Note: assigning the chunker makes sure that it is not deleted too early | |
117 | chunker = subprocessio.SubprocessIOChunker( |
|
126 | chunker = subprocessio.SubprocessIOChunker( | |
118 |
args, shell=False, inputstream=inputstream, env=environ |
|
127 | args, shell=False, inputstream=inputstream, env=environ | |
|
128 | ) | |||
119 | output = ''.join(chunker.output) |
|
129 | output = ''.join(chunker.output) | |
120 |
|
130 | |||
121 | print len(data), len(output) |
|
131 | print("{} {}".format(len(data * size), len(output))) | |
122 | assert output == data |
|
132 | assert output == data |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now