Show More
The requested changes are too big and content was truncated. Show full diff
@@ -0,0 +1,42 b'' | |||
|
1 | .. _restore-deleted-repositories: | |
|
2 | ||
|
3 | Restoring Deleted Repositories | |
|
4 | ============================== | |
|
5 | ||
|
6 | By default when repository or whole repository group is deleted an archived copy | |
|
7 | of filesystem repositories are kept. You can see them as special entries in the | |
|
8 | repository storage such as:: | |
|
9 | ||
|
10 | drwxrwxr-x 3 rcdev rcdev 4096 Dec 4 2017 rm__20171204_105727_400795__ce-import | |
|
11 | drwxrwxr-x 6 rcdev rcdev 4096 Nov 21 2017 rm__20180221_152430_675047__svn-repo | |
|
12 | drwxr-xr-x 7 rcdev rcdev 4096 Mar 28 2018 rm__20180328_143124_617576__test-git | |
|
13 | drwxr-xr-x 7 rcdev rcdev 4096 Mar 28 2018 rm__20180328_144954_317729__test-git-install-hooks | |
|
14 | ||
|
15 | ||
|
16 | Data from those repositories can be restored by simply removing the | |
|
17 | `rm_YYYYDDMM_HHMMSS_DDDDDD__` prefix and additionally only in case of Mercurial | |
|
18 | repositories remove the `.hg` store prefix.:: | |
|
19 | ||
|
20 | rm__.hg => .hg | |
|
21 | ||
|
22 | ||
|
23 | For Git or SVN repositories this operation is not required. | |
|
24 | ||
|
25 | After removing the prefix repository can be brought by opening | |
|
26 | :menuselection:`Admin --> Settings --> Remap and Rescan` and running `Rescan Filesystem` | |
|
27 | ||
|
28 | This will create a new DB entry restoring the data previously removed. | |
|
29 | To restore OLD database entries this should be done by restoring from a Database backup. | |
|
30 | ||
|
31 | RhodeCode also keeps the repository group structure, this is marked by entries that | |
|
32 | in addition have GROUP in the prefix, eg:: | |
|
33 | ||
|
34 | drwxr-xr-x 2 rcdev rcdev 4096 Jan 18 16:13 rm__20181130_120650_977082_GROUP_Test1 | |
|
35 | drwxr-xr-x 2 rcdev rcdev 4096 Jan 18 16:13 rm__20181130_120659_922952_GROUP_Docs | |
|
36 | ||
|
37 | ||
|
38 | ||
|
39 | .. note:: | |
|
40 | ||
|
41 | RhodeCode Tools have a special cleanup tool for the archived repositories. Please | |
|
42 | see :ref:`clean-up-cmds` |
@@ -0,0 +1,37 b'' | |||
|
1 | .. _store-methods-ref: | |
|
2 | ||
|
3 | store methods | |
|
4 | ============= | |
|
5 | ||
|
6 | file_store_add (EE only) | |
|
7 | ------------------------ | |
|
8 | ||
|
9 | .. py:function:: file_store_add(apiuser, filename, content) | |
|
10 | ||
|
11 | Upload API for the file_store | |
|
12 | ||
|
13 | Example usage from CLI:: | |
|
14 | rhodecode-api --instance-name=enterprise-1 upload_file "{"content": "$(cat image.jpg | base64)", "filename":"image.jpg"}" | |
|
15 | ||
|
16 | This command takes the following options: | |
|
17 | ||
|
18 | :param apiuser: This is filled automatically from the |authtoken|. | |
|
19 | :type apiuser: AuthUser | |
|
20 | :param filename: name of the file uploaded | |
|
21 | :type filename: str | |
|
22 | :param content: base64 encoded content of the uploaded file | |
|
23 | :type content: str | |
|
24 | ||
|
25 | Example output: | |
|
26 | ||
|
27 | .. code-block:: bash | |
|
28 | ||
|
29 | id : <id_given_in_input> | |
|
30 | result: { | |
|
31 | "access_path": "/_file_store/download/84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg", | |
|
32 | "access_path_fqn": "http://server.domain.com/_file_store/download/84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg", | |
|
33 | "store_fid": "84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg" | |
|
34 | } | |
|
35 | error : null | |
|
36 | ||
|
37 |
@@ -0,0 +1,88 b'' | |||
|
1 | .. _auth-saml-bulk-enroll-users-ref: | |
|
2 | ||
|
3 | ||
|
4 | Bulk enroll multiple existing users | |
|
5 | ----------------------------------- | |
|
6 | ||
|
7 | ||
|
8 | RhodeCode Supports standard SAML 2.0 SSO for the web-application part. | |
|
9 | Below is an example how to enroll list of all or some users to use SAML authentication. | |
|
10 | This method simply enables SAML authentication for many users at once. | |
|
11 | ||
|
12 | ||
|
13 | From the server RhodeCode Enterprise is running run ishell on the instance which we | |
|
14 | want to apply the SAML migration:: | |
|
15 | ||
|
16 | rccontrol ishell enterprise-1 | |
|
17 | ||
|
18 | Follow these steps to enable SAML authentication for multiple users. | |
|
19 | ||
|
20 | ||
|
21 | 1) Create a user_id => attribute mapping | |
|
22 | ||
|
23 | ||
|
24 | `saml2user` is a mapping of external ID from SAML provider such as OneLogin, DuoSecurity, Google. | |
|
25 | This mapping consists of local rhodecode user_id mapped to set of required attributes needed to bind SAML | |
|
26 | account to internal rhodecode user. | |
|
27 | For example, 123 is local rhodecode user_id, and '48253211' is OneLogin ID. | |
|
28 | For other providers you'd have to figure out what would be the user-id, sometimes it's the email, i.e for Google | |
|
29 | The most important this id needs to be unique for each user. | |
|
30 | ||
|
31 | .. code-block:: python | |
|
32 | ||
|
33 | In [1]: saml2user = { | |
|
34 | ...: # OneLogin, uses externalID available to read from in the UI | |
|
35 | ...: 123: {'id: '48253211'}, | |
|
36 | ...: # for Google/DuoSecurity email is also an option for unique ID | |
|
37 | ...: 124: {'id: 'email@domain.com'}, | |
|
38 | ...: } | |
|
39 | ||
|
40 | ||
|
41 | 2) Import the plugin you want to run migration for. | |
|
42 | ||
|
43 | From available options pick only one and run the `import` statement | |
|
44 | ||
|
45 | .. code-block:: python | |
|
46 | ||
|
47 | # for Duo Security | |
|
48 | In [2]: from rc_auth_plugins.auth_duo_security import RhodeCodeAuthPlugin | |
|
49 | # for OneLogin | |
|
50 | In [2]: from rc_auth_plugins.auth_onelogin import RhodeCodeAuthPlugin | |
|
51 | # generic SAML plugin | |
|
52 | In [2]: from rc_auth_plugins.auth_saml import RhodeCodeAuthPlugin | |
|
53 | ||
|
54 | 3) Run the migration based on saml2user mapping. | |
|
55 | ||
|
56 | Enter in the ishell prompt | |
|
57 | ||
|
58 | .. code-block:: python | |
|
59 | ||
|
60 | In [3]: for user in User.get_all(): | |
|
61 | ...: existing_identity = ExternalIdentity().query().filter(ExternalIdentity.local_user_id == user.user_id).scalar() | |
|
62 | ...: attrs = saml2user.get(user.user_id) | |
|
63 | ...: provider = RhodeCodeAuthPlugin.uid | |
|
64 | ...: if existing_identity: | |
|
65 | ...: print('Identity for user `{}` already exists, skipping'.format(user.username)) | |
|
66 | ...: continue | |
|
67 | ...: if attrs: | |
|
68 | ...: external_id = attrs['id'] | |
|
69 | ...: new_external_identity = ExternalIdentity() | |
|
70 | ...: new_external_identity.external_id = external_id | |
|
71 | ...: new_external_identity.external_username = '{}-saml-{}'.format(user.username, user.user_id) | |
|
72 | ...: new_external_identity.provider_name = provider | |
|
73 | ...: new_external_identity.local_user_id = user_id | |
|
74 | ...: new_external_identity.access_token = '' | |
|
75 | ...: new_external_identity.token_secret = '' | |
|
76 | ...: new_external_identity.alt_token = '' | |
|
77 | ...: Session().add(ex_identity) | |
|
78 | ...: Session().commit() | |
|
79 | ...: print('Set user `{}` external identity bound to ExternalID:{}'.format(user.username, external_id)) | |
|
80 | ||
|
81 | .. note:: | |
|
82 | ||
|
83 | saml2user can be really big and hard to maintain in ishell. It's also possible | |
|
84 | to load it as a JSON file prepared before and stored on disk. To do so run:: | |
|
85 | ||
|
86 | import json | |
|
87 | saml2user = json.loads(open('/path/to/saml2user.json','rb').read()) | |
|
88 |
@@ -0,0 +1,148 b'' | |||
|
1 | |RCE| 4.16.0 |RNS| | |
|
2 | ------------------ | |
|
3 | ||
|
4 | Release Date | |
|
5 | ^^^^^^^^^^^^ | |
|
6 | ||
|
7 | - 2019-02-15 | |
|
8 | ||
|
9 | ||
|
10 | New Features | |
|
11 | ^^^^^^^^^^^^ | |
|
12 | ||
|
13 | ||
|
14 | - Full-text search: added support for ElasticSearch 6.X (ES6) | |
|
15 | - Full-text search: Expose a quick way to search within repository groups using ES6. | |
|
16 | - Full-text search: Add quick links to broaden/narrow search scope to repositories or | |
|
17 | repository groups from global search. | |
|
18 | - Full-text search: ES6 backend adds new highlighter, and search markers for better UX when searching. | |
|
19 | - Full-text search: ES6 backend has enabled advanced `query string syntax` | |
|
20 | adding more search and filtering capabilities. | |
|
21 | - Full-text search: ES6 engine will now show added information where available such as line numbers file size. | |
|
22 | - Files: added option to use highlight marker to show keywords inside file source. This | |
|
23 | is used now for ES6 backend extended highlighting capabilities | |
|
24 | - Artifacts (beta): EE edition exposes new feature called storage_api this allows storing | |
|
25 | binary files outside of Version Control System, but in the scope of a repository or group. | |
|
26 | This will soon become an Artifacts functionality available in EE edition. | |
|
27 | - Authentication: introduced `User restriction` and `Scope restriction` for RhodeCode authentication plugins. | |
|
28 | Admins can limit usage of RhodeCode plugins to super-admins user types, and usage in Web, or VCS protocol only. | |
|
29 | This is mostly to help to migrate users to SAML, keeping the super-admins to manage instances via local-logins, | |
|
30 | and secondly to force usage of AuthenticationTokens instead of re-using same credentials for | |
|
31 | WEB and VCS authentication. | |
|
32 | - API: added basic upload API for the storage_api. It's possible to store files using internal | |
|
33 | API. This is a start for attachments upload in RhodeCode. | |
|
34 | - API: added store_exception_api for remote exception storage. This is used by a new | |
|
35 | indexer that will report any problems back into the RhodeCode instance in case of indexing problems. | |
|
36 | - API: added function to fetch comments for a repository. | |
|
37 | - Quick search: improve the styling of search input and results. | |
|
38 | - Pull requests: allowed to select all forks and parent forks of target repository in creation UI. | |
|
39 | This is a common workflow supported by GitHub etc. | |
|
40 | ||
|
41 | ||
|
42 | General | |
|
43 | ^^^^^^^ | |
|
44 | ||
|
45 | - Users/Repositories/Repository groups: expose IDs of those objects in advanced views. | |
|
46 | Useful for API calls or usage in ishell. | |
|
47 | - UI: moved repo group select next to the name as it's very relevant to each other. | |
|
48 | - Pull requests: increase the stability of concurrent pull requests created. | |
|
49 | - Pull requests: introduced operation state for pull requests to prevent from | |
|
50 | locks during merge/update operations in concurrent busy environments. | |
|
51 | - Pull requests: ensure that merge response provide more details about failed operations. | |
|
52 | - UI / Files: expose downloads options onto files view similar as in summary page. | |
|
53 | - Repositories: show hooks version and update link in the advanced section of repository page. | |
|
54 | - Events: trigger 'review_status_change' in all cases when reviewers are changed | |
|
55 | influencing review status. | |
|
56 | - Files: display submodules in a sorted way, equal to how Directories are sorted. | |
|
57 | - API: fetching all pull-requests now sorts the results and exposed a flag to show/hide | |
|
58 | the merge result state for faster result fetching. | |
|
59 | - API: merge_pull_request expose detailed merge message in the merge operation | |
|
60 | next to numeric merge response code. | |
|
61 | - API: added possibility to specify owner to create_pull_request API. | |
|
62 | - SSH: Added ability to disable server-side SSH key generation to enforce users | |
|
63 | generated SSH keys only outside of the server. | |
|
64 | - Integrations: allow PUT method for WebHook integration. | |
|
65 | - Dependencies: bumped git to 2.19.2 release. | |
|
66 | - Dependencies: dropped pygments-markdown-lexer as it's natively supported by pygments now. | |
|
67 | - Dependencies: bumped pyramid to 1.10.1 | |
|
68 | - Dependencies: bumped pastedeploy to 2.0.1 | |
|
69 | - Dependencies: bumped pastescript to 3.0.0 | |
|
70 | - Dependencies: bumped pathlib2 to 2.3.3 | |
|
71 | - Dependencies: bumped webob to 1.8.4 | |
|
72 | - Dependencies: bumped iso8601 to 0.1.12 | |
|
73 | - Dependencies: bumped more-itertools to 5.0.0 | |
|
74 | - Dependencies: bumped psutil to 5.4.8 | |
|
75 | - Dependencies: bumped pyasn1 to 0.4.5 | |
|
76 | - Dependencies: bumped pygments to 2.3.1 | |
|
77 | - Dependencies: bumped pyramid-debugtoolbar to 4.5.0 | |
|
78 | - Dependencies: bumped subprocess32 to 3.5.3 | |
|
79 | - Dependencies: bumped supervisor to 3.3.5 | |
|
80 | - Dependencies: bumped dogpile.cache to 0.7.1 | |
|
81 | - Dependencies: bumped simplejson to 3.16.0 | |
|
82 | - Dependencies: bumped gevent to 1.4.0 | |
|
83 | - Dependencies: bumped configparser to 3.5.1 | |
|
84 | ||
|
85 | ||
|
86 | Security | |
|
87 | ^^^^^^^^ | |
|
88 | ||
|
89 | - Fork page: don't expose fork origin link if we don't have permission to access this repository. | |
|
90 | Additionally don't pre-select such repository in pull request ref selector. | |
|
91 | - Security: fix possible XSS in the issue tracker URL. | |
|
92 | - Security: sanitize plaintext renderer with bleach, preventing XSS in rendered html. | |
|
93 | - Audit logs: added audit logs for API permission calls. | |
|
94 | ||
|
95 | ||
|
96 | Performance | |
|
97 | ^^^^^^^^^^^ | |
|
98 | ||
|
99 | - Summary page: don't load repo size when showing expanded information about repository. | |
|
100 | Size calculation needs to be triggered manually. | |
|
101 | - Git: use rev-list for fetching last commit data in case of single commit history. | |
|
102 | In some cases, it is much faster than previously used git log command. | |
|
103 | ||
|
104 | ||
|
105 | Fixes | |
|
106 | ^^^^^ | |
|
107 | ||
|
108 | - Installer: fixed 32bit package builds broken in previous releases. | |
|
109 | - Git: use iterative fetch to prevent errors about too many arguments on | |
|
110 | synchronizing very large repositories. | |
|
111 | - Git: pass in the SSL dir that is exposed from wire for remote GIT commands. | |
|
112 | - LDAP+Groups: improve logging, and fix the case when extracting group name from LDAP | |
|
113 | returned nothing. We should warn about that, but not FAIL on login. | |
|
114 | - Default reviewers: fixed submodule support in picking reviewers from annotation for files. | |
|
115 | - Hooks: handle non-ascii characters in hooks new pull-requests open template. | |
|
116 | - Diffs: fixed missing limited diff container display on over-size limit diffs. | |
|
117 | - Diffs: fixed 500 error in case of some very uncommon diffs containing only Unicode characters. | |
|
118 | - Repositories: handle VCS backend unavailable correctly in advanced settings for the repository. | |
|
119 | - Remap & rescan: prevent empty/damaged repositories to break the remap operation. | |
|
120 | - Visual: fixed show revision/commit length settings. | |
|
121 | - Mercurial submodules: only show submodule in the path that it belongs too. | |
|
122 | Before even submodules from root node were shown in subdirectories. | |
|
123 | - UI/Files: fixed icons in file tree search. | |
|
124 | - WebHook integration: quote URL variables to prevent URL errors with special chars | |
|
125 | like # in the title. | |
|
126 | - API: pull-requests, fixed invocation of merge as another user. | |
|
127 | - VCS: limit fd leaks on subprocessio calls. | |
|
128 | - VCS: expose SSL certificate path over the wire to the vcsserver, this solves some | |
|
129 | remote SSL import problems reported. | |
|
130 | ||
|
131 | ||
|
132 | Upgrade notes | |
|
133 | ^^^^^^^^^^^^^ | |
|
134 | ||
|
135 | This release brings the new Full-text search capabilities using ElasticSearch 6. | |
|
136 | If you use Elastic Search backend a backward compatibility mode is enabled and | |
|
137 | ElasticSearch backend defaults to previously used ElasticSearch 2. | |
|
138 | ||
|
139 | To use new features a full index rebuild is required, in addition ```--es-version=6``` flag | |
|
140 | needs to be used with indexer and ```search.es_version = 6``` should be set in rhodecode.ini | |
|
141 | ||
|
142 | Additionally new mapping format is available for the indexer that has additional capabilities | |
|
143 | for include/exclude rules. Old format should work as well, but we encourage to | |
|
144 | generate a new mapping.ini file using rhodecode-index command, and migrate your repositories | |
|
145 | to the new format. | |
|
146 | ||
|
147 | Please refer to the :ref:`indexing-ref` documentation for more details. | |
|
148 |
@@ -0,0 +1,107 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | ||
|
21 | ||
|
22 | import pytest | |
|
23 | ||
|
24 | from rhodecode.model.db import User, ChangesetComment | |
|
25 | from rhodecode.model.meta import Session | |
|
26 | from rhodecode.model.comment import CommentsModel | |
|
27 | from rhodecode.api.tests.utils import ( | |
|
28 | build_data, api_call, assert_error, assert_call_ok) | |
|
29 | ||
|
30 | ||
|
31 | @pytest.fixture() | |
|
32 | def make_repo_comments_factory(request): | |
|
33 | ||
|
34 | def maker(repo): | |
|
35 | user = User.get_first_super_admin() | |
|
36 | commit = repo.scm_instance()[0] | |
|
37 | ||
|
38 | commit_id = commit.raw_id | |
|
39 | file_0 = commit.affected_files[0] | |
|
40 | comments = [] | |
|
41 | ||
|
42 | # general | |
|
43 | CommentsModel().create( | |
|
44 | text='General Comment', repo=repo, user=user, commit_id=commit_id, | |
|
45 | comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False) | |
|
46 | ||
|
47 | # inline | |
|
48 | CommentsModel().create( | |
|
49 | text='Inline Comment', repo=repo, user=user, commit_id=commit_id, | |
|
50 | f_path=file_0, line_no='n1', | |
|
51 | comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False) | |
|
52 | ||
|
53 | # todo | |
|
54 | CommentsModel().create( | |
|
55 | text='INLINE TODO Comment', repo=repo, user=user, commit_id=commit_id, | |
|
56 | f_path=file_0, line_no='n1', | |
|
57 | comment_type=ChangesetComment.COMMENT_TYPE_TODO, send_email=False) | |
|
58 | ||
|
59 | @request.addfinalizer | |
|
60 | def cleanup(): | |
|
61 | for comment in comments: | |
|
62 | Session().delete(comment) | |
|
63 | return maker | |
|
64 | ||
|
65 | ||
|
66 | @pytest.mark.usefixtures("testuser_api", "app") | |
|
67 | class TestGetRepo(object): | |
|
68 | ||
|
69 | @pytest.mark.parametrize('filters, expected_count', [ | |
|
70 | ({}, 3), | |
|
71 | ({'comment_type': ChangesetComment.COMMENT_TYPE_NOTE}, 2), | |
|
72 | ({'comment_type': ChangesetComment.COMMENT_TYPE_TODO}, 1), | |
|
73 | ({'commit_id': 'FILLED DYNAMIC'}, 3), | |
|
74 | ]) | |
|
75 | def test_api_get_repo_comments(self, backend, user_util, | |
|
76 | make_repo_comments_factory, filters, expected_count): | |
|
77 | commits = [{'message': 'A'}, {'message': 'B'}] | |
|
78 | repo = backend.create_repo(commits=commits) | |
|
79 | make_repo_comments_factory(repo) | |
|
80 | ||
|
81 | api_call_params = {'repoid': repo.repo_name,} | |
|
82 | api_call_params.update(filters) | |
|
83 | ||
|
84 | if 'commit_id' in api_call_params: | |
|
85 | commit = repo.scm_instance()[0] | |
|
86 | commit_id = commit.raw_id | |
|
87 | api_call_params['commit_id'] = commit_id | |
|
88 | ||
|
89 | id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params) | |
|
90 | response = api_call(self.app, params) | |
|
91 | result = assert_call_ok(id_, given=response.body) | |
|
92 | ||
|
93 | assert len(result) == expected_count | |
|
94 | ||
|
95 | def test_api_get_repo_comments_wrong_comment_typ(self, backend_hg): | |
|
96 | ||
|
97 | repo = backend_hg.create_repo() | |
|
98 | make_repo_comments_factory(repo) | |
|
99 | ||
|
100 | api_call_params = {'repoid': repo.repo_name,} | |
|
101 | api_call_params.update({'comment_type': 'bogus'}) | |
|
102 | ||
|
103 | expected = 'comment_type must be one of `{}` got {}'.format( | |
|
104 | ChangesetComment.COMMENT_TYPES, 'bogus') | |
|
105 | id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params) | |
|
106 | response = api_call(self.app, params) | |
|
107 | assert_error(id_, expected, given=response.body) |
@@ -0,0 +1,59 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | ||
|
21 | ||
|
22 | import pytest | |
|
23 | ||
|
24 | from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error | |
|
25 | ||
|
26 | ||
|
27 | @pytest.mark.usefixtures("testuser_api", "app") | |
|
28 | class TestStoreException(object): | |
|
29 | ||
|
30 | def test_store_exception_invalid_json(self): | |
|
31 | id_, params = build_data(self.apikey, 'store_exception', | |
|
32 | exc_data_json='XXX,{') | |
|
33 | response = api_call(self.app, params) | |
|
34 | ||
|
35 | expected = 'Failed to parse JSON data from exc_data_json field. ' \ | |
|
36 | 'Please make sure it contains a valid JSON.' | |
|
37 | assert_error(id_, expected, given=response.body) | |
|
38 | ||
|
39 | def test_store_exception_missing_json_params_json(self): | |
|
40 | id_, params = build_data(self.apikey, 'store_exception', | |
|
41 | exc_data_json='{"foo":"bar"}') | |
|
42 | response = api_call(self.app, params) | |
|
43 | ||
|
44 | expected = "Missing exc_traceback, or exc_type_name in " \ | |
|
45 | "exc_data_json field. Missing: 'exc_traceback'" | |
|
46 | assert_error(id_, expected, given=response.body) | |
|
47 | ||
|
48 | def test_store_exception(self): | |
|
49 | id_, params = build_data( | |
|
50 | self.apikey, 'store_exception', | |
|
51 | exc_data_json='{"exc_traceback": "invalid", "exc_type_name":"ValueError"}') | |
|
52 | response = api_call(self.app, params) | |
|
53 | exc_id = response.json['result']['exc_id'] | |
|
54 | ||
|
55 | expected = { | |
|
56 | 'exc_id': exc_id, | |
|
57 | 'exc_url': 'http://example.com/_admin/settings/exceptions/{}'.format(exc_id) | |
|
58 | } | |
|
59 | assert_ok(id_, expected, given=response.body) |
@@ -0,0 +1,49 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | import os | |
|
21 | from rhodecode.apps.file_store import config_keys | |
|
22 | from rhodecode.config.middleware import _bool_setting, _string_setting | |
|
23 | ||
|
24 | ||
|
25 | def _sanitize_settings_and_apply_defaults(settings): | |
|
26 | """ | |
|
27 | Set defaults, convert to python types and validate settings. | |
|
28 | """ | |
|
29 | _bool_setting(settings, config_keys.enabled, 'true') | |
|
30 | ||
|
31 | _string_setting(settings, config_keys.backend, 'local') | |
|
32 | ||
|
33 | default_store = os.path.join(os.path.dirname(settings['__file__']), 'upload_store') | |
|
34 | _string_setting(settings, config_keys.store_path, default_store) | |
|
35 | ||
|
36 | ||
|
37 | def includeme(config): | |
|
38 | settings = config.registry.settings | |
|
39 | _sanitize_settings_and_apply_defaults(settings) | |
|
40 | ||
|
41 | config.add_route( | |
|
42 | name='upload_file', | |
|
43 | pattern='/_file_store/upload') | |
|
44 | config.add_route( | |
|
45 | name='download_file', | |
|
46 | pattern='/_file_store/download/{fid}') | |
|
47 | ||
|
48 | # Scan module for configuration decorators. | |
|
49 | config.scan('.views', ignore='.tests') |
@@ -0,0 +1,27 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | ||
|
21 | ||
|
22 | # Definition of setting keys used to configure this module. Defined here to | |
|
23 | # avoid repetition of keys throughout the module. | |
|
24 | ||
|
25 | enabled = 'file_store.enabled' | |
|
26 | backend = 'file_store.backend' | |
|
27 | store_path = 'file_store.storage_path' |
@@ -0,0 +1,31 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | ||
|
21 | ||
|
22 | class FileNotAllowedException(Exception): | |
|
23 | """ | |
|
24 | Thrown if file does not have an allowed extension. | |
|
25 | """ | |
|
26 | ||
|
27 | ||
|
28 | class FileOverSizeException(Exception): | |
|
29 | """ | |
|
30 | Thrown if file is over the set limit. | |
|
31 | """ |
@@ -0,0 +1,66 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | ||
|
21 | ||
|
22 | ANY = [] | |
|
23 | TEXT_EXT = ['txt', 'md', 'rst', 'log'] | |
|
24 | DOCUMENTS_EXT = ['pdf', 'rtf', 'odf', 'ods', 'gnumeric', 'abw', 'doc', 'docx', 'xls', 'xlsx'] | |
|
25 | IMAGES_EXT = ['jpg', 'jpe', 'jpeg', 'png', 'gif', 'svg', 'bmp', 'tiff'] | |
|
26 | AUDIO_EXT = ['wav', 'mp3', 'aac', 'ogg', 'oga', 'flac'] | |
|
27 | VIDEO_EXT = ['mpeg', '3gp', 'avi', 'divx', 'dvr', 'flv', 'mp4', 'wmv'] | |
|
28 | DATA_EXT = ['csv', 'ini', 'json', 'plist', 'xml', 'yaml', 'yml'] | |
|
29 | SCRIPTS_EXT = ['js', 'php', 'pl', 'py', 'rb', 'sh', 'go', 'c', 'h'] | |
|
30 | ARCHIVES_EXT = ['gz', 'bz2', 'zip', 'tar', 'tgz', 'txz', '7z'] | |
|
31 | EXECUTABLES_EXT = ['so', 'exe', 'dll'] | |
|
32 | ||
|
33 | ||
|
34 | DEFAULT = DOCUMENTS_EXT + TEXT_EXT + IMAGES_EXT + DATA_EXT | |
|
35 | ||
|
36 | GROUPS = dict(( | |
|
37 | ('any', ANY), | |
|
38 | ('text', TEXT_EXT), | |
|
39 | ('documents', DOCUMENTS_EXT), | |
|
40 | ('images', IMAGES_EXT), | |
|
41 | ('audio', AUDIO_EXT), | |
|
42 | ('video', VIDEO_EXT), | |
|
43 | ('data', DATA_EXT), | |
|
44 | ('scripts', SCRIPTS_EXT), | |
|
45 | ('archives', ARCHIVES_EXT), | |
|
46 | ('executables', EXECUTABLES_EXT), | |
|
47 | ('default', DEFAULT), | |
|
48 | )) | |
|
49 | ||
|
50 | ||
|
51 | def resolve_extensions(extensions, groups=None): | |
|
52 | """ | |
|
53 | Calculate allowed extensions based on a list of extensions provided, and optional | |
|
54 | groups of extensions from the available lists. | |
|
55 | ||
|
56 | :param extensions: a list of extensions e.g ['py', 'txt'] | |
|
57 | :param groups: additionally groups to extend the extensions. | |
|
58 | """ | |
|
59 | groups = groups or [] | |
|
60 | valid_exts = set([x.lower() for x in extensions]) | |
|
61 | ||
|
62 | for group in groups: | |
|
63 | if group in GROUPS: | |
|
64 | valid_exts.update(GROUPS[group]) | |
|
65 | ||
|
66 | return valid_exts |
@@ -0,0 +1,211 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | ||
|
21 | import os | |
|
22 | import time | |
|
23 | import shutil | |
|
24 | import hashlib | |
|
25 | ||
|
26 | from rhodecode.lib.ext_json import json | |
|
27 | from rhodecode.apps.file_store import utils | |
|
28 | from rhodecode.apps.file_store.extensions import resolve_extensions | |
|
29 | from rhodecode.apps.file_store.exceptions import FileNotAllowedException | |
|
30 | ||
|
31 | METADATA_VER = 'v1' | |
|
32 | ||
|
33 | ||
|
34 | class LocalFileStorage(object): | |
|
35 | ||
|
36 | @classmethod | |
|
37 | def resolve_name(cls, name, directory): | |
|
38 | """ | |
|
39 | Resolves a unique name and the correct path. If a filename | |
|
40 | for that path already exists then a numeric prefix with values > 0 will be | |
|
41 | added, for example test.jpg -> test-1.jpg etc. initially file would have 0 prefix. | |
|
42 | ||
|
43 | :param name: base name of file | |
|
44 | :param directory: absolute directory path | |
|
45 | """ | |
|
46 | ||
|
47 | basename, ext = os.path.splitext(name) | |
|
48 | counter = 0 | |
|
49 | while True: | |
|
50 | name = '%s-%d%s' % (basename, counter, ext) | |
|
51 | ||
|
52 | # sub_store prefix to optimize disk usage, e.g some_path/ab/final_file | |
|
53 | sub_store = cls._sub_store_from_filename(basename) | |
|
54 | sub_store_path = os.path.join(directory, sub_store) | |
|
55 | if not os.path.exists(sub_store_path): | |
|
56 | os.makedirs(sub_store_path) | |
|
57 | ||
|
58 | path = os.path.join(sub_store_path, name) | |
|
59 | if not os.path.exists(path): | |
|
60 | return name, path | |
|
61 | counter += 1 | |
|
62 | ||
|
63 | @classmethod | |
|
64 | def _sub_store_from_filename(cls, filename): | |
|
65 | return filename[:2] | |
|
66 | ||
|
67 | @classmethod | |
|
68 | def calculate_path_hash(cls, file_path): | |
|
69 | """ | |
|
70 | Efficient calculation of file_path sha256 sum | |
|
71 | ||
|
72 | :param file_path: | |
|
73 | :return: sha256sum | |
|
74 | """ | |
|
75 | digest = hashlib.sha256() | |
|
76 | with open(file_path, 'rb') as f: | |
|
77 | for chunk in iter(lambda: f.read(1024 * 100), b""): | |
|
78 | digest.update(chunk) | |
|
79 | ||
|
80 | return digest.hexdigest() | |
|
81 | ||
|
82 | def __init__(self, base_path, extension_groups=None): | |
|
83 | ||
|
84 | """ | |
|
85 | Local file storage | |
|
86 | ||
|
87 | :param base_path: the absolute base path where uploads are stored | |
|
88 | :param extension_groups: extensions string | |
|
89 | """ | |
|
90 | ||
|
91 | extension_groups = extension_groups or ['any'] | |
|
92 | self.base_path = base_path | |
|
93 | self.extensions = resolve_extensions([], groups=extension_groups) | |
|
94 | ||
|
95 | def store_path(self, filename): | |
|
96 | """ | |
|
97 | Returns absolute file path of the filename, joined to the | |
|
98 | base_path. | |
|
99 | ||
|
100 | :param filename: base name of file | |
|
101 | """ | |
|
102 | sub_store = self._sub_store_from_filename(filename) | |
|
103 | return os.path.join(self.base_path, sub_store, filename) | |
|
104 | ||
|
105 | def delete(self, filename): | |
|
106 | """ | |
|
107 | Deletes the filename. Filename is resolved with the | |
|
108 | absolute path based on base_path. If file does not exist, | |
|
109 | returns **False**, otherwise **True** | |
|
110 | ||
|
111 | :param filename: base name of file | |
|
112 | """ | |
|
113 | if self.exists(filename): | |
|
114 | os.remove(self.store_path(filename)) | |
|
115 | return True | |
|
116 | return False | |
|
117 | ||
|
118 | def exists(self, filename): | |
|
119 | """ | |
|
120 | Checks if file exists. Resolves filename's absolute | |
|
121 | path based on base_path. | |
|
122 | ||
|
123 | :param filename: base name of file | |
|
124 | """ | |
|
125 | return os.path.exists(self.store_path(filename)) | |
|
126 | ||
|
127 | def filename_allowed(self, filename, extensions=None): | |
|
128 | """Checks if a filename has an allowed extension | |
|
129 | ||
|
130 | :param filename: base name of file | |
|
131 | :param extensions: iterable of extensions (or self.extensions) | |
|
132 | """ | |
|
133 | _, ext = os.path.splitext(filename) | |
|
134 | return self.extension_allowed(ext, extensions) | |
|
135 | ||
|
136 | def extension_allowed(self, ext, extensions=None): | |
|
137 | """ | |
|
138 | Checks if an extension is permitted. Both e.g. ".jpg" and | |
|
139 | "jpg" can be passed in. Extension lookup is case-insensitive. | |
|
140 | ||
|
141 | :param ext: extension to check | |
|
142 | :param extensions: iterable of extensions to validate against (or self.extensions) | |
|
143 | """ | |
|
144 | ||
|
145 | extensions = extensions or self.extensions | |
|
146 | if not extensions: | |
|
147 | return True | |
|
148 | if ext.startswith('.'): | |
|
149 | ext = ext[1:] | |
|
150 | return ext.lower() in extensions | |
|
151 | ||
|
152 | def save_file(self, file_obj, filename, directory=None, extensions=None, | |
|
153 | extra_metadata=None, **kwargs): | |
|
154 | """ | |
|
155 | Saves a file object to the uploads location. | |
|
156 | Returns the resolved filename, i.e. the directory + | |
|
157 | the (randomized/incremented) base name. | |
|
158 | ||
|
159 | :param file_obj: **cgi.FieldStorage** object (or similar) | |
|
160 | :param filename: original filename | |
|
161 | :param directory: relative path of sub-directory | |
|
162 | :param extensions: iterable of allowed extensions, if not default | |
|
163 | :param extra_metadata: extra JSON metadata to store next to the file with .meta suffix | |
|
164 | """ | |
|
165 | ||
|
166 | extensions = extensions or self.extensions | |
|
167 | ||
|
168 | if not self.filename_allowed(filename, extensions): | |
|
169 | raise FileNotAllowedException() | |
|
170 | ||
|
171 | if directory: | |
|
172 | dest_directory = os.path.join(self.base_path, directory) | |
|
173 | else: | |
|
174 | dest_directory = self.base_path | |
|
175 | ||
|
176 | if not os.path.exists(dest_directory): | |
|
177 | os.makedirs(dest_directory) | |
|
178 | ||
|
179 | filename = utils.uid_filename(filename) | |
|
180 | ||
|
181 | # resolve also produces special sub-dir for file optimized store | |
|
182 | filename, path = self.resolve_name(filename, dest_directory) | |
|
183 | stored_file_dir = os.path.dirname(path) | |
|
184 | ||
|
185 | file_obj.seek(0) | |
|
186 | ||
|
187 | with open(path, "wb") as dest: | |
|
188 | shutil.copyfileobj(file_obj, dest) | |
|
189 | ||
|
190 | metadata = {} | |
|
191 | if extra_metadata: | |
|
192 | metadata = extra_metadata | |
|
193 | ||
|
194 | size = os.stat(path).st_size | |
|
195 | file_hash = self.calculate_path_hash(path) | |
|
196 | ||
|
197 | metadata.update( | |
|
198 | {"filename": filename, | |
|
199 | "size": size, | |
|
200 | "time": time.time(), | |
|
201 | "sha256": file_hash, | |
|
202 | "meta_ver": METADATA_VER}) | |
|
203 | ||
|
204 | filename_meta = filename + '.meta' | |
|
205 | with open(os.path.join(stored_file_dir, filename_meta), "wb") as dest_meta: | |
|
206 | dest_meta.write(json.dumps(metadata)) | |
|
207 | ||
|
208 | if directory: | |
|
209 | filename = os.path.join(directory, filename) | |
|
210 | ||
|
211 | return filename, metadata |
@@ -0,0 +1,20 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 |
@@ -0,0 +1,111 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | import os | |
|
21 | import pytest | |
|
22 | ||
|
23 | from rhodecode.lib.ext_json import json | |
|
24 | from rhodecode.tests import TestController | |
|
25 | from rhodecode.apps.file_store import utils, config_keys | |
|
26 | ||
|
27 | ||
|
28 | def route_path(name, params=None, **kwargs): | |
|
29 | import urllib | |
|
30 | ||
|
31 | base_url = { | |
|
32 | 'upload_file': '/_file_store/upload', | |
|
33 | 'download_file': '/_file_store/download/{fid}', | |
|
34 | ||
|
35 | }[name].format(**kwargs) | |
|
36 | ||
|
37 | if params: | |
|
38 | base_url = '{}?{}'.format(base_url, urllib.urlencode(params)) | |
|
39 | return base_url | |
|
40 | ||
|
41 | ||
|
42 | class TestFileStoreViews(TestController): | |
|
43 | ||
|
44 | @pytest.mark.parametrize("fid, content, exists", [ | |
|
45 | ('abcde-0.jpg', "xxxxx", True), | |
|
46 | ('abcde-0.exe', "1234567", True), | |
|
47 | ('abcde-0.jpg', "xxxxx", False), | |
|
48 | ]) | |
|
49 | def test_get_files_from_store(self, fid, content, exists, tmpdir): | |
|
50 | self.log_user() | |
|
51 | store_path = self.app._pyramid_settings[config_keys.store_path] | |
|
52 | ||
|
53 | if exists: | |
|
54 | status = 200 | |
|
55 | store = utils.get_file_storage({config_keys.store_path: store_path}) | |
|
56 | filesystem_file = os.path.join(str(tmpdir), fid) | |
|
57 | with open(filesystem_file, 'wb') as f: | |
|
58 | f.write(content) | |
|
59 | ||
|
60 | with open(filesystem_file, 'rb') as f: | |
|
61 | fid, metadata = store.save_file(f, fid, extra_metadata={'filename': fid}) | |
|
62 | ||
|
63 | else: | |
|
64 | status = 404 | |
|
65 | ||
|
66 | response = self.app.get(route_path('download_file', fid=fid), status=status) | |
|
67 | ||
|
68 | if exists: | |
|
69 | assert response.text == content | |
|
70 | file_store_path = os.path.dirname(store.resolve_name(fid, store_path)[1]) | |
|
71 | metadata_file = os.path.join(file_store_path, fid + '.meta') | |
|
72 | assert os.path.exists(metadata_file) | |
|
73 | with open(metadata_file, 'rb') as f: | |
|
74 | json_data = json.loads(f.read()) | |
|
75 | ||
|
76 | assert json_data | |
|
77 | assert 'size' in json_data | |
|
78 | ||
|
79 | def test_upload_files_without_content_to_store(self): | |
|
80 | self.log_user() | |
|
81 | response = self.app.post( | |
|
82 | route_path('upload_file'), | |
|
83 | params={'csrf_token': self.csrf_token}, | |
|
84 | status=200) | |
|
85 | ||
|
86 | assert response.json == { | |
|
87 | u'error': u'store_file data field is missing', | |
|
88 | u'access_path': None, | |
|
89 | u'store_fid': None} | |
|
90 | ||
|
91 | def test_upload_files_bogus_content_to_store(self): | |
|
92 | self.log_user() | |
|
93 | response = self.app.post( | |
|
94 | route_path('upload_file'), | |
|
95 | params={'csrf_token': self.csrf_token, 'store_file': 'bogus'}, | |
|
96 | status=200) | |
|
97 | ||
|
98 | assert response.json == { | |
|
99 | u'error': u'filename cannot be read from the data field', | |
|
100 | u'access_path': None, | |
|
101 | u'store_fid': None} | |
|
102 | ||
|
103 | def test_upload_content_to_store(self): | |
|
104 | self.log_user() | |
|
105 | response = self.app.post( | |
|
106 | route_path('upload_file'), | |
|
107 | upload_files=[('store_file', 'myfile.txt', 'SOME CONTENT')], | |
|
108 | params={'csrf_token': self.csrf_token}, | |
|
109 | status=200) | |
|
110 | ||
|
111 | assert response.json['store_fid'] |
@@ -0,0 +1,47 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | ||
|
21 | ||
|
22 | import os | |
|
23 | import uuid | |
|
24 | ||
|
25 | ||
|
26 | def get_file_storage(settings): | |
|
27 | from rhodecode.apps.file_store.local_store import LocalFileStorage | |
|
28 | from rhodecode.apps.file_store import config_keys | |
|
29 | store_path = settings.get(config_keys.store_path) | |
|
30 | return LocalFileStorage(base_path=store_path) | |
|
31 | ||
|
32 | ||
|
33 | def uid_filename(filename, randomized=True): | |
|
34 | """ | |
|
35 | Generates a randomized or stable (uuid) filename, | |
|
36 | preserving the original extension. | |
|
37 | ||
|
38 | :param filename: the original filename | |
|
39 | :param randomized: define if filename should be stable (sha1 based) or randomized | |
|
40 | """ | |
|
41 | _, ext = os.path.splitext(filename) | |
|
42 | if randomized: | |
|
43 | uid = uuid.uuid4() | |
|
44 | else: | |
|
45 | hash_key = '{}.{}'.format(filename, 'store') | |
|
46 | uid = uuid.uuid5(uuid.NAMESPACE_URL, hash_key) | |
|
47 | return str(uid) + ext.lower() |
@@ -0,0 +1,115 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | ||
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | # | |
|
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 | |
|
7 | # (only), as published by the Free Software Foundation. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
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/>. | |
|
16 | # | |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
20 | import logging | |
|
21 | ||
|
22 | from pyramid.view import view_config | |
|
23 | from pyramid.response import FileResponse | |
|
24 | from pyramid.httpexceptions import HTTPFound, HTTPNotFound | |
|
25 | ||
|
26 | from rhodecode.apps._base import BaseAppView | |
|
27 | from rhodecode.apps.file_store import utils | |
|
28 | from rhodecode.apps.file_store.exceptions import ( | |
|
29 | FileNotAllowedException, FileOverSizeException) | |
|
30 | ||
|
31 | from rhodecode.lib import helpers as h | |
|
32 | from rhodecode.lib import audit_logger | |
|
33 | from rhodecode.lib.auth import (CSRFRequired, NotAnonymous) | |
|
34 | from rhodecode.model.db import Session, FileStore | |
|
35 | ||
|
36 | log = logging.getLogger(__name__) | |
|
37 | ||
|
38 | ||
|
39 | class FileStoreView(BaseAppView): | |
|
40 | upload_key = 'store_file' | |
|
41 | ||
|
42 | def load_default_context(self): | |
|
43 | c = self._get_local_tmpl_context() | |
|
44 | self.storage = utils.get_file_storage(self.request.registry.settings) | |
|
45 | return c | |
|
46 | ||
|
47 | @NotAnonymous() | |
|
48 | @CSRFRequired() | |
|
49 | @view_config(route_name='upload_file', request_method='POST', renderer='json_ext') | |
|
50 | def upload_file(self): | |
|
51 | self.load_default_context() | |
|
52 | file_obj = self.request.POST.get(self.upload_key) | |
|
53 | ||
|
54 | if file_obj is None: | |
|
55 | return {'store_fid': None, | |
|
56 | 'access_path': None, | |
|
57 | 'error': '{} data field is missing'.format(self.upload_key)} | |
|
58 | ||
|
59 | if not hasattr(file_obj, 'filename'): | |
|
60 | return {'store_fid': None, | |
|
61 | 'access_path': None, | |
|
62 | 'error': 'filename cannot be read from the data field'} | |
|
63 | ||
|
64 | filename = file_obj.filename | |
|
65 | ||
|
66 | metadata = { | |
|
67 | 'user_uploaded': {'username': self._rhodecode_user.username, | |
|
68 | 'user_id': self._rhodecode_user.user_id, | |
|
69 | 'ip': self._rhodecode_user.ip_addr}} | |
|
70 | try: | |
|
71 | store_fid, metadata = self.storage.save_file( | |
|
72 | file_obj.file, filename, extra_metadata=metadata) | |
|
73 | except FileNotAllowedException: | |
|
74 | return {'store_fid': None, | |
|
75 | 'access_path': None, | |
|
76 | 'error': 'File {} is not allowed.'.format(filename)} | |
|
77 | ||
|
78 | except FileOverSizeException: | |
|
79 | return {'store_fid': None, | |
|
80 | 'access_path': None, | |
|
81 | 'error': 'File {} is exceeding allowed limit.'.format(filename)} | |
|
82 | ||
|
83 | try: | |
|
84 | entry = FileStore.create( | |
|
85 | file_uid=store_fid, filename=metadata["filename"], | |
|
86 | file_hash=metadata["sha256"], file_size=metadata["size"], | |
|
87 | file_description='upload attachment', | |
|
88 | check_acl=False, user_id=self._rhodecode_user.user_id | |
|
89 | ) | |
|
90 | Session().add(entry) | |
|
91 | Session().commit() | |
|
92 | log.debug('Stored upload in DB as %s', entry) | |
|
93 | except Exception: | |
|
94 | log.exception('Failed to store file %s', filename) | |
|
95 | return {'store_fid': None, | |
|
96 | 'access_path': None, | |
|
97 | 'error': 'File {} failed to store in DB.'.format(filename)} | |
|
98 | ||
|
99 | return {'store_fid': store_fid, | |
|
100 | 'access_path': h.route_path('download_file', fid=store_fid)} | |
|
101 | ||
|
102 | @view_config(route_name='download_file') | |
|
103 | def download_file(self): | |
|
104 | self.load_default_context() | |
|
105 | file_uid = self.request.matchdict['fid'] | |
|
106 | log.debug('Requesting FID:%s from store %s', file_uid, self.storage) | |
|
107 | ||
|
108 | if not self.storage.exists(file_uid): | |
|
109 | log.debug('File with FID:%s not found in the store', file_uid) | |
|
110 | raise HTTPNotFound() | |
|
111 | ||
|
112 | FileStore.bump_access_counter(file_uid) | |
|
113 | ||
|
114 | file_path = self.storage.store_path(file_uid) | |
|
115 | return FileResponse(file_path) |
@@ -0,0 +1,110 b'' | |||
|
1 | # Example to validate pushed files names and size using some sort of rules | |
|
2 | ||
|
3 | ||
|
4 | ||
|
5 | @has_kwargs({ | |
|
6 | 'server_url': 'url of instance that triggered this hook', | |
|
7 | 'config': 'path to .ini config used', | |
|
8 | 'scm': 'type of version control "git", "hg", "svn"', | |
|
9 | 'username': 'username of actor who triggered this event', | |
|
10 | 'ip': 'ip address of actor who triggered this hook', | |
|
11 | 'action': '', | |
|
12 | 'repository': 'repository name', | |
|
13 | 'repo_store_path': 'full path to where repositories are stored', | |
|
14 | 'commit_ids': 'pre transaction metadata for commit ids', | |
|
15 | 'hook_type': '', | |
|
16 | 'user_agent': 'Client user agent, e.g git or mercurial CLI version', | |
|
17 | }) | |
|
18 | def _pre_push_hook(*args, **kwargs): | |
|
19 | """ | |
|
20 | Post push hook | |
|
21 | To stop version control from storing the transaction and send a message to user | |
|
22 | use non-zero HookResponse with a message, e.g return HookResponse(1, 'Not allowed') | |
|
23 | ||
|
24 | This message will be shown back to client during PUSH operation | |
|
25 | ||
|
26 | Commit ids might look like that:: | |
|
27 | ||
|
28 | [{u'hg_env|git_env': ..., | |
|
29 | u'multiple_heads': [], | |
|
30 | u'name': u'default', | |
|
31 | u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69', | |
|
32 | u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69', | |
|
33 | u'ref': u'', | |
|
34 | u'total_commits': 2, | |
|
35 | u'type': u'branch'}] | |
|
36 | """ | |
|
37 | import fnmatch | |
|
38 | from .helpers import extra_fields, extract_pre_files | |
|
39 | from .utils import str2bool, aslist | |
|
40 | from rhodecode.lib.helpers import format_byte_size_binary | |
|
41 | ||
|
42 | # returns list of dicts with key-val fetched from extra fields | |
|
43 | repo_extra_fields = extra_fields.run(**kwargs) | |
|
44 | ||
|
45 | # optionally use 'extra fields' to control the logic per repo | |
|
46 | # e.g store a list of patterns to be forbidden e.g `*.exe, *.dump` | |
|
47 | forbid_files = repo_extra_fields.get('forbid_files_glob', {}).get('field_value') | |
|
48 | forbid_files = aslist(forbid_files) | |
|
49 | ||
|
50 | # optionally get bytes limit for a single file, e.g 1024 for 1KB | |
|
51 | forbid_size_over = repo_extra_fields.get('forbid_size_over', {}).get('field_value') | |
|
52 | forbid_size_over = int(forbid_size_over or 0) | |
|
53 | ||
|
54 | def validate_file_name_and_size(file_data, forbidden_files=None, size_limit=None): | |
|
55 | """ | |
|
56 | This function validates commited files against some sort of rules. | |
|
57 | It should return a valid boolean, and a reason for failure | |
|
58 | ||
|
59 | file_data =[ | |
|
60 | 'raw_diff', 'old_revision', 'stats', 'original_filename', 'is_limited_diff', | |
|
61 | 'chunks', 'new_revision', 'operation', 'exceeds_limit', 'filename' | |
|
62 | ] | |
|
63 | file_data['ops'] = { | |
|
64 | # is file binary | |
|
65 | 'binary': False, | |
|
66 | ||
|
67 | # lines | |
|
68 | 'added': 32, | |
|
69 | 'deleted': 0 | |
|
70 | ||
|
71 | 'ops': {3: 'modified file'}, | |
|
72 | 'new_mode': '100644', | |
|
73 | 'old_mode': None | |
|
74 | } | |
|
75 | """ | |
|
76 | file_name = file_data['filename'] | |
|
77 | operation = file_data['operation'] # can be A(dded), M(odified), D(eleted) | |
|
78 | ||
|
79 | # check files names | |
|
80 | if forbidden_files: | |
|
81 | reason = 'File {} is forbidden to be pushed'.format(file_name) | |
|
82 | for forbidden_pattern in forbid_files: | |
|
83 | # here we can also filter for operation, e.g if check for only ADDED files | |
|
84 | # if operation == 'A': | |
|
85 | if fnmatch.fnmatch(file_name, forbidden_pattern): | |
|
86 | return False, reason | |
|
87 | ||
|
88 | # validate A(dded) files and size | |
|
89 | if size_limit and operation == 'A': | |
|
90 | size = len(file_data['raw_diff']) | |
|
91 | ||
|
92 | reason = 'File {} size of {} bytes exceeds limit {}'.format( | |
|
93 | file_name, format_byte_size_binary(size), | |
|
94 | format_byte_size_binary(size_limit)) | |
|
95 | if size > size_limit: | |
|
96 | return False, reason | |
|
97 | ||
|
98 | return True, '' | |
|
99 | ||
|
100 | if forbid_files or forbid_size_over: | |
|
101 | # returns list of dicts with key-val fetched from extra fields | |
|
102 | file_list = extract_pre_files.run(**kwargs) | |
|
103 | ||
|
104 | for file_data in file_list: | |
|
105 | file_valid, reason = validate_file_name_and_size( | |
|
106 | file_data, forbid_files, forbid_size_over) | |
|
107 | if not file_valid: | |
|
108 | return HookResponse(1, reason) | |
|
109 | ||
|
110 | return HookResponse(0, '') |
@@ -0,0 +1,96 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
3 | # | |
|
4 | # This program is free software: you can redistribute it and/or modify | |
|
5 | # it under the terms of the GNU Affero General Public License, version 3 | |
|
6 | # (only), as published by the Free Software Foundation. | |
|
7 | # | |
|
8 | # This program is distributed in the hope that it will be useful, | |
|
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
11 | # GNU General Public License for more details. | |
|
12 | # | |
|
13 | # You should have received a copy of the GNU Affero General Public License | |
|
14 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
|
15 | # | |
|
16 | # This program is dual-licensed. If you wish to learn more about the | |
|
17 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
|
18 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
|
19 | ||
|
20 | """ | |
|
21 | us in hooks:: | |
|
22 | ||
|
23 | from .helpers import extract_pre_files | |
|
24 | # returns list of dicts with key-val fetched from extra fields | |
|
25 | file_list = extract_pre_files.run(**kwargs) | |
|
26 | ||
|
27 | """ | |
|
28 | import re | |
|
29 | import collections | |
|
30 | import json | |
|
31 | ||
|
32 | from rhodecode.lib import diffs | |
|
33 | from rhodecode.lib.vcs.backends.hg.diff import MercurialDiff | |
|
34 | from rhodecode.lib.vcs.backends.git.diff import GitDiff | |
|
35 | ||
|
36 | ||
|
37 | def get_hg_files(repo, refs): | |
|
38 | files = [] | |
|
39 | return files | |
|
40 | ||
|
41 | ||
|
42 | def get_git_files(repo, refs): | |
|
43 | files = [] | |
|
44 | ||
|
45 | for data in refs: | |
|
46 | # we should now extract commit data | |
|
47 | old_rev = data['old_rev'] | |
|
48 | new_rev = data['new_rev'] | |
|
49 | ||
|
50 | if '00000000' in old_rev: | |
|
51 | # new branch, we don't need to extract nothing | |
|
52 | return files | |
|
53 | ||
|
54 | git_env = dict(data['git_env']) | |
|
55 | ||
|
56 | cmd = [ | |
|
57 | 'diff', old_rev, new_rev | |
|
58 | ] | |
|
59 | ||
|
60 | stdout, stderr = repo.run_git_command(cmd, extra_env=git_env) | |
|
61 | vcs_diff = GitDiff(stdout) | |
|
62 | ||
|
63 | diff_processor = diffs.DiffProcessor(vcs_diff, format='newdiff') | |
|
64 | # this is list of dicts with diff information | |
|
65 | # _parsed[0].keys() | |
|
66 | # ['raw_diff', 'old_revision', 'stats', 'original_filename', | |
|
67 | # 'is_limited_diff', 'chunks', 'new_revision', 'operation', | |
|
68 | # 'exceeds_limit', 'filename'] | |
|
69 | files = _parsed = diff_processor.prepare() | |
|
70 | ||
|
71 | return files | |
|
72 | ||
|
73 | ||
|
74 | def run(*args, **kwargs): | |
|
75 | from rhodecode.model.db import Repository | |
|
76 | ||
|
77 | vcs_type = kwargs['scm'] | |
|
78 | # use temp name then the main one propagated | |
|
79 | repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository'] | |
|
80 | ||
|
81 | repo = Repository.get_by_repo_name(repo_name) | |
|
82 | vcs_repo = repo.scm_instance(cache=False) | |
|
83 | ||
|
84 | files = [] | |
|
85 | ||
|
86 | if vcs_type == 'git': | |
|
87 | for rev_data in kwargs['commit_ids']: | |
|
88 | new_environ = dict((k, v) for k, v in rev_data['git_env']) | |
|
89 | files = get_git_files(vcs_repo, kwargs['commit_ids']) | |
|
90 | ||
|
91 | if vcs_type == 'hg': | |
|
92 | for rev_data in kwargs['commit_ids']: | |
|
93 | new_environ = dict((k, v) for k, v in rev_data['hg_env']) | |
|
94 | files = get_hg_files(vcs_repo, kwargs['commit_ids']) | |
|
95 | ||
|
96 | return files |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: new file 100644 | |
The requested commit or file is too big and content was truncated. Show full diff |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | [bumpversion] |
|
2 |
current_version = 4.1 |
|
|
2 | current_version = 4.16.0 | |
|
3 | 3 | message = release: Bump version {current_version} to {new_version} |
|
4 | 4 | |
|
5 | 5 | [bumpversion:file:rhodecode/VERSION] |
@@ -5,25 +5,20 b' done = false' | |||
|
5 | 5 | done = true |
|
6 | 6 | |
|
7 | 7 | [task:rc_tools_pinned] |
|
8 | done = true | |
|
9 | 8 | |
|
10 | 9 | [task:fixes_on_stable] |
|
11 | done = true | |
|
12 | 10 | |
|
13 | 11 | [task:pip2nix_generated] |
|
14 | done = true | |
|
15 | 12 | |
|
16 | 13 | [task:changelog_updated] |
|
17 | done = true | |
|
18 | 14 | |
|
19 | 15 | [task:generate_api_docs] |
|
20 | done = true | |
|
16 | ||
|
17 | [task:updated_translation] | |
|
21 | 18 | |
|
22 | 19 | [release] |
|
23 |
state = |
|
|
24 |
version = 4.1 |
|
|
25 | ||
|
26 | [task:updated_translation] | |
|
20 | state = in_progress | |
|
21 | version = 4.16.0 | |
|
27 | 22 | |
|
28 | 23 | [task:generate_js_routes] |
|
29 | 24 |
@@ -12,8 +12,6 b' permission notice:' | |||
|
12 | 12 | file:licenses/msgpack_license.txt |
|
13 | 13 | Copyright (c) 2009 - tornado |
|
14 | 14 | file:licenses/tornado_license.txt |
|
15 | Copyright (c) 2015 - pygments-markdown-lexer | |
|
16 | file:licenses/pygments_markdown_lexer_license.txt | |
|
17 | 15 | Copyright 2006 - diff_match_patch |
|
18 | 16 | file:licenses/diff_match_patch_license.txt |
|
19 | 17 |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | |
|
2 | .PHONY: clean docs docs-clean docs-cleanup test test-clean test-only test-only-postgres test-only-mysql web-build | |
|
2 | .PHONY: clean docs docs-clean docs-cleanup test test-clean test-only test-only-postgres test-only-mysql web-build generate-pkgs | |
|
3 | 3 | |
|
4 | 4 | NODE_PATH=./node_modules |
|
5 | 5 | WEBPACK=./node_binaries/webpack |
@@ -8,7 +8,7 b' GRUNT=./node_binaries/grunt' | |||
|
8 | 8 | |
|
9 | 9 | clean: |
|
10 | 10 | make test-clean |
|
11 | find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' \) -exec rm '{}' ';' | |
|
11 | find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' -o -iname '*.orig' \) -exec rm '{}' ';' | |
|
12 | 12 | |
|
13 | 13 | test: |
|
14 | 14 | make test-clean |
@@ -51,3 +51,5 b' docs-cleanup:' | |||
|
51 | 51 | web-build: |
|
52 | 52 | NODE_PATH=$(NODE_PATH) $(GRUNT) |
|
53 | 53 | |
|
54 | generate-pkgs: | |
|
55 | nix-shell pkgs/shell-generate.nix --command "pip2nix generate --licenses" |
@@ -53,7 +53,7 b' asyncore_use_poll = true' | |||
|
53 | 53 | ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini |
|
54 | 54 | |
|
55 | 55 | #use = egg:gunicorn#main |
|
56 | ## Sets the number of process workers. More workers means more concurent connections | |
|
56 | ## Sets the number of process workers. More workers means more concurrent connections | |
|
57 | 57 | ## RhodeCode can handle at the same time. Each additional worker also it increases |
|
58 | 58 | ## memory usage as each has it's own set of caches. |
|
59 | 59 | ## Recommended value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers, but no more |
@@ -133,10 +133,10 b' rhodecode.api.url = /_admin/api' | |||
|
133 | 133 | ## `SignatureVerificationError` in case of wrong key, or damaged encryption data. |
|
134 | 134 | #rhodecode.encrypted_values.strict = false |
|
135 | 135 | |
|
136 |
## return gzipped responses from Rhode |
|
|
136 | ## return gzipped responses from RhodeCode (static files/application) | |
|
137 | 137 | gzip_responses = false |
|
138 | 138 | |
|
139 | ## autogenerate javascript routes file on startup | |
|
139 | ## auto-generate javascript routes file on startup | |
|
140 | 140 | generate_js_files = false |
|
141 | 141 | |
|
142 | 142 | ## System global default language. |
@@ -153,7 +153,7 b' startup.import_repos = false' | |||
|
153 | 153 | ## the repository. |
|
154 | 154 | #archive_cache_dir = /tmp/tarballcache |
|
155 | 155 | |
|
156 |
## URL at which the application is running. This is used for |
|
|
156 | ## URL at which the application is running. This is used for Bootstrapping | |
|
157 | 157 | ## requests in context when no web request is available. Used in ishell, or |
|
158 | 158 | ## SSH calls. Set this for events to receive proper url for SSH calls. |
|
159 | 159 | app.base_url = http://rhodecode.local |
@@ -203,7 +203,7 b' gist_alias_url =' | |||
|
203 | 203 | ## used for access. |
|
204 | 204 | ## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it |
|
205 | 205 | ## came from the the logged in user who own this authentication token. |
|
206 |
## Additionally @TOKEN syntax |
|
|
206 | ## Additionally @TOKEN syntax can be used to bound the view to specific | |
|
207 | 207 | ## authentication token. Such view would be only accessible when used together |
|
208 | 208 | ## with this authentication token |
|
209 | 209 | ## |
@@ -227,14 +227,14 b' default_encoding = UTF-8' | |||
|
227 | 227 | |
|
228 | 228 | ## instance-id prefix |
|
229 | 229 | ## a prefix key for this instance used for cache invalidation when running |
|
230 |
## multiple instances of |
|
|
231 |
## all running |
|
|
230 | ## multiple instances of RhodeCode, make sure it's globally unique for | |
|
231 | ## all running RhodeCode instances. Leave empty if you don't use it | |
|
232 | 232 | instance_id = |
|
233 | 233 | |
|
234 | 234 | ## Fallback authentication plugin. Set this to a plugin ID to force the usage |
|
235 | 235 | ## of an authentication plugin also if it is disabled by it's settings. |
|
236 | 236 | ## This could be useful if you are unable to log in to the system due to broken |
|
237 |
## authentication settings. Then you can enable e.g. the internal |
|
|
237 | ## authentication settings. Then you can enable e.g. the internal RhodeCode auth | |
|
238 | 238 | ## module to log in again and fix the settings. |
|
239 | 239 | ## |
|
240 | 240 | ## Available builtin plugin IDs (hash is part of the ID): |
@@ -250,7 +250,7 b' instance_id =' | |||
|
250 | 250 | ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with |
|
251 | 251 | ## handling that causing a series of failed authentication calls. |
|
252 | 252 | ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code |
|
253 |
## This will be served instead of default 401 on bad auth |
|
|
253 | ## This will be served instead of default 401 on bad authentication | |
|
254 | 254 | auth_ret_code = |
|
255 | 255 | |
|
256 | 256 | ## use special detection method when serving auth_ret_code, instead of serving |
@@ -284,6 +284,13 b' labs_settings_active = true' | |||
|
284 | 284 | ## This is used to store exception from RhodeCode in shared directory |
|
285 | 285 | #exception_tracker.store_path = |
|
286 | 286 | |
|
287 | ## File store configuration. This is used to store and serve uploaded files | |
|
288 | file_store.enabled = true | |
|
289 | ## Storage backend, available options are: local | |
|
290 | file_store.backend = local | |
|
291 | ## path to store the uploaded binaries | |
|
292 | file_store.storage_path = %(here)s/data/file_store | |
|
293 | ||
|
287 | 294 | |
|
288 | 295 | #################################### |
|
289 | 296 | ### CELERY CONFIG #### |
@@ -325,6 +332,7 b' rc_cache.cache_perms.expiration_time = 3' | |||
|
325 | 332 | #rc_cache.cache_perms.arguments.host = localhost |
|
326 | 333 | #rc_cache.cache_perms.arguments.port = 6379 |
|
327 | 334 | #rc_cache.cache_perms.arguments.db = 0 |
|
335 | ## more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends | |
|
328 | 336 | #rc_cache.cache_perms.arguments.distributed_lock = true |
|
329 | 337 | |
|
330 | 338 | ## `cache_repo` cache settings for FileTree, Readme, RSS FEEDS |
@@ -340,6 +348,7 b' rc_cache.cache_repo.expiration_time = 25' | |||
|
340 | 348 | #rc_cache.cache_repo.arguments.host = localhost |
|
341 | 349 | #rc_cache.cache_repo.arguments.port = 6379 |
|
342 | 350 | #rc_cache.cache_repo.arguments.db = 1 |
|
351 | ## more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends | |
|
343 | 352 | #rc_cache.cache_repo.arguments.distributed_lock = true |
|
344 | 353 | |
|
345 | 354 | ## cache settings for SQL queries, this needs to use memory type backend |
@@ -424,7 +433,7 b' channelstream.server = 127.0.0.1:9800' | |||
|
424 | 433 | ## location of the channelstream server from outside world |
|
425 | 434 | ## use ws:// for http or wss:// for https. This address needs to be handled |
|
426 | 435 | ## by external HTTP server such as Nginx or Apache |
|
427 |
## see |
|
|
436 | ## see Nginx/Apache configuration examples in our docs | |
|
428 | 437 | channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream |
|
429 | 438 | channelstream.secret = secret |
|
430 | 439 | channelstream.history.location = %(here)s/channelstream_history |
@@ -441,14 +450,14 b' channelstream.proxy_path = /_channelstre' | |||
|
441 | 450 | ## Appenlight is tailored to work with RhodeCode, see |
|
442 | 451 | ## http://appenlight.com for details how to obtain an account |
|
443 | 452 | |
|
444 |
## |
|
|
453 | ## Appenlight integration enabled | |
|
445 | 454 | appenlight = false |
|
446 | 455 | |
|
447 | 456 | appenlight.server_url = https://api.appenlight.com |
|
448 | 457 | appenlight.api_key = YOUR_API_KEY |
|
449 | 458 | #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5 |
|
450 | 459 | |
|
451 | # used for JS client | |
|
460 | ## used for JS client | |
|
452 | 461 | appenlight.api_public_key = YOUR_API_PUBLIC_KEY |
|
453 | 462 | |
|
454 | 463 | ## TWEAK AMOUNT OF INFO SENT HERE |
@@ -473,7 +482,7 b' appenlight.logging.level = WARNING' | |||
|
473 | 482 | ## (saves API quota for intensive logging) |
|
474 | 483 | appenlight.logging_on_error = false |
|
475 | 484 | |
|
476 | ## list of additonal keywords that should be grabbed from environ object | |
|
485 | ## list of additional keywords that should be grabbed from environ object | |
|
477 | 486 | ## can be string with comma separated list of words in lowercase |
|
478 | 487 | ## (by default client will always send following info: |
|
479 | 488 | ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that |
@@ -533,7 +542,7 b' sqlalchemy.db1.convert_unicode = true' | |||
|
533 | 542 | vcs.server.enable = true |
|
534 | 543 | vcs.server = localhost:9900 |
|
535 | 544 | |
|
536 |
## Web server connectivity protocol, responsible for web based VCS operat |
|
|
545 | ## Web server connectivity protocol, responsible for web based VCS operations | |
|
537 | 546 | ## Available protocols are: |
|
538 | 547 | ## `http` - use http-rpc backend (default) |
|
539 | 548 | vcs.server.protocol = http |
@@ -582,7 +591,8 b' svn.proxy.config_file_path = %(here)s/mo' | |||
|
582 | 591 | ## In most cases it should be set to `/`. |
|
583 | 592 | svn.proxy.location_root = / |
|
584 | 593 | ## Command to reload the mod dav svn configuration on change. |
|
585 | ## Example: `/etc/init.d/apache2 reload` | |
|
594 | ## Example: `/etc/init.d/apache2 reload` or /home/USER/apache_reload.sh | |
|
595 | ## Make sure user who runs RhodeCode process is allowed to reload Apache | |
|
586 | 596 | #svn.proxy.reload_cmd = /etc/init.d/apache2 reload |
|
587 | 597 | ## If the timeout expires before the reload command finishes, the command will |
|
588 | 598 | ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds. |
@@ -593,7 +603,7 b' svn.proxy.location_root = /' | |||
|
593 | 603 | ############################################################ |
|
594 | 604 | |
|
595 | 605 | ## Defines if a custom authorized_keys file should be created and written on |
|
596 | ## any change user ssh keys. Setting this to false also disables posibility | |
|
606 | ## any change user ssh keys. Setting this to false also disables possibility | |
|
597 | 607 | ## of adding SSH keys by users from web interface. Super admins can still |
|
598 | 608 | ## manage SSH Keys. |
|
599 | 609 | ssh.generate_authorized_keyfile = false |
@@ -601,13 +611,13 b' ssh.generate_authorized_keyfile = false' | |||
|
601 | 611 | ## Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding` |
|
602 | 612 | # ssh.authorized_keys_ssh_opts = |
|
603 | 613 | |
|
604 |
## Path to the auth |
|
|
614 | ## Path to the authorized_keys file where the generate entries are placed. | |
|
605 | 615 | ## It is possible to have multiple key files specified in `sshd_config` e.g. |
|
606 | 616 | ## AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode |
|
607 | 617 | ssh.authorized_keys_file_path = ~/.ssh/authorized_keys_rhodecode |
|
608 | 618 | |
|
609 | 619 | ## Command to execute the SSH wrapper. The binary is available in the |
|
610 |
## |
|
|
620 | ## RhodeCode installation directory. | |
|
611 | 621 | ## e.g ~/.rccontrol/community-1/profile/bin/rc-ssh-wrapper |
|
612 | 622 | ssh.wrapper_cmd = ~/.rccontrol/community-1/rc-ssh-wrapper |
|
613 | 623 | |
@@ -615,7 +625,7 b' ssh.wrapper_cmd = ~/.rccontrol/community' | |||
|
615 | 625 | ssh.wrapper_cmd_allow_shell = false |
|
616 | 626 | |
|
617 | 627 | ## Enables logging, and detailed output send back to the client during SSH |
|
618 |
## operations. Useful |
|
|
628 | ## operations. Useful for debugging, shouldn't be used in production. | |
|
619 | 629 | ssh.enable_debug_logging = true |
|
620 | 630 | |
|
621 | 631 | ## Paths to binary executable, by default they are the names, but we can |
@@ -624,6 +634,10 b' ssh.executable.hg = ~/.rccontrol/vcsserv' | |||
|
624 | 634 | ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git |
|
625 | 635 | ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve |
|
626 | 636 | |
|
637 | ## Enables SSH key generator web interface. Disabling this still allows users | |
|
638 | ## to add their own keys. | |
|
639 | ssh.enable_ui_key_generator = true | |
|
640 | ||
|
627 | 641 | |
|
628 | 642 | ## Dummy marker to add new entries after. |
|
629 | 643 | ## Add any custom entries below. Please don't remove. |
@@ -53,7 +53,7 b' port = 5000' | |||
|
53 | 53 | ## run with gunicorn --log-config rhodecode.ini --paste rhodecode.ini |
|
54 | 54 | |
|
55 | 55 | use = egg:gunicorn#main |
|
56 | ## Sets the number of process workers. More workers means more concurent connections | |
|
56 | ## Sets the number of process workers. More workers means more concurrent connections | |
|
57 | 57 | ## RhodeCode can handle at the same time. Each additional worker also it increases |
|
58 | 58 | ## memory usage as each has it's own set of caches. |
|
59 | 59 | ## Recommended value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers, but no more |
@@ -108,10 +108,10 b' use = egg:rhodecode-enterprise-ce' | |||
|
108 | 108 | ## `SignatureVerificationError` in case of wrong key, or damaged encryption data. |
|
109 | 109 | #rhodecode.encrypted_values.strict = false |
|
110 | 110 | |
|
111 |
## return gzipped responses from Rhode |
|
|
111 | ## return gzipped responses from RhodeCode (static files/application) | |
|
112 | 112 | gzip_responses = false |
|
113 | 113 | |
|
114 | ## autogenerate javascript routes file on startup | |
|
114 | ## auto-generate javascript routes file on startup | |
|
115 | 115 | generate_js_files = false |
|
116 | 116 | |
|
117 | 117 | ## System global default language. |
@@ -128,7 +128,7 b' startup.import_repos = false' | |||
|
128 | 128 | ## the repository. |
|
129 | 129 | #archive_cache_dir = /tmp/tarballcache |
|
130 | 130 | |
|
131 |
## URL at which the application is running. This is used for |
|
|
131 | ## URL at which the application is running. This is used for Bootstrapping | |
|
132 | 132 | ## requests in context when no web request is available. Used in ishell, or |
|
133 | 133 | ## SSH calls. Set this for events to receive proper url for SSH calls. |
|
134 | 134 | app.base_url = http://rhodecode.local |
@@ -178,7 +178,7 b' gist_alias_url =' | |||
|
178 | 178 | ## used for access. |
|
179 | 179 | ## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it |
|
180 | 180 | ## came from the the logged in user who own this authentication token. |
|
181 |
## Additionally @TOKEN syntax |
|
|
181 | ## Additionally @TOKEN syntax can be used to bound the view to specific | |
|
182 | 182 | ## authentication token. Such view would be only accessible when used together |
|
183 | 183 | ## with this authentication token |
|
184 | 184 | ## |
@@ -202,14 +202,14 b' default_encoding = UTF-8' | |||
|
202 | 202 | |
|
203 | 203 | ## instance-id prefix |
|
204 | 204 | ## a prefix key for this instance used for cache invalidation when running |
|
205 |
## multiple instances of |
|
|
206 |
## all running |
|
|
205 | ## multiple instances of RhodeCode, make sure it's globally unique for | |
|
206 | ## all running RhodeCode instances. Leave empty if you don't use it | |
|
207 | 207 | instance_id = |
|
208 | 208 | |
|
209 | 209 | ## Fallback authentication plugin. Set this to a plugin ID to force the usage |
|
210 | 210 | ## of an authentication plugin also if it is disabled by it's settings. |
|
211 | 211 | ## This could be useful if you are unable to log in to the system due to broken |
|
212 |
## authentication settings. Then you can enable e.g. the internal |
|
|
212 | ## authentication settings. Then you can enable e.g. the internal RhodeCode auth | |
|
213 | 213 | ## module to log in again and fix the settings. |
|
214 | 214 | ## |
|
215 | 215 | ## Available builtin plugin IDs (hash is part of the ID): |
@@ -225,7 +225,7 b' instance_id =' | |||
|
225 | 225 | ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with |
|
226 | 226 | ## handling that causing a series of failed authentication calls. |
|
227 | 227 | ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code |
|
228 |
## This will be served instead of default 401 on bad auth |
|
|
228 | ## This will be served instead of default 401 on bad authentication | |
|
229 | 229 | auth_ret_code = |
|
230 | 230 | |
|
231 | 231 | ## use special detection method when serving auth_ret_code, instead of serving |
@@ -259,6 +259,13 b' labs_settings_active = true' | |||
|
259 | 259 | ## This is used to store exception from RhodeCode in shared directory |
|
260 | 260 | #exception_tracker.store_path = |
|
261 | 261 | |
|
262 | ## File store configuration. This is used to store and serve uploaded files | |
|
263 | file_store.enabled = true | |
|
264 | ## Storage backend, available options are: local | |
|
265 | file_store.backend = local | |
|
266 | ## path to store the uploaded binaries | |
|
267 | file_store.storage_path = %(here)s/data/file_store | |
|
268 | ||
|
262 | 269 | |
|
263 | 270 | #################################### |
|
264 | 271 | ### CELERY CONFIG #### |
@@ -300,6 +307,7 b' rc_cache.cache_perms.expiration_time = 3' | |||
|
300 | 307 | #rc_cache.cache_perms.arguments.host = localhost |
|
301 | 308 | #rc_cache.cache_perms.arguments.port = 6379 |
|
302 | 309 | #rc_cache.cache_perms.arguments.db = 0 |
|
310 | ## more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends | |
|
303 | 311 | #rc_cache.cache_perms.arguments.distributed_lock = true |
|
304 | 312 | |
|
305 | 313 | ## `cache_repo` cache settings for FileTree, Readme, RSS FEEDS |
@@ -315,6 +323,7 b' rc_cache.cache_repo.expiration_time = 25' | |||
|
315 | 323 | #rc_cache.cache_repo.arguments.host = localhost |
|
316 | 324 | #rc_cache.cache_repo.arguments.port = 6379 |
|
317 | 325 | #rc_cache.cache_repo.arguments.db = 1 |
|
326 | ## more Redis options: https://dogpilecache.sqlalchemy.org/en/latest/api.html#redis-backends | |
|
318 | 327 | #rc_cache.cache_repo.arguments.distributed_lock = true |
|
319 | 328 | |
|
320 | 329 | ## cache settings for SQL queries, this needs to use memory type backend |
@@ -399,7 +408,7 b' channelstream.server = 127.0.0.1:9800' | |||
|
399 | 408 | ## location of the channelstream server from outside world |
|
400 | 409 | ## use ws:// for http or wss:// for https. This address needs to be handled |
|
401 | 410 | ## by external HTTP server such as Nginx or Apache |
|
402 |
## see |
|
|
411 | ## see Nginx/Apache configuration examples in our docs | |
|
403 | 412 | channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream |
|
404 | 413 | channelstream.secret = secret |
|
405 | 414 | channelstream.history.location = %(here)s/channelstream_history |
@@ -416,14 +425,14 b' channelstream.proxy_path = /_channelstre' | |||
|
416 | 425 | ## Appenlight is tailored to work with RhodeCode, see |
|
417 | 426 | ## http://appenlight.com for details how to obtain an account |
|
418 | 427 | |
|
419 |
## |
|
|
428 | ## Appenlight integration enabled | |
|
420 | 429 | appenlight = false |
|
421 | 430 | |
|
422 | 431 | appenlight.server_url = https://api.appenlight.com |
|
423 | 432 | appenlight.api_key = YOUR_API_KEY |
|
424 | 433 | #appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5 |
|
425 | 434 | |
|
426 | # used for JS client | |
|
435 | ## used for JS client | |
|
427 | 436 | appenlight.api_public_key = YOUR_API_PUBLIC_KEY |
|
428 | 437 | |
|
429 | 438 | ## TWEAK AMOUNT OF INFO SENT HERE |
@@ -448,7 +457,7 b' appenlight.logging.level = WARNING' | |||
|
448 | 457 | ## (saves API quota for intensive logging) |
|
449 | 458 | appenlight.logging_on_error = false |
|
450 | 459 | |
|
451 | ## list of additonal keywords that should be grabbed from environ object | |
|
460 | ## list of additional keywords that should be grabbed from environ object | |
|
452 | 461 | ## can be string with comma separated list of words in lowercase |
|
453 | 462 | ## (by default client will always send following info: |
|
454 | 463 | ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that |
@@ -506,7 +515,7 b' sqlalchemy.db1.convert_unicode = true' | |||
|
506 | 515 | vcs.server.enable = true |
|
507 | 516 | vcs.server = localhost:9900 |
|
508 | 517 | |
|
509 |
## Web server connectivity protocol, responsible for web based VCS operat |
|
|
518 | ## Web server connectivity protocol, responsible for web based VCS operations | |
|
510 | 519 | ## Available protocols are: |
|
511 | 520 | ## `http` - use http-rpc backend (default) |
|
512 | 521 | vcs.server.protocol = http |
@@ -555,7 +564,8 b' svn.proxy.config_file_path = %(here)s/mo' | |||
|
555 | 564 | ## In most cases it should be set to `/`. |
|
556 | 565 | svn.proxy.location_root = / |
|
557 | 566 | ## Command to reload the mod dav svn configuration on change. |
|
558 | ## Example: `/etc/init.d/apache2 reload` | |
|
567 | ## Example: `/etc/init.d/apache2 reload` or /home/USER/apache_reload.sh | |
|
568 | ## Make sure user who runs RhodeCode process is allowed to reload Apache | |
|
559 | 569 | #svn.proxy.reload_cmd = /etc/init.d/apache2 reload |
|
560 | 570 | ## If the timeout expires before the reload command finishes, the command will |
|
561 | 571 | ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds. |
@@ -566,7 +576,7 b' svn.proxy.location_root = /' | |||
|
566 | 576 | ############################################################ |
|
567 | 577 | |
|
568 | 578 | ## Defines if a custom authorized_keys file should be created and written on |
|
569 | ## any change user ssh keys. Setting this to false also disables posibility | |
|
579 | ## any change user ssh keys. Setting this to false also disables possibility | |
|
570 | 580 | ## of adding SSH keys by users from web interface. Super admins can still |
|
571 | 581 | ## manage SSH Keys. |
|
572 | 582 | ssh.generate_authorized_keyfile = false |
@@ -574,13 +584,13 b' ssh.generate_authorized_keyfile = false' | |||
|
574 | 584 | ## Options for ssh, default is `no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding` |
|
575 | 585 | # ssh.authorized_keys_ssh_opts = |
|
576 | 586 | |
|
577 |
## Path to the auth |
|
|
587 | ## Path to the authorized_keys file where the generate entries are placed. | |
|
578 | 588 | ## It is possible to have multiple key files specified in `sshd_config` e.g. |
|
579 | 589 | ## AuthorizedKeysFile %h/.ssh/authorized_keys %h/.ssh/authorized_keys_rhodecode |
|
580 | 590 | ssh.authorized_keys_file_path = ~/.ssh/authorized_keys_rhodecode |
|
581 | 591 | |
|
582 | 592 | ## Command to execute the SSH wrapper. The binary is available in the |
|
583 |
## |
|
|
593 | ## RhodeCode installation directory. | |
|
584 | 594 | ## e.g ~/.rccontrol/community-1/profile/bin/rc-ssh-wrapper |
|
585 | 595 | ssh.wrapper_cmd = ~/.rccontrol/community-1/rc-ssh-wrapper |
|
586 | 596 | |
@@ -588,7 +598,7 b' ssh.wrapper_cmd = ~/.rccontrol/community' | |||
|
588 | 598 | ssh.wrapper_cmd_allow_shell = false |
|
589 | 599 | |
|
590 | 600 | ## Enables logging, and detailed output send back to the client during SSH |
|
591 |
## operations. Useful |
|
|
601 | ## operations. Useful for debugging, shouldn't be used in production. | |
|
592 | 602 | ssh.enable_debug_logging = false |
|
593 | 603 | |
|
594 | 604 | ## Paths to binary executable, by default they are the names, but we can |
@@ -597,6 +607,10 b' ssh.executable.hg = ~/.rccontrol/vcsserv' | |||
|
597 | 607 | ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git |
|
598 | 608 | ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve |
|
599 | 609 | |
|
610 | ## Enables SSH key generator web interface. Disabling this still allows users | |
|
611 | ## to add their own keys. | |
|
612 | ssh.enable_ui_key_generator = true | |
|
613 | ||
|
600 | 614 | |
|
601 | 615 | ## Dummy marker to add new entries after. |
|
602 | 616 | ## Add any custom entries below. Please don't remove. |
@@ -19,14 +19,15 b'' | |||
|
19 | 19 | # } |
|
20 | 20 | |
|
21 | 21 | args@ |
|
22 | { pythonPackages ? "python27Packages" | |
|
22 | { system ? builtins.currentSystem | |
|
23 | , pythonPackages ? "python27Packages" | |
|
23 | 24 | , pythonExternalOverrides ? self: super: {} |
|
24 | 25 | , doCheck ? false |
|
25 | 26 | , ... |
|
26 | 27 | }: |
|
27 | 28 | |
|
28 | 29 | let |
|
29 | pkgs_ = (import <nixpkgs> {}); | |
|
30 | pkgs_ = args.pkgs or (import <nixpkgs> { inherit system; }); | |
|
30 | 31 | in |
|
31 | 32 | |
|
32 | 33 | let |
@@ -80,7 +81,8 b' let' | |||
|
80 | 81 | |
|
81 | 82 | nodeEnv = import ./pkgs/node-default.nix { |
|
82 | 83 | inherit |
|
83 |
pkgs |
|
|
84 | pkgs | |
|
85 | system; | |
|
84 | 86 | }; |
|
85 | 87 | nodeDependencies = nodeEnv.shell.nodeDependencies; |
|
86 | 88 |
@@ -116,7 +116,7 b' Full-text Search Backup' | |||
|
116 | 116 | |
|
117 | 117 | You may also have full text search set up, but the index can be rebuild from |
|
118 | 118 | re-imported |repos| if necessary. You will most likely want to backup your |
|
119 | :file:`mapping.ini` file if you've configured that. For more information, see | |
|
119 | :file:`search_mapping.ini` file if you've configured that. For more information, see | |
|
120 | 120 | the :ref:`indexing-ref` section. |
|
121 | 121 | |
|
122 | 122 | Restoration Steps |
@@ -140,7 +140,7 b' Post Restoration Steps' | |||
|
140 | 140 | Once you have restored your |RCE| instance to basic functionality, you can |
|
141 | 141 | then work on restoring any specific setup changes you had made. |
|
142 | 142 | |
|
143 | * To recreate the |RCE| index, use the backed up :file:`mapping.ini` file if | |
|
143 | * To recreate the |RCE| index, use the backed up :file:`search_mapping.ini` file if | |
|
144 | 144 | you had made changes and rerun the indexer. See the |
|
145 | 145 | :ref:`indexing-ref` section for details. |
|
146 | 146 | * To reconfigure any extensions, copy the backed up extensions into the |
@@ -23,9 +23,9 b' sections.' | |||
|
23 | 23 | * :ref:`increase-gunicorn` |
|
24 | 24 | * :ref:`x-frame` |
|
25 | 25 | |
|
26 | \- **mapping.ini** | |
|
26 | \- **search_mapping.ini** | |
|
27 | 27 | Default location: |
|
28 | :file:`/home/{user}/.rccontrol/{instance-id}/mapping.ini` | |
|
28 | :file:`/home/{user}/.rccontrol/{instance-id}/search_mapping.ini` | |
|
29 | 29 | |
|
30 | 30 | This file is used to control the |RCE| indexer. It comes configured |
|
31 | 31 | to index your instance. To change the default configuration, see |
@@ -3,35 +3,41 b'' | |||
|
3 | 3 | Full-text Search |
|
4 | 4 | ---------------- |
|
5 | 5 | |
|
6 | By default RhodeCode is configured to use `Whoosh`_ to index |repos| and | |
|
7 | provide full-text search. | |
|
6 | RhodeCode provides a full text search capabilities to search inside file content, | |
|
7 | commit message, and file paths. Indexing is not enabled by default and to use | |
|
8 | full text search building an index is a pre-requisite. | |
|
8 | 9 | |
|
9 | |RCE| also provides support for `Elasticsearch`_ as a backend for scalable | |
|
10 | search. See :ref:`enable-elasticsearch` for details. | |
|
10 | By default RhodeCode is configured to use `Whoosh`_ to index |repos| and | |
|
11 | provide full-text search. `Whoosh`_ works well for a small amount of data and | |
|
12 | shouldn't be used in case of large code-bases and lots of repositories. | |
|
13 | ||
|
14 | |RCE| also provides support for `ElasticSearch 6`_ as a backend more for advanced | |
|
15 | and scalable search. See :ref:`enable-elasticsearch` for details. | |
|
11 | 16 | |
|
12 | 17 | Indexing |
|
13 | 18 | ^^^^^^^^ |
|
14 | 19 | |
|
15 |
To run the indexer you need to |
|
|
16 | |repos|. | |
|
20 | To run the indexer you need to have an |authtoken| with admin rights to all |repos|. | |
|
17 | 21 | |
|
18 |
To index |
|
|
22 | To index repositories stored in RhodeCode, you have the option to set the indexer up in a | |
|
19 | 23 | number of ways, for example: |
|
20 | 24 | |
|
21 |
* Call the indexer via a cron job. We recommend running this |
|
|
22 |
|
|
|
23 | * Set the indexer to infinitely loop and reindex as soon as it has run its | |
|
24 | cycle. | |
|
25 | * Call the indexer via a cron job. We recommend running this once at night. | |
|
26 | In case you need everything indexed immediately it's possible to index few | |
|
27 | times during the day. Indexer has a special locking mechanism that won't allow | |
|
28 | two instances of indexer running at once. It's safe to run it even every 1hr. | |
|
29 | * Set the indexer to infinitely loop and reindex as soon as it has run its previous cycle. | |
|
25 | 30 | * Hook the indexer up with your CI server to reindex after each push. |
|
26 | 31 | |
|
27 |
The indexer works by indexing new commits added since the last run |
|
|
28 | wish to build a brand new index from scratch each time, | |
|
29 | use the ``force`` option in the configuration file. | |
|
32 | The indexer works by indexing new commits added since the last run, and comparing | |
|
33 | file changes to index only new or modified files. | |
|
34 | If you wish to build a brand new index from scratch each time, use the ``force`` | |
|
35 | option in the configuration file, or run it with --force flag. | |
|
30 | 36 | |
|
31 | 37 | .. important:: |
|
32 | 38 | |
|
33 | 39 | You need to have |RCT| installed, see :ref:`install-tools`. Since |RCE| |
|
34 | 3.5.0 they are installed by default. | |
|
40 | 3.5.0 they are installed by default and available with community/enterprise installations. | |
|
35 | 41 | |
|
36 | 42 | To set up indexing, use the following steps: |
|
37 | 43 | |
@@ -45,6 +51,13 b' 4. :ref:`advanced-indexing`' | |||
|
45 | 51 | Configure the ``.rhoderc`` File |
|
46 | 52 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
47 | 53 | |
|
54 | .. note:: | |
|
55 | ||
|
56 | Optionally it's possible to use indexer without the ``.rhoderc``. Simply instead of | |
|
57 | executing with `--instance-name=enterprise-1` execute providing the host and token | |
|
58 | directly: `--api-host=http://127.0.0.1:10000 --api-key=<auth-token-goes-here>` | |
|
59 | ||
|
60 | ||
|
48 | 61 | |RCT| uses the :file:`/home/{user}/.rhoderc` file for connection details |
|
49 | 62 | to |RCE| instances. If this file is not automatically created, |
|
50 | 63 | you can configure it using the following example. You need to configure the |
@@ -56,11 +69,11 b' details for each instance you want to in' | |||
|
56 | 69 | # of the instance you want to index |
|
57 | 70 | $ rccontrol status |
|
58 | 71 | |
|
59 |
|
|
|
60 |
|
|
|
61 |
|
|
|
62 |
|
|
|
63 |
|
|
|
72 | - NAME: enterprise-1 | |
|
73 | - STATUS: RUNNING | |
|
74 | - TYPE: Enterprise | |
|
75 | - VERSION: 4.1.0 | |
|
76 | - URL: http://127.0.0.1:10003 | |
|
64 | 77 | |
|
65 | 78 | To get your API Token, on the |RCE| interface go to |
|
66 | 79 | :menuselection:`username --> My Account --> Auth tokens` |
@@ -72,29 +85,35 b' To get your API Token, on the |RCE| inte' | |||
|
72 | 85 | [instance:enterprise-1] |
|
73 | 86 | api_host = http://127.0.0.1:10000 |
|
74 | 87 | api_key = <auth token goes here> |
|
75 | repo_dir = /home/<username>/repos | |
|
88 | ||
|
76 | 89 | |
|
77 | 90 | .. _run-index: |
|
78 | 91 | |
|
79 | 92 | Run the Indexer |
|
80 | 93 | ^^^^^^^^^^^^^^^ |
|
81 | 94 | |
|
82 | Run the indexer using the following command, and specify the instance you | |
|
83 | want to index: | |
|
95 | Run the indexer using the following command, and specify the instance you want to index: | |
|
84 | 96 | |
|
85 | 97 | .. code-block:: bash |
|
86 | 98 | |
|
87 | # From inside a virtualevv | |
|
88 | (venv)$ rhodecode-index --instance-name=enterprise-1 | |
|
89 | ||
|
90 | # Using default installation | |
|
99 | # Using default simples indexing of all repositories | |
|
91 | 100 | $ /home/user/.rccontrol/enterprise-1/profile/bin/rhodecode-index \ |
|
92 | 101 | --instance-name=enterprise-1 |
|
93 | 102 | |
|
94 | # Using a custom mapping file | |
|
103 | # Using a custom mapping file with indexing rules, and using elasticsearch 6 backend | |
|
95 | 104 | $ /home/user/.rccontrol/enterprise-1/profile/bin/rhodecode-index \ |
|
96 | 105 | --instance-name=enterprise-1 \ |
|
97 | --mapping=/home/user/.rccontrol/enterprise-1/mapping.ini | |
|
106 | --mapping=/home/user/.rccontrol/enterprise-1/search_mapping.ini \ | |
|
107 | --es-version=6 --engine-location=http://elasticsearch-host:9200 | |
|
108 | ||
|
109 | # Using a custom mapping file and invocation without ``.rhoderc`` | |
|
110 | $ /home/user/.rccontrol/enterprise-1/profile/bin/rhodecode-index \ | |
|
111 | --api-host=http://rhodecodecode.myserver.com --api-key=xxxxx \ | |
|
112 | --mapping=/home/user/.rccontrol/enterprise-1/search_mapping.ini | |
|
113 | ||
|
114 | # From inside a virtualev on your local machine or CI server. | |
|
115 | (venv)$ rhodecode-index --instance-name=enterprise-1 | |
|
116 | ||
|
98 | 117 | |
|
99 | 118 | .. note:: |
|
100 | 119 | |
@@ -136,119 +155,173 b' 3. Save the file.' | |||
|
136 | 155 | # using a specially configured mapping file |
|
137 | 156 | */15 * * * * ~/.rccontrol/enterprise-4/profile/bin/rhodecode-index \ |
|
138 | 157 | --instance-name=enterprise-4 \ |
|
139 | --mapping=/home/user/.rccontrol/enterprise-4/mapping.ini | |
|
158 | --mapping=/home/user/.rccontrol/enterprise-4/search_mapping.ini | |
|
140 | 159 | |
|
141 | 160 | .. _advanced-indexing: |
|
142 | 161 | |
|
143 | 162 | Advanced Indexing |
|
144 | 163 | ^^^^^^^^^^^^^^^^^ |
|
145 | 164 | |
|
146 | |RCT| indexes based on the :file:`mapping.ini` file. To configure your index, | |
|
147 | you can specify different options in this file. The default location is: | |
|
165 | ||
|
166 | Force Re-Indexing single repository | |
|
167 | +++++++++++++++++++++++++++++++++++ | |
|
168 | ||
|
169 | Often it's required to re-index whole repository because of some repository changes, | |
|
170 | or to remove some indexed secrets, or files. There's a special `--repo-name=` flag | |
|
171 | for the indexer that limits execution to a single repository. For example to force-reindex | |
|
172 | single repository such call can be made:: | |
|
173 | ||
|
174 | rhodecode-index --instance-name=enterprise-1 --force --repo-name=rhodecode-vcsserver | |
|
175 | ||
|
176 | ||
|
177 | Removing repositories from index | |
|
178 | ++++++++++++++++++++++++++++++++ | |
|
148 | 179 | |
|
149 | * :file:`/home/{user}/.rccontrol/{instance-id}/mapping.ini`, using default | |
|
150 | |RCT|. | |
|
180 | The indexer automatically removes renamed repositories and builds index for new names. | |
|
181 | In the same way if a listed repository in mapping.ini is not reported existing by the | |
|
182 | server it's removed from the index. | |
|
183 | In case that you wish to remove indexed repository manually such call would allow that:: | |
|
184 | ||
|
185 | rhodecode-index --instance-name=enterprise-1 --remove-only --repo-name=rhodecode-vcsserver | |
|
186 | ||
|
187 | ||
|
188 | Using search_mapping.ini file for advanced index rules | |
|
189 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
|
190 | ||
|
191 | By default rhodecode-index runs for all repositories, all files with parsing limits | |
|
192 | defined by the CLI default arguments. You can change those limits by calling with | |
|
193 | different flags such as `--max-filesize=2048kb` or `--repo-limit=10` | |
|
194 | ||
|
195 | For more advanced execution logic it's possible to use a configuration file that | |
|
196 | would define detailed rules which repositories and how should be indexed. | |
|
197 | ||
|
198 | |RCT| provides an example index configuration file called :file:`search_mapping.ini`. | |
|
199 | This file is created by default during installation and is located at: | |
|
200 | ||
|
201 | * :file:`/home/{user}/.rccontrol/{instance-id}/search_mapping.ini`, using default |RCT|. | |
|
151 | 202 | * :file:`~/venv/lib/python2.7/site-packages/rhodecode_tools/templates/mapping.ini`, |
|
152 | 203 | when using ``virtualenv``. |
|
153 | 204 | |
|
154 | 205 | .. note:: |
|
155 | 206 | |
|
156 | If you need to create the :file:`mapping.ini` file, use the |RCT| | |
|
157 |
``rhodecode-index --create-mapping path/to/ |
|
|
158 | see the :ref:`tools-cli` section. | |
|
159 | ||
|
160 | The indexer runs in a random order to prevent a failing |repo| from stopping | |
|
161 | a build. To configure different indexing scenarios, set the following options | |
|
162 | inside the :file:`mapping.ini` and specify the altered file using the | |
|
163 | ``--mapping`` option. | |
|
207 | If you need to create the :file:`search_mapping.ini` file manually, use the |RCT| | |
|
208 | ``rhodecode-index --create-mapping path/to/search_mapping.ini`` API call. | |
|
209 | For details, see the :ref:`tools-cli` section. | |
|
164 | 210 | |
|
165 | * ``index_files`` : Index the specified file types. | |
|
166 | * ``skip_files`` : Do not index the specified file types. | |
|
167 | * ``index_files_content`` : Index the content of the specified file types. | |
|
168 | * ``skip_files_content`` : Do not index the content of the specified files. | |
|
169 | * ``force`` : Create a fresh index on each run. | |
|
170 | * ``max_filesize`` : Files larger than the set size will not be indexed. | |
|
171 | * ``commit_parse_limit`` : Set the batch size when indexing commit messages. | |
|
172 | Set to a lower number to lessen memory load. | |
|
173 | * ``repo_limit`` : Set the maximum number or |repos| indexed per run. | |
|
174 | * ``[INCLUDE]`` : Set |repos| you want indexed. This takes precedent over | |
|
175 | ``[EXCLUDE]``. | |
|
176 | * ``[EXCLUDE]`` : Set |repos| you do not want indexed. Exclude can be used to | |
|
177 | not index branches, forks, or log |repos|. | |
|
211 | To Run the indexer with mapping file provide it using `--mapping` flag:: | |
|
178 | 212 |
|
|
179 | At the end of the file you can specify conditions for specific |repos| that | |
|
180 | will override the default values. To configure your indexer, | |
|
181 | use the following example :file:`mapping.ini` file. | |
|
213 | rhodecode-index --instance-name=enterprise-1 --mapping=/my/path/search_mapping.ini | |
|
214 | ||
|
215 | ||
|
216 | Here's a detailed example of using :file:`search_mapping.ini` file. | |
|
182 | 217 | |
|
183 | 218 | .. code-block:: ini |
|
184 | 219 | |
|
185 | 220 | [__DEFAULT__] |
|
186 | # default patterns for indexing files and content of files. | |
|
187 | # Binary files are skipped by default. | |
|
221 | ; Create index on commits data, and files data in this order. Available options | |
|
222 | ; are `commits`, `files` | |
|
223 | index_types = commits,files | |
|
224 | ||
|
225 | ; Commit fetch limit. In what amount of chunks commits should be fetched | |
|
226 | ; via api and parsed. This allows server to transfer smaller chunks and be less loaded | |
|
227 | commit_fetch_limit = 1000 | |
|
188 | 228 | |
|
189 | # Index python and markdown files | |
|
190 | index_files = *.py, *.md | |
|
229 | ; Commit process limit. Limit the number of commits indexer should fetch, and | |
|
230 | ; store inside the full text search index. eg. if repo has 2000 commits, and | |
|
231 | ; limit is 1000, on the first run it will process commits 0-1000 and on the | |
|
232 | ; second 1000-2000 commits. Help reduce memory usage, default is 50000 | |
|
233 | ; (set -1 for unlimited) | |
|
234 | commit_process_limit = 20000 | |
|
191 | 235 | |
|
192 | # Do not index these file types | |
|
193 | skip_files = *.svg, *.log, *.dump, *.txt | |
|
236 | ; Limit of how many repositories each run can process, default is -1 (unlimited) | |
|
237 | ; in case of 1000s of repositories it's better to execute in chunks to not overload | |
|
238 | ; the server. | |
|
239 | repo_limit = -1 | |
|
194 | 240 | |
|
195 | # Index both file types and their content | |
|
196 | index_files_content = *.cpp, *.ini, *.py | |
|
241 | ; Default patterns for indexing files and content of files. Binary files | |
|
242 | ; are skipped by default. | |
|
243 | ||
|
244 | ; Add to index those comma separated files; globs syntax | |
|
245 | ; e.g index_files = *.py, *.c, *.h, *.js | |
|
246 | index_files = *, | |
|
247 | ||
|
248 | ; Do not add to index those comma separated files, this excludes | |
|
249 | ; both search by name and content; globs syntax | |
|
250 | ; e.g index_files = *.key, *.sql, *.xml, *.pem, *.crt | |
|
251 | skip_files = , | |
|
197 | 252 | |
|
198 | # Index file names, but not file content | |
|
199 | skip_files_content = *.svg, | |
|
253 | ; Add to index content of those comma separated files; globs syntax | |
|
254 | ; e.g index_files = *.h, *.obj | |
|
255 | index_files_content = *, | |
|
200 | 256 | |
|
201 | # Force rebuilding an index from scratch. Each repository will be rebuild | |
|
202 | # from scratch with a global flag. Use local flag to rebuild single repos | |
|
257 | ; Do not add to index content of those comma separated files; globs syntax | |
|
258 | ; Binary files are not indexed by default. | |
|
259 | ; e.g index_files = *.min.js, *.xml, *.dump, *.log, *.dump | |
|
260 | skip_files_content = , | |
|
261 | ||
|
262 | ; Force rebuilding an index from scratch. Each repository will be rebuild from | |
|
263 | ; scratch with a global flag. Use --repo-name=NAME --force to rebuild single repo | |
|
203 | 264 | force = false |
|
204 | 265 | |
|
205 | # Do not index files larger than 385KB | |
|
206 | max_filesize = 385KB | |
|
266 | ; maximum file size that indexer will use, files above that limit are not going | |
|
267 | ; to have they content indexed. | |
|
268 | ; Possible options are KB (kilobytes), MB (megabytes), eg 1MB or 1024KB | |
|
269 | max_filesize = 10MB | |
|
207 | 270 | |
|
208 | # Limit commit indexing to 500 per batch | |
|
209 | commit_parse_limit = 500 | |
|
210 | ||
|
211 | # Limit each index run to 25 repos | |
|
212 | repo_limit = 25 | |
|
213 | 271 | |
|
214 | # __INCLUDE__ is more important that __EXCLUDE__. | |
|
215 | ||
|
216 | [__INCLUDE__] | |
|
217 | # Include all repos with these names | |
|
272 | [__INDEX_RULES__] | |
|
273 | ; Ordered match rules for repositories. A list of all repositories will be fetched | |
|
274 | ; using API and this list will be filtered using those rules. | |
|
275 | ; Syntax for entry: `glob_pattern_OR_full_repo_name = 0 OR 1` where 0=exclude, 1=include | |
|
276 | ; When this ordered list is traversed first match will return the include/exclude marker | |
|
277 | ; For example: | |
|
278 | ; upstream/binary_repo = 0 | |
|
279 | ; upstream/subrepo/xml_files = 0 | |
|
280 | ; upstream/* = 1 | |
|
281 | ; special-repo = 1 | |
|
282 | ; * = 0 | |
|
283 | ; This will index all repositories under upstream/*, but skip upstream/binary_repo | |
|
284 | ; and upstream/sub_repo/xml_files, last * = 0 means skip all other matches | |
|
218 | 285 | |
|
219 | docs/* = 1 | |
|
220 | lib/* = 1 | |
|
221 | ||
|
222 | [__EXCLUDE__] | |
|
223 | # Do not include the following repo in index | |
|
224 | 286 | |
|
225 | dev-docs/* = 1 | |
|
226 | legacy-repos/* = 1 | |
|
227 | *-dev/* = 1 | |
|
228 | ||
|
229 | # Each repo that needs special indexing is a separate section below. | |
|
230 | # In each section set the options to override the global configuration | |
|
231 | # parameters above. | |
|
232 | # If special settings are not configured, the global configuration values | |
|
233 | # above are inherited. If no special repositories are | |
|
234 | # defined here RhodeCode will use the API to ask for all repositories | |
|
287 | ; == EXPLICIT REPOSITORY INDEXING == | |
|
288 | ; If defined this will skip using __INDEX_RULES__, and will not use API to fetch | |
|
289 | ; list of repositories, it will explicitly take names defined with [NAME] format and | |
|
290 | ; try to build the index, to build index just for repo_name_1 and special-repo use: | |
|
291 | ; [repo_name_1] | |
|
292 | ; [special-repo] | |
|
235 | 293 | |
|
236 | # For this repo use different settings | |
|
237 | [special-repo] | |
|
238 | commit_parse_limit = 20, | |
|
239 | skip_files = *.idea, *.xml, | |
|
294 | ; == PER REPOSITORY CONFIGURATION == | |
|
295 | ; This allows overriding the global configuration per repository. | |
|
296 | ; example to set specific file limit, and skip certain files for repository special-repo | |
|
297 | ; the CLI flags doesn't override the conf settings. | |
|
298 | ; [conf:special-repo] | |
|
299 | ; max_filesize = 5mb | |
|
300 | ; skip_files = *.xml, *.sql | |
|
301 | ||
|
240 | 302 | |
|
241 | # For another repo use different settings | |
|
242 | [another-special-repo] | |
|
243 | index_files = *, | |
|
244 | max_filesize = 800MB | |
|
245 | commit_parse_limit = 20000 | |
|
303 | ||
|
304 | In case of 1000s of repositories it can be tricky to write the include/exclude rules at first. | |
|
305 | There's a special flag to test the mapping file rules and list repositories that would | |
|
306 | be indexed. Run the indexer with `--show-matched-repos` to list only the | |
|
307 | match repositories defined in .ini file rules:: | |
|
308 | ||
|
309 | rhodecode-index --instance-name=enterprise-1 --show-matched-repos --mapping=/my/path/search_mapping.ini | |
|
310 | ||
|
246 | 311 | |
|
247 | 312 | .. _enable-elasticsearch: |
|
248 | 313 | |
|
249 |
Enabling Elastic |
|
|
314 | Enabling ElasticSearch | |
|
250 | 315 | ^^^^^^^^^^^^^^^^^^^^^^ |
|
251 | 316 | |
|
317 | ElasticSearch is available in EE edition only. It provides much scalable and more advanced | |
|
318 | search capabilities. While Whoosh is fine for upto 1-2GB of data, beyond that amount it | |
|
319 | starts slowing down, and can cause other problems. | |
|
320 | New ElasticSearch 6 also provides much more advanced query language. | |
|
321 | It allows advanced filtering by file paths, extensions, use OR statements, ranges etc. | |
|
322 | Please check query language examples in the search field for some advanced query language usage. | |
|
323 | ||
|
324 | ||
|
252 | 325 | 1. Open the :file:`rhodecode.ini` file for the instance you wish to edit. The |
|
253 | 326 | default location is |
|
254 | 327 | :file:`home/{user}/.rccontrol/{instance-id}/rhodecode.ini` |
@@ -268,9 +341,19 b' and change it to:' | |||
|
268 | 341 | .. code-block:: ini |
|
269 | 342 | |
|
270 | 343 | search.module = rc_elasticsearch |
|
271 |
search.location = http://localhost:9200 |
|
|
344 | search.location = http://localhost:9200 | |
|
345 | ## specify Elastic Search version, 6 for latest or 2 for legacy | |
|
346 | search.es_version = 6 | |
|
347 | ||
|
348 | where ``search.location`` points to the ElasticSearch server | |
|
349 | by default running on port 9200. | |
|
272 | 350 | |
|
273 | where ``search.location`` points to the elasticsearch server. | |
|
351 | Index invocation also needs change. Please provide --es-version= and | |
|
352 | --engine-location= parameters to define ElasticSearch server location and it's version. | |
|
353 | For example:: | |
|
354 | ||
|
355 | rhodecode-index --instace-name=enterprise-1 --es-version=6 --engine-location=http://localhost:9200 | |
|
356 | ||
|
274 | 357 |
|
|
275 | 358 | .. _Whoosh: https://pypi.python.org/pypi/Whoosh/ |
|
276 |
.. _Elastic |
|
|
359 | .. _ElasticSearch 6: https://www.elastic.co/ |
@@ -9,6 +9,9 b' Use the following example to configure N' | |||
|
9 | 9 | ## Rate limiter for certain pages to prevent brute force attacks |
|
10 | 10 | limit_req_zone $binary_remote_addr zone=req_limit:10m rate=1r/s; |
|
11 | 11 | |
|
12 | ## cache zone | |
|
13 | proxy_cache_path /etc/nginx/nginx_cache levels=1:2 use_temp_path=off keys_zone=cache_zone:10m inactive=720h max_size=10g; | |
|
14 | ||
|
12 | 15 | ## Custom log format |
|
13 | 16 | log_format log_custom '$remote_addr - $remote_user [$time_local] ' |
|
14 | 17 | '"$request" $status $body_bytes_sent ' |
@@ -141,6 +144,34 b' Use the following example to configure N' | |||
|
141 | 144 | try_files $uri @rhodecode_http; |
|
142 | 145 | } |
|
143 | 146 | |
|
147 | ## Special Cache for file store, make sure you enable this intentionally as | |
|
148 | ## it could bypass upload files permissions | |
|
149 | # location /_file_store/download { | |
|
150 | # | |
|
151 | # proxy_cache cache_zone; | |
|
152 | # # ignore Set-Cookie | |
|
153 | # proxy_ignore_headers Set-Cookie; | |
|
154 | # proxy_ignore_headers Cookie; | |
|
155 | # | |
|
156 | # proxy_cache_key $host$uri$is_args$args; | |
|
157 | # proxy_cache_methods GET; | |
|
158 | # | |
|
159 | # proxy_cache_bypass $http_cache_control; | |
|
160 | # proxy_cache_valid 200 302 720h; | |
|
161 | # | |
|
162 | # proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; | |
|
163 | # | |
|
164 | # # returns cache status in headers | |
|
165 | # add_header X-Proxy-Cache $upstream_cache_status; | |
|
166 | # add_header Cache-Control "public"; | |
|
167 | # | |
|
168 | # proxy_cache_lock on; | |
|
169 | # proxy_cache_lock_age 5m; | |
|
170 | # | |
|
171 | # proxy_pass http://rc; | |
|
172 | # | |
|
173 | # } | |
|
174 | ||
|
144 | 175 | location / { |
|
145 | 176 | try_files $uri @rhodecode_http; |
|
146 | 177 | } |
@@ -35,7 +35,7 b' 2. On the |repo| group settings page you' | |||
|
35 | 35 | |
|
36 | 36 | * :guilabel:`Owner`: Lets you change the group owner. Useful when users are |
|
37 | 37 | moving roles within an organisation. |
|
38 |
* :guilabel:` |
|
|
38 | * :guilabel:`Repository group`: Lets you add the |repo| group as a sub-group | |
|
39 | 39 | of a larger group, i.e. :guilabel:`QA-Repos >> QA-Repos-Berlin` |
|
40 | 40 | * :guilabel:`Enable automatic locking`: For more information, |
|
41 | 41 | see :ref:`repo-locking` |
@@ -30,3 +30,5 b' The following are the most common system' | |||
|
30 | 30 | enable-debug |
|
31 | 31 | admin-tricks |
|
32 | 32 | cleanup-cmds |
|
33 | restore-deleted-repositories | |
|
34 |
@@ -78,7 +78,7 b' Configuration Files' | |||
|
78 | 78 | ------------------- |
|
79 | 79 | |
|
80 | 80 | * :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` |
|
81 | * :file:`/home/{user}/.rccontrol/{instance-id}/mapping.ini` | |
|
81 | * :file:`/home/{user}/.rccontrol/{instance-id}/search_mapping.ini` | |
|
82 | 82 | * :file:`/home/{user}/.rccontrol/{vcsserver-id}/vcsserver.ini` |
|
83 | 83 | * :file:`/home/{user}/.rccontrol/supervisor/supervisord.ini` |
|
84 | 84 | * :file:`/home/{user}/.rccontrol.ini` |
@@ -196,7 +196,8 b' are not required in args.' | |||
|
196 | 196 | .. --- API DEFS MARKER --- |
|
197 | 197 | .. toctree:: |
|
198 | 198 | |
|
199 |
methods/ |
|
|
199 | methods/repo-methods | |
|
200 | methods/store-methods | |
|
200 | 201 | methods/license-methods |
|
201 | 202 | methods/deprecated-methods |
|
202 | 203 | methods/gist-methods |
@@ -83,7 +83,7 b' comment_pull_request' | |||
|
83 | 83 | create_pull_request |
|
84 | 84 | ------------------- |
|
85 | 85 | |
|
86 | .. py:function:: create_pull_request(apiuser, source_repo, target_repo, source_ref, target_ref, title=<Optional:''>, description=<Optional:''>, description_renderer=<Optional:''>, reviewers=<Optional:None>) | |
|
86 | .. py:function:: create_pull_request(apiuser, source_repo, target_repo, source_ref, target_ref, owner=<Optional:<OptionalAttr:apiuser>>, title=<Optional:''>, description=<Optional:''>, description_renderer=<Optional:''>, reviewers=<Optional:None>) | |
|
87 | 87 | |
|
88 | 88 | Creates a new pull request. |
|
89 | 89 | |
@@ -104,6 +104,8 b' create_pull_request' | |||
|
104 | 104 | :type source_ref: str |
|
105 | 105 | :param target_ref: Set the target ref name. |
|
106 | 106 | :type target_ref: str |
|
107 | :param owner: user_id or username | |
|
108 | :type owner: Optional(str) | |
|
107 | 109 | :param title: Optionally Set the pull request title, it's generated otherwise |
|
108 | 110 | :type title: str |
|
109 | 111 | :param description: Set the pull request description. |
@@ -248,7 +250,7 b' get_pull_request_comments' | |||
|
248 | 250 | get_pull_requests |
|
249 | 251 | ----------------- |
|
250 | 252 | |
|
251 | .. py:function:: get_pull_requests(apiuser, repoid, status=<Optional:'new'>) | |
|
253 | .. py:function:: get_pull_requests(apiuser, repoid, status=<Optional:'new'>, merge_state=<Optional:True>) | |
|
252 | 254 | |
|
253 | 255 | Get all pull requests from the repository specified in `repoid`. |
|
254 | 256 | |
@@ -262,6 +264,9 b' get_pull_requests' | |||
|
262 | 264 | * ``open`` |
|
263 | 265 | * ``closed`` |
|
264 | 266 | :type status: str |
|
267 | :param merge_state: Optional calculate merge state for each repository. | |
|
268 | This could result in longer time to fetch the data | |
|
269 | :type merge_state: bool | |
|
265 | 270 | |
|
266 | 271 | Example output: |
|
267 | 272 | |
@@ -356,10 +361,11 b' merge_pull_request' | |||
|
356 | 361 | |
|
357 | 362 | "id": <id_given_in_input>, |
|
358 | 363 | "result": { |
|
359 | "executed": "<bool>", | |
|
360 | "failure_reason": "<int>", | |
|
361 |
"merge_ |
|
|
362 |
" |
|
|
364 | "executed": "<bool>", | |
|
365 | "failure_reason": "<int>", | |
|
366 | "merge_status_message": "<str>", | |
|
367 | "merge_commit_id": "<merge_commit_id>", | |
|
368 | "possible": "<bool>", | |
|
363 | 369 | "merge_ref": { |
|
364 | 370 | "commit_id": "<commit_id>", |
|
365 | 371 | "type": "<type>", |
@@ -394,15 +394,54 b' get_repo_changesets' | |||
|
394 | 394 | of changed files. |
|
395 | 395 | |
|
396 | 396 | |
|
397 |
get_repo_ |
|
|
398 | -------------- | |
|
397 | get_repo_comments | |
|
398 | ----------------- | |
|
399 | ||
|
400 | .. py:function:: get_repo_comments(apiuser, repoid, commit_id=<Optional:None>, comment_type=<Optional:None>, userid=<Optional:None>) | |
|
401 | ||
|
402 | Get all comments for a repository | |
|
399 | 403 | |
|
400 | .. py:function:: get_repo_nodes(apiuser, repoid, revision, root_path, ret_type=<Optional:'all'>, details=<Optional:'basic'>, max_file_bytes=<Optional:None>) | |
|
404 | :param apiuser: This is filled automatically from the |authtoken|. | |
|
405 | :type apiuser: AuthUser | |
|
406 | :param repoid: Set the repository name or repository ID. | |
|
407 | :type repoid: str or int | |
|
408 | :param commit_id: Optionally filter the comments by the commit_id | |
|
409 | :type commit_id: Optional(str), default: None | |
|
410 | :param comment_type: Optionally filter the comments by the comment_type | |
|
411 | one of: 'note', 'todo' | |
|
412 | :type comment_type: Optional(str), default: None | |
|
413 | :param userid: Optionally filter the comments by the author of comment | |
|
414 | :type userid: Optional(str or int), Default: None | |
|
415 | ||
|
416 | Example error output: | |
|
417 | ||
|
418 | .. code-block:: bash | |
|
401 | 419 |
|
|
402 | Returns a list of nodes and children in a flat list for a given | |
|
403 | path at given revision. | |
|
420 | { | |
|
421 | "id" : <id_given_in_input>, | |
|
422 | "result" : [ | |
|
423 | { | |
|
424 | "comment_author": <USER_DETAILS>, | |
|
425 | "comment_created_on": "2017-02-01T14:38:16.309", | |
|
426 | "comment_f_path": "file.txt", | |
|
427 | "comment_id": 282, | |
|
428 | "comment_lineno": "n1", | |
|
429 | "comment_resolved_by": null, | |
|
430 | "comment_status": [], | |
|
431 | "comment_text": "This file needs a header", | |
|
432 | "comment_type": "todo" | |
|
433 | } | |
|
434 | ], | |
|
435 | "error" : null | |
|
436 | } | |
|
404 | 437 |
|
|
405 | It's possible to specify ret_type to show only `files` or `dirs`. | |
|
438 | ||
|
439 | get_repo_file | |
|
440 | ------------- | |
|
441 | ||
|
442 | .. py:function:: get_repo_file(apiuser, repoid, commit_id, file_path, max_file_bytes=<Optional:None>, details=<Optional:'basic'>, cache=<Optional:True>) | |
|
443 | ||
|
444 | Returns a single file from repository at given revision. | |
|
406 | 445 | |
|
407 | 446 | This command can only be run using an |authtoken| with admin rights, |
|
408 | 447 | or users with at least read rights to |repos|. |
@@ -411,37 +450,104 b' get_repo_nodes' | |||
|
411 | 450 | :type apiuser: AuthUser |
|
412 | 451 | :param repoid: The repository name or repository ID. |
|
413 | 452 | :type repoid: str or int |
|
414 |
:param |
|
|
415 |
:type |
|
|
416 |
:param |
|
|
417 |
:type |
|
|
418 | :param ret_type: Set the return type. Valid options are | |
|
419 | ``all`` (default), ``files`` and ``dirs``. | |
|
420 | :type ret_type: Optional(str) | |
|
421 | :param details: Returns extended information about nodes, such as | |
|
422 | md5, binary, and or content. The valid options are ``basic`` and | |
|
423 | ``full``. | |
|
453 | :param commit_id: The revision for which listing should be done. | |
|
454 | :type commit_id: str | |
|
455 | :param file_path: The path from which to start displaying. | |
|
456 | :type file_path: str | |
|
457 | :param details: Returns different set of information about nodes. | |
|
458 | The valid options are ``minimal`` ``basic`` and ``full``. | |
|
424 | 459 | :type details: Optional(str) |
|
425 | 460 | :param max_file_bytes: Only return file content under this file size bytes |
|
426 |
:type |
|
|
427 | ||
|
461 | :type max_file_bytes: Optional(int) | |
|
462 | :param cache: Use internal caches for fetching files. If disabled fetching | |
|
463 | files is slower but more memory efficient | |
|
464 | :type cache: Optional(bool) | |
|
428 | 465 | Example output: |
|
429 | 466 | |
|
430 | 467 | .. code-block:: bash |
|
431 | 468 | |
|
432 | 469 | id : <id_given_in_input> |
|
433 |
result: |
|
|
434 | { | |
|
435 | "name" : "<name>" | |
|
436 | "type" : "<type>", | |
|
437 | "binary": "<true|false>" (only in extended mode) | |
|
438 | "md5" : "<md5 of file content>" (only in extended mode) | |
|
439 | }, | |
|
440 | ... | |
|
441 |
|
|
|
470 | result: { | |
|
471 | "binary": false, | |
|
472 | "extension": "py", | |
|
473 | "lines": 35, | |
|
474 | "content": "....", | |
|
475 | "md5": "76318336366b0f17ee249e11b0c99c41", | |
|
476 | "mimetype": "text/x-python", | |
|
477 | "name": "python.py", | |
|
478 | "size": 817, | |
|
479 | "type": "file", | |
|
480 | } | |
|
442 | 481 | error: null |
|
443 | 482 | |
|
444 | 483 | |
|
484 | get_repo_fts_tree | |
|
485 | ----------------- | |
|
486 | ||
|
487 | .. py:function:: get_repo_fts_tree(apiuser, repoid, commit_id, root_path) | |
|
488 | ||
|
489 | Returns a list of tree nodes for path at given revision. This api is built | |
|
490 | strictly for usage in full text search building, and shouldn't be consumed | |
|
491 | ||
|
492 | This command can only be run using an |authtoken| with admin rights, | |
|
493 | or users with at least read rights to |repos|. | |
|
494 | ||
|
495 | ||
|
496 | get_repo_nodes | |
|
497 | -------------- | |
|
498 | ||
|
499 | .. py:function:: get_repo_nodes(apiuser, repoid, revision, root_path, ret_type=<Optional:'all'>, details=<Optional:'basic'>, max_file_bytes=<Optional:None>) | |
|
500 | ||
|
501 | Returns a list of nodes and children in a flat list for a given | |
|
502 | path at given revision. | |
|
503 | ||
|
504 | It's possible to specify ret_type to show only `files` or `dirs`. | |
|
505 | ||
|
506 | This command can only be run using an |authtoken| with admin rights, | |
|
507 | or users with at least read rights to |repos|. | |
|
508 | ||
|
509 | :param apiuser: This is filled automatically from the |authtoken|. | |
|
510 | :type apiuser: AuthUser | |
|
511 | :param repoid: The repository name or repository ID. | |
|
512 | :type repoid: str or int | |
|
513 | :param revision: The revision for which listing should be done. | |
|
514 | :type revision: str | |
|
515 | :param root_path: The path from which to start displaying. | |
|
516 | :type root_path: str | |
|
517 | :param ret_type: Set the return type. Valid options are | |
|
518 | ``all`` (default), ``files`` and ``dirs``. | |
|
519 | :type ret_type: Optional(str) | |
|
520 | :param details: Returns extended information about nodes, such as | |
|
521 | md5, binary, and or content. | |
|
522 | The valid options are ``basic`` and ``full``. | |
|
523 | :type details: Optional(str) | |
|
524 | :param max_file_bytes: Only return file content under this file size bytes | |
|
525 | :type details: Optional(int) | |
|
526 | ||
|
527 | Example output: | |
|
528 | ||
|
529 | .. code-block:: bash | |
|
530 | ||
|
531 | id : <id_given_in_input> | |
|
532 | result: [ | |
|
533 | { | |
|
534 | "binary": false, | |
|
535 | "content": "File line | |
|
536 | Line2 | |
|
537 | ", | |
|
538 | "extension": "md", | |
|
539 | "lines": 2, | |
|
540 | "md5": "059fa5d29b19c0657e384749480f6422", | |
|
541 | "mimetype": "text/x-minidsrc", | |
|
542 | "name": "file.md", | |
|
543 | "size": 580, | |
|
544 | "type": "file" | |
|
545 | }, | |
|
546 | ... | |
|
547 | ] | |
|
548 | error: null | |
|
549 | ||
|
550 | ||
|
445 | 551 | get_repo_refs |
|
446 | 552 | ------------- |
|
447 | 553 |
@@ -103,7 +103,7 b' get_method' | |||
|
103 | 103 | :param apiuser: This is filled automatically from the |authtoken|. |
|
104 | 104 | :type apiuser: AuthUser |
|
105 | 105 | :param pattern: pattern to match method names against |
|
106 |
:type |
|
|
106 | :type pattern: Optional("*") | |
|
107 | 107 | |
|
108 | 108 | Example output: |
|
109 | 109 | |
@@ -232,3 +232,37 b' rescan_repos' | |||
|
232 | 232 | } |
|
233 | 233 | |
|
234 | 234 | |
|
235 | store_exception | |
|
236 | --------------- | |
|
237 | ||
|
238 | .. py:function:: store_exception(apiuser, exc_data_json, prefix=<Optional:'rhodecode'>) | |
|
239 | ||
|
240 | Stores sent exception inside the built-in exception tracker in |RCE| server. | |
|
241 | ||
|
242 | This command can only be run using an |authtoken| with admin rights to | |
|
243 | the specified repository. | |
|
244 | ||
|
245 | This command takes the following options: | |
|
246 | ||
|
247 | :param apiuser: This is filled automatically from the |authtoken|. | |
|
248 | :type apiuser: AuthUser | |
|
249 | ||
|
250 | :param exc_data_json: JSON data with exception e.g | |
|
251 | {"exc_traceback": "Value `1` is not allowed", "exc_type_name": "ValueError"} | |
|
252 | :type exc_data_json: JSON data | |
|
253 | ||
|
254 | :param prefix: prefix for error type, e.g 'rhodecode', 'vcsserver', 'rhodecode-tools' | |
|
255 | :type prefix: Optional("rhodecode") | |
|
256 | ||
|
257 | Example output: | |
|
258 | ||
|
259 | .. code-block:: bash | |
|
260 | ||
|
261 | id : <id_given_in_input> | |
|
262 | "result": { | |
|
263 | "exc_id": 139718459226384, | |
|
264 | "exc_url": "http://localhost:8080/_admin/settings/exceptions/139718459226384" | |
|
265 | } | |
|
266 | error : null | |
|
267 | ||
|
268 |
@@ -15,4 +15,5 b' Please check for reference two example p' | |||
|
15 | 15 | |
|
16 | 16 | auth-saml-duosecurity |
|
17 | 17 | auth-saml-onelogin |
|
18 | auth-saml-bulk-enroll-users | |
|
18 | 19 |
@@ -73,6 +73,10 b' 2. Enable the SSH module on instance.' | |||
|
73 | 73 | ssh.executable.git = ~/.rccontrol/vcsserver-1/profile/bin/git |
|
74 | 74 | ssh.executable.svn = ~/.rccontrol/vcsserver-1/profile/bin/svnserve |
|
75 | 75 | |
|
76 | ## Enables SSH key generator web interface. Disabling this still allows users | |
|
77 | ## to add their own keys. | |
|
78 | ssh.enable_ui_key_generator = true | |
|
79 | ||
|
76 | 80 | |
|
77 | 81 | 3. Set base_url for instance to enable proper event handling (Optional): |
|
78 | 82 |
@@ -52,6 +52,7 b' run::' | |||
|
52 | 52 | Followed by:: |
|
53 | 53 | |
|
54 | 54 | nix-channel --update |
|
55 | nix-env -i nix-2.0.4 | |
|
55 | 56 |
|
|
56 | 57 | |
|
57 | 58 | Install required binaries |
@@ -65,6 +66,18 b' run::' | |||
|
65 | 66 | nix-env -i nix-prefetch-git |
|
66 | 67 | |
|
67 | 68 | |
|
69 | Speed up JS build by installing PhantomJS | |
|
70 | ----------------------------------------- | |
|
71 | ||
|
72 | PhantomJS will be downloaded each time nix-shell is invoked. To speed this by | |
|
73 | setting already downloaded version do this:: | |
|
74 | ||
|
75 | nix-env -i phantomjs-2.1.1 | |
|
76 | ||
|
77 | # and set nix bin path | |
|
78 | export PATH=$PATH:~/.nix-profile/bin | |
|
79 | ||
|
80 | ||
|
68 | 81 | Clone the required repositories |
|
69 | 82 | ------------------------------- |
|
70 | 83 | |
@@ -76,8 +89,8 b' you have it installed before continuing.' | |||
|
76 | 89 | To obtain the required sources, use the following commands:: |
|
77 | 90 | |
|
78 | 91 | mkdir rhodecode-develop && cd rhodecode-develop |
|
79 | hg clone https://code.rhodecode.com/rhodecode-enterprise-ce | |
|
80 | hg clone https://code.rhodecode.com/rhodecode-vcsserver | |
|
92 | hg clone -u default https://code.rhodecode.com/rhodecode-enterprise-ce | |
|
93 | hg clone -u default https://code.rhodecode.com/rhodecode-vcsserver | |
|
81 | 94 | |
|
82 | 95 | .. note:: |
|
83 | 96 | |
@@ -93,11 +106,15 b' need to install the following.' | |||
|
93 | 106 | |
|
94 | 107 | required libraries:: |
|
95 | 108 | |
|
109 | # svn related | |
|
96 | 110 | sudo apt-get install libapr1-dev libaprutil1-dev |
|
97 | 111 |
|
|
112 | # libcurl required too | |
|
113 | sudo apt-get install libcurl4-openssl-dev | |
|
114 | # mysql/pg server for development, optional | |
|
98 | 115 | sudo apt-get install mysql-server libmysqlclient-dev |
|
99 | 116 | sudo apt-get install postgresql postgresql-contrib libpq-dev |
|
100 | sudo apt-get install libcurl4-openssl-dev | |
|
117 | ||
|
101 | 118 | |
|
102 | 119 | |
|
103 | 120 | Enter the Development Shell |
@@ -106,7 +123,7 b' Enter the Development Shell' | |||
|
106 | 123 | The final step is to start the development shells. To do this, run the |
|
107 | 124 | following command from inside the cloned repository:: |
|
108 | 125 | |
|
109 | #first, the vcsserver | |
|
126 | # first, the vcsserver | |
|
110 | 127 | cd ~/rhodecode-vcsserver |
|
111 | 128 | nix-shell |
|
112 | 129 | |
@@ -182,7 +199,7 b" To use the application's frontend and pr" | |||
|
182 | 199 | you will need to compile the CSS and JavaScript with Grunt. |
|
183 | 200 | This is easily done from within the nix-shell using the following command:: |
|
184 | 201 | |
|
185 | grunt | |
|
202 | make web-build | |
|
186 | 203 | |
|
187 | 204 | When developing new features you will need to recompile following any |
|
188 | 205 | changes made to the CSS or JavaScript files when developing the code:: |
@@ -18,11 +18,11 b' Activating rcextensions' | |||
|
18 | 18 | To activate rcextensions simply copy or rename the created template rcextensions |
|
19 | 19 | into the path where the rhodecode.ini file is located:: |
|
20 | 20 | |
|
21 | pushd ~/rccontrol/enterprise-1/ | |
|
21 | pushd ~/.rccontrol/enterprise-1/ | |
|
22 | 22 | or |
|
23 | pushd ~/rccontrol/community-1/ | |
|
23 | pushd ~/.rccontrol/community-1/ | |
|
24 | 24 | |
|
25 | mv etc/rcextensions.tmpl rcextensions | |
|
25 | mv profile/etc/rcextensions.tmpl rcextensions | |
|
26 | 26 | |
|
27 | 27 | |
|
28 | 28 | rcextensions are loaded when |RCE| starts. So a restart is required after activation or |
@@ -104,7 +104,7 b' Upgrade notes' | |||
|
104 | 104 | - In this release, we're shipping a new `rcextensions`. The changes made are |
|
105 | 105 | backward incompatible. An update of `rcextensions` is required |
|
106 | 106 | prior to using them again. Please check the new `rcextensions.tmpl` directory |
|
107 | located in `etc/rcextensions.tmpl` in your instance installation path. | |
|
107 | located in `profile/etc/rcextensions.tmpl` in your instance installation path. | |
|
108 | 108 | Old code should be 100% portable by just copy&paste to the right function. |
|
109 | 109 | |
|
110 | 110 | - Mailing: We introduced a new mailing library. The older options should be compatible and |
@@ -9,6 +9,7 b' Release Notes' | |||
|
9 | 9 | .. toctree:: |
|
10 | 10 | :maxdepth: 1 |
|
11 | 11 | |
|
12 | release-notes-4.16.0.rst | |
|
12 | 13 | release-notes-4.15.2.rst |
|
13 | 14 | release-notes-4.15.1.rst |
|
14 | 15 | release-notes-4.15.0.rst |
@@ -516,7 +516,7 b' Example usage:' | |||
|
516 | 516 | $ ~/.rccontrol/enterprise-4/profile/bin/rhodecode-index \ |
|
517 | 517 | --instance-name=enterprise-4 |
|
518 | 518 | |
|
519 | # Run indexer based on mapping.ini file | |
|
519 | # Run indexer based on search_mapping.ini file | |
|
520 | 520 | # This is using pre-350 virtualenv |
|
521 | 521 | (venv)$ rhodecode-index --instance-name=enterprise-1 |
|
522 | 522 | |
@@ -527,7 +527,7 b' Example usage:' | |||
|
527 | 527 | |
|
528 | 528 | # Create the indexing mapping file |
|
529 | 529 | $ ~/.rccontrol/enterprise-4/profile/bin/rhodecode-index \ |
|
530 | --create-mapping mapping.ini --instance-name=enterprise-4 | |
|
530 | --create-mapping search_mapping.ini --instance-name=enterprise-4 | |
|
531 | 531 | |
|
532 | 532 | .. _tools-rhodecode-list-instance: |
|
533 | 533 |
@@ -52,7 +52,7 b'' | |||
|
52 | 52 | "<%= dirs.js.src %>/plugins/jquery.auto-grow-input.js", |
|
53 | 53 | "<%= dirs.js.src %>/plugins/jquery.autocomplete.js", |
|
54 | 54 | "<%= dirs.js.src %>/plugins/jquery.debounce.js", |
|
55 |
"<%= dirs.js. |
|
|
55 | "<%= dirs.js.node_modules %>/mark.js/dist/jquery.mark.min.js", | |
|
56 | 56 | "<%= dirs.js.src %>/plugins/jquery.timeago.js", |
|
57 | 57 | "<%= dirs.js.src %>/plugins/jquery.timeago-extension.js", |
|
58 | 58 | "<%= dirs.js.src %>/select2/select2.js", |
@@ -22,6 +22,7 b'' | |||
|
22 | 22 | "grunt-contrib-watch": "^0.6.1", |
|
23 | 23 | "grunt-webpack": "^3.1.3", |
|
24 | 24 | "jquery": "1.11.3", |
|
25 | "mark.js": "8.11.1", | |
|
25 | 26 | "jshint": "^2.9.1-rc3", |
|
26 | 27 | "moment": "^2.18.1", |
|
27 | 28 | "mousetrap": "^1.6.1", |
This diff has been collapsed as it changes many lines, (696 lines changed) Show them Hide them | |||
@@ -409,13 +409,13 b' let' | |||
|
409 | 409 | sha512 = "mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA=="; |
|
410 | 410 | }; |
|
411 | 411 | }; |
|
412 |
"@webcomponents/shadycss-1. |
|
|
412 | "@webcomponents/shadycss-1.7.1" = { | |
|
413 | 413 | name = "_at_webcomponents_slash_shadycss"; |
|
414 | 414 | packageName = "@webcomponents/shadycss"; |
|
415 |
version = "1. |
|
|
416 | src = fetchurl { | |
|
417 |
url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1. |
|
|
418 | sha512 = "iURGZZU6BaiRJtGgjMn208QxPkY11QwT/VmuHNa4Yb+kJxU/WODe4C8b0LDOtnk4KJzJg50hCfwvPRAjePEzbA=="; | |
|
415 | version = "1.7.1"; | |
|
416 | src = fetchurl { | |
|
417 | url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.7.1.tgz"; | |
|
418 | sha512 = "6SZqLajRPWL0rrKDZOGF8PCBq5B9JqgFmE5rX5psk6i8WrqiMkSCuO8+rnirzViTsU5CqnjQPFC3OvG4YJdMrQ=="; | |
|
419 | 419 | }; |
|
420 | 420 | }; |
|
421 | 421 | "@webcomponents/webcomponentsjs-2.2.1" = { |
@@ -499,13 +499,13 b' let' | |||
|
499 | 499 | sha1 = "82ffb02b29e662ae53bdc20af15947706739c536"; |
|
500 | 500 | }; |
|
501 | 501 | }; |
|
502 |
"ajv-6.6. |
|
|
502 | "ajv-6.6.2" = { | |
|
503 | 503 | name = "ajv"; |
|
504 | 504 | packageName = "ajv"; |
|
505 |
version = "6.6. |
|
|
506 | src = fetchurl { | |
|
507 |
url = "https://registry.npmjs.org/ajv/-/ajv-6.6. |
|
|
508 | sha512 = "ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww=="; | |
|
505 | version = "6.6.2"; | |
|
506 | src = fetchurl { | |
|
507 | url = "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz"; | |
|
508 | sha512 = "FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g=="; | |
|
509 | 509 | }; |
|
510 | 510 | }; |
|
511 | 511 | "ajv-keywords-3.2.0" = { |
@@ -815,15 +815,6 b' let' | |||
|
815 | 815 | sha1 = "b6bbe0b0674b9d719708ca38de8c237cb526c3d1"; |
|
816 | 816 | }; |
|
817 | 817 | }; |
|
818 | "async-1.0.0" = { | |
|
819 | name = "async"; | |
|
820 | packageName = "async"; | |
|
821 | version = "1.0.0"; | |
|
822 | src = fetchurl { | |
|
823 | url = "https://registry.npmjs.org/async/-/async-1.0.0.tgz"; | |
|
824 | sha1 = "f8fc04ca3a13784ade9e1641af98578cfbd647a9"; | |
|
825 | }; | |
|
826 | }; | |
|
827 | 818 | "async-2.6.1" = { |
|
828 | 819 | name = "async"; |
|
829 | 820 | packageName = "async"; |
@@ -1445,6 +1436,15 b' let' | |||
|
1445 | 1436 | sha512 = "+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q=="; |
|
1446 | 1437 | }; |
|
1447 | 1438 | }; |
|
1439 | "big.js-5.2.2" = { | |
|
1440 | name = "big.js"; | |
|
1441 | packageName = "big.js"; | |
|
1442 | version = "5.2.2"; | |
|
1443 | src = fetchurl { | |
|
1444 | url = "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz"; | |
|
1445 | sha512 = "vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="; | |
|
1446 | }; | |
|
1447 | }; | |
|
1448 | 1448 | "binary-extensions-1.12.0" = { |
|
1449 | 1449 | name = "binary-extensions"; |
|
1450 | 1450 | packageName = "binary-extensions"; |
@@ -1679,22 +1679,22 b' let' | |||
|
1679 | 1679 | sha1 = "b534e7c734c4f81ec5fbe8aca2ad24354b962c6c"; |
|
1680 | 1680 | }; |
|
1681 | 1681 | }; |
|
1682 |
"caniuse-db-1.0.300009 |
|
|
1682 | "caniuse-db-1.0.30000927" = { | |
|
1683 | 1683 | name = "caniuse-db"; |
|
1684 | 1684 | packageName = "caniuse-db"; |
|
1685 |
version = "1.0.300009 |
|
|
1686 | src = fetchurl { | |
|
1687 |
url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.300009 |
|
|
1688 | sha512 = "uiepPdHcJ06Na9t15L5l+pp3NWQU4IETbmleghD6tqCqbIYqhHSu7nVfbK2gqPjfy+9jl/wHF1UQlyTszh9tJQ=="; | |
|
1689 | }; | |
|
1690 | }; | |
|
1691 |
"caniuse-lite-1.0.300009 |
|
|
1685 | version = "1.0.30000927"; | |
|
1686 | src = fetchurl { | |
|
1687 | url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000927.tgz"; | |
|
1688 | sha512 = "CX/QvLA8oh7kQ9cHCCzFm0UZW4KwSyQSRJ5A1XtH42HaMJQ0yh+9fEVWagMqv9I1vSCtaqA5Mb8k0uKfv7jhDw=="; | |
|
1689 | }; | |
|
1690 | }; | |
|
1691 | "caniuse-lite-1.0.30000927" = { | |
|
1692 | 1692 | name = "caniuse-lite"; |
|
1693 | 1693 | packageName = "caniuse-lite"; |
|
1694 |
version = "1.0.300009 |
|
|
1695 | src = fetchurl { | |
|
1696 |
url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.300009 |
|
|
1697 | sha512 = "M3zAtV36U+xw5mMROlTXpAHClmPAor6GPKAMD5Yi7glCB5sbMPFtnQ3rGpk4XqPdUrrTIaVYSJZxREZWNy8QJg=="; | |
|
1694 | version = "1.0.30000927"; | |
|
1695 | src = fetchurl { | |
|
1696 | url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000927.tgz"; | |
|
1697 | sha512 = "ogq4NbUWf1uG/j66k0AmiO3GjqJAlQyF8n4w8a954cbCyFKmYGvRtgz6qkq2fWuduTXHibX7GyYL5Pg58Aks2g=="; | |
|
1698 | 1698 | }; |
|
1699 | 1699 | }; |
|
1700 | 1700 | "caseless-0.12.0" = { |
@@ -1733,13 +1733,13 b' let' | |||
|
1733 | 1733 | sha1 = "a8115c55e4a702fe4d150abd3872822a7e09fc98"; |
|
1734 | 1734 | }; |
|
1735 | 1735 | }; |
|
1736 |
"chalk-2.4. |
|
|
1736 | "chalk-2.4.2" = { | |
|
1737 | 1737 | name = "chalk"; |
|
1738 | 1738 | packageName = "chalk"; |
|
1739 |
version = "2.4. |
|
|
1740 | src = fetchurl { | |
|
1741 |
url = "https://registry.npmjs.org/chalk/-/chalk-2.4. |
|
|
1742 | sha512 = "ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ=="; | |
|
1739 | version = "2.4.2"; | |
|
1740 | src = fetchurl { | |
|
1741 | url = "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"; | |
|
1742 | sha512 = "Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="; | |
|
1743 | 1743 | }; |
|
1744 | 1744 | }; |
|
1745 | 1745 | "chokidar-2.0.4" = { |
@@ -1958,15 +1958,6 b' let' | |||
|
1958 | 1958 | sha1 = "2423fe6678ac0c5dae8852e5d0e5be08c997abcc"; |
|
1959 | 1959 | }; |
|
1960 | 1960 | }; |
|
1961 | "colors-1.0.3" = { | |
|
1962 | name = "colors"; | |
|
1963 | packageName = "colors"; | |
|
1964 | version = "1.0.3"; | |
|
1965 | src = fetchurl { | |
|
1966 | url = "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz"; | |
|
1967 | sha1 = "0433f44d809680fdeb60ed260f1b0c262e82a40b"; | |
|
1968 | }; | |
|
1969 | }; | |
|
1970 | 1961 | "colors-1.1.2" = { |
|
1971 | 1962 | name = "colors"; |
|
1972 | 1963 | packageName = "colors"; |
@@ -1976,13 +1967,13 b' let' | |||
|
1976 | 1967 | sha1 = "168a4701756b6a7f51a12ce0c97bfa28c084ed63"; |
|
1977 | 1968 | }; |
|
1978 | 1969 | }; |
|
1979 |
"colors-1.3. |
|
|
1970 | "colors-1.3.3" = { | |
|
1980 | 1971 | name = "colors"; |
|
1981 | 1972 | packageName = "colors"; |
|
1982 |
version = "1.3. |
|
|
1983 | src = fetchurl { | |
|
1984 |
url = "https://registry.npmjs.org/colors/-/colors-1.3. |
|
|
1985 | sha512 = "rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ=="; | |
|
1973 | version = "1.3.3"; | |
|
1974 | src = fetchurl { | |
|
1975 | url = "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz"; | |
|
1976 | sha512 = "mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg=="; | |
|
1986 | 1977 | }; |
|
1987 | 1978 | }; |
|
1988 | 1979 | "combined-stream-1.0.7" = { |
@@ -2102,13 +2093,13 b' let' | |||
|
2102 | 2093 | sha512 = "Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA=="; |
|
2103 | 2094 | }; |
|
2104 | 2095 | }; |
|
2105 |
"core-js-2. |
|
|
2096 | "core-js-2.6.1" = { | |
|
2106 | 2097 | name = "core-js"; |
|
2107 | 2098 | packageName = "core-js"; |
|
2108 |
version = "2. |
|
|
2109 | src = fetchurl { | |
|
2110 |
url = "https://registry.npmjs.org/core-js/-/core-js-2. |
|
|
2111 | sha512 = "RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="; | |
|
2099 | version = "2.6.1"; | |
|
2100 | src = fetchurl { | |
|
2101 | url = "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz"; | |
|
2102 | sha512 = "L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg=="; | |
|
2112 | 2103 | }; |
|
2113 | 2104 | }; |
|
2114 | 2105 | "core-util-is-1.0.2" = { |
@@ -2246,15 +2237,6 b' let' | |||
|
2246 | 2237 | sha1 = "ddd52c587033f49e94b71fc55569f252e8ff5f85"; |
|
2247 | 2238 | }; |
|
2248 | 2239 | }; |
|
2249 | "cycle-1.0.3" = { | |
|
2250 | name = "cycle"; | |
|
2251 | packageName = "cycle"; | |
|
2252 | version = "1.0.3"; | |
|
2253 | src = fetchurl { | |
|
2254 | url = "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz"; | |
|
2255 | sha1 = "21e80b2be8580f98b468f379430662b046c34ad2"; | |
|
2256 | }; | |
|
2257 | }; | |
|
2258 | 2240 | "cyclist-0.2.2" = { |
|
2259 | 2241 | name = "cyclist"; |
|
2260 | 2242 | packageName = "cyclist"; |
@@ -2489,13 +2471,13 b' let' | |||
|
2489 | 2471 | sha1 = "bd28773e2642881aec51544924299c5cd822185b"; |
|
2490 | 2472 | }; |
|
2491 | 2473 | }; |
|
2492 |
"domelementtype-1.3. |
|
|
2474 | "domelementtype-1.3.1" = { | |
|
2493 | 2475 | name = "domelementtype"; |
|
2494 | 2476 | packageName = "domelementtype"; |
|
2495 |
version = "1.3. |
|
|
2496 | src = fetchurl { | |
|
2497 |
url = "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3. |
|
|
2498 | sha1 = "b17aed82e8ab59e52dd9c19b1756e0fc187204c2"; | |
|
2477 | version = "1.3.1"; | |
|
2478 | src = fetchurl { | |
|
2479 | url = "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz"; | |
|
2480 | sha512 = "BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="; | |
|
2499 | 2481 | }; |
|
2500 | 2482 | }; |
|
2501 | 2483 | "domhandler-2.1.0" = { |
@@ -2552,13 +2534,13 b' let' | |||
|
2552 | 2534 | sha1 = "3a83a904e54353287874c564b7549386849a98c9"; |
|
2553 | 2535 | }; |
|
2554 | 2536 | }; |
|
2555 |
"electron-to-chromium-1.3.8 |
|
|
2537 | "electron-to-chromium-1.3.98" = { | |
|
2556 | 2538 | name = "electron-to-chromium"; |
|
2557 | 2539 | packageName = "electron-to-chromium"; |
|
2558 |
version = "1.3.8 |
|
|
2559 | src = fetchurl { | |
|
2560 |
url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.8 |
|
|
2561 | sha512 = "kWSDVVF9t3mft2OHVZy4K85X2beP6c6mFm3teFS/mLSDJpQwuFIWHrULCX+w6H1E55ZYmFRlT+ATAFRwhrYzsw=="; | |
|
2540 | version = "1.3.98"; | |
|
2541 | src = fetchurl { | |
|
2542 | url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.98.tgz"; | |
|
2543 | sha512 = "WIZdNuvE3dFr6kkPgv4d/cfswNZD6XbeLBM8baOIQTsnbf4xWrVEaLvp7oNnbnMWWXDqq7Tbv+H5JfciLTJm4Q=="; | |
|
2562 | 2544 | }; |
|
2563 | 2545 | }; |
|
2564 | 2546 | "elliptic-6.4.1" = { |
@@ -2633,13 +2615,13 b' let' | |||
|
2633 | 2615 | sha512 = "MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg=="; |
|
2634 | 2616 | }; |
|
2635 | 2617 | }; |
|
2636 |
"es-abstract-1.1 |
|
|
2618 | "es-abstract-1.13.0" = { | |
|
2637 | 2619 | name = "es-abstract"; |
|
2638 | 2620 | packageName = "es-abstract"; |
|
2639 |
version = "1.1 |
|
|
2640 | src = fetchurl { | |
|
2641 |
url = "https://registry.npmjs.org/es-abstract/-/es-abstract-1.1 |
|
|
2642 | sha512 = "C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA=="; | |
|
2621 | version = "1.13.0"; | |
|
2622 | src = fetchurl { | |
|
2623 | url = "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz"; | |
|
2624 | sha512 = "vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg=="; | |
|
2643 | 2625 | }; |
|
2644 | 2626 | }; |
|
2645 | 2627 | "es-to-primitive-1.2.0" = { |
@@ -2651,15 +2633,6 b' let' | |||
|
2651 | 2633 | sha512 = "qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg=="; |
|
2652 | 2634 | }; |
|
2653 | 2635 | }; |
|
2654 | "es6-promise-4.2.5" = { | |
|
2655 | name = "es6-promise"; | |
|
2656 | packageName = "es6-promise"; | |
|
2657 | version = "4.2.5"; | |
|
2658 | src = fetchurl { | |
|
2659 | url = "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz"; | |
|
2660 | sha512 = "n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg=="; | |
|
2661 | }; | |
|
2662 | }; | |
|
2663 | 2636 | "es6-templates-0.2.3" = { |
|
2664 | 2637 | name = "es6-templates"; |
|
2665 | 2638 | packageName = "es6-templates"; |
@@ -2777,13 +2750,13 b' let' | |||
|
2777 | 2750 | sha512 = "/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA=="; |
|
2778 | 2751 | }; |
|
2779 | 2752 | }; |
|
2780 |
"execa- |
|
|
2753 | "execa-1.0.0" = { | |
|
2781 | 2754 | name = "execa"; |
|
2782 | 2755 | packageName = "execa"; |
|
2783 |
version = " |
|
|
2784 | src = fetchurl { | |
|
2785 |
url = "https://registry.npmjs.org/execa/-/execa- |
|
|
2786 | sha512 = "7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw=="; | |
|
2756 | version = "1.0.0"; | |
|
2757 | src = fetchurl { | |
|
2758 | url = "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz"; | |
|
2759 | sha512 = "adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA=="; | |
|
2787 | 2760 | }; |
|
2788 | 2761 | }; |
|
2789 | 2762 | "exit-0.1.2" = { |
@@ -2858,15 +2831,6 b' let' | |||
|
2858 | 2831 | sha512 = "Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw=="; |
|
2859 | 2832 | }; |
|
2860 | 2833 | }; |
|
2861 | "extract-zip-1.6.7" = { | |
|
2862 | name = "extract-zip"; | |
|
2863 | packageName = "extract-zip"; | |
|
2864 | version = "1.6.7"; | |
|
2865 | src = fetchurl { | |
|
2866 | url = "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz"; | |
|
2867 | sha1 = "a840b4b8af6403264c8db57f4f1a74333ef81fe9"; | |
|
2868 | }; | |
|
2869 | }; | |
|
2870 | 2834 | "extsprintf-1.3.0" = { |
|
2871 | 2835 | name = "extsprintf"; |
|
2872 | 2836 | packageName = "extsprintf"; |
@@ -2876,15 +2840,6 b' let' | |||
|
2876 | 2840 | sha1 = "96918440e3041a7a414f8c52e3c574eb3c3e1e05"; |
|
2877 | 2841 | }; |
|
2878 | 2842 | }; |
|
2879 | "eyes-0.1.8" = { | |
|
2880 | name = "eyes"; | |
|
2881 | packageName = "eyes"; | |
|
2882 | version = "0.1.8"; | |
|
2883 | src = fetchurl { | |
|
2884 | url = "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz"; | |
|
2885 | sha1 = "62cf120234c683785d902348a800ef3e0cc20bc0"; | |
|
2886 | }; | |
|
2887 | }; | |
|
2888 | 2843 | "fast-deep-equal-2.0.1" = { |
|
2889 | 2844 | name = "fast-deep-equal"; |
|
2890 | 2845 | packageName = "fast-deep-equal"; |
@@ -2930,15 +2885,6 b' let' | |||
|
2930 | 2885 | sha1 = "c14c5b3bf14d7417ffbfd990c0a7495cd9f337bc"; |
|
2931 | 2886 | }; |
|
2932 | 2887 | }; |
|
2933 | "fd-slicer-1.0.1" = { | |
|
2934 | name = "fd-slicer"; | |
|
2935 | packageName = "fd-slicer"; | |
|
2936 | version = "1.0.1"; | |
|
2937 | src = fetchurl { | |
|
2938 | url = "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz"; | |
|
2939 | sha1 = "8b5bcbd9ec327c5041bf9ab023fd6750f1177e65"; | |
|
2940 | }; | |
|
2941 | }; | |
|
2942 | 2888 | "file-sync-cmp-0.1.1" = { |
|
2943 | 2889 | name = "file-sync-cmp"; |
|
2944 | 2890 | packageName = "file-sync-cmp"; |
@@ -3002,22 +2948,22 b' let' | |||
|
3002 | 2948 | sha1 = "9326b1488c22d1a6088650a86901b2d9a90a2cbc"; |
|
3003 | 2949 | }; |
|
3004 | 2950 | }; |
|
3005 |
"fined-1.1. |
|
|
2951 | "fined-1.1.1" = { | |
|
3006 | 2952 | name = "fined"; |
|
3007 | 2953 | packageName = "fined"; |
|
3008 |
version = "1.1. |
|
|
3009 | src = fetchurl { | |
|
3010 |
url = "https://registry.npmjs.org/fined/-/fined-1.1. |
|
|
3011 | sha1 = "b37dc844b76a2f5e7081e884f7c0ae344f153476"; | |
|
3012 | }; | |
|
3013 | }; | |
|
3014 |
"flagged-respawn-1.0. |
|
|
2954 | version = "1.1.1"; | |
|
2955 | src = fetchurl { | |
|
2956 | url = "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz"; | |
|
2957 | sha512 = "jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g=="; | |
|
2958 | }; | |
|
2959 | }; | |
|
2960 | "flagged-respawn-1.0.1" = { | |
|
3015 | 2961 | name = "flagged-respawn"; |
|
3016 | 2962 | packageName = "flagged-respawn"; |
|
3017 |
version = "1.0. |
|
|
3018 | src = fetchurl { | |
|
3019 |
url = "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0. |
|
|
3020 | sha1 = "4e79ae9b2eb38bf86b3bb56bf3e0a56aa5fcabd7"; | |
|
2963 | version = "1.0.1"; | |
|
2964 | src = fetchurl { | |
|
2965 | url = "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz"; | |
|
2966 | sha512 = "lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q=="; | |
|
3021 | 2967 | }; |
|
3022 | 2968 | }; |
|
3023 | 2969 | "flatten-1.0.2" = { |
@@ -3092,15 +3038,6 b' let' | |||
|
3092 | 3038 | sha1 = "8bfb5502bde4a4d36cfdeea007fcca21d7e382af"; |
|
3093 | 3039 | }; |
|
3094 | 3040 | }; |
|
3095 | "fs-extra-1.0.0" = { | |
|
3096 | name = "fs-extra"; | |
|
3097 | packageName = "fs-extra"; | |
|
3098 | version = "1.0.0"; | |
|
3099 | src = fetchurl { | |
|
3100 | url = "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz"; | |
|
3101 | sha1 = "cd3ce5f7e7cb6145883fcae3191e9877f8587950"; | |
|
3102 | }; | |
|
3103 | }; | |
|
3104 | 3041 | "fs-write-stream-atomic-1.0.10" = { |
|
3105 | 3042 | name = "fs-write-stream-atomic"; |
|
3106 | 3043 | packageName = "fs-write-stream-atomic"; |
@@ -3155,13 +3092,13 b' let' | |||
|
3155 | 3092 | sha512 = "3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="; |
|
3156 | 3093 | }; |
|
3157 | 3094 | }; |
|
3158 |
"get-stream- |
|
|
3095 | "get-stream-4.1.0" = { | |
|
3159 | 3096 | name = "get-stream"; |
|
3160 | 3097 | packageName = "get-stream"; |
|
3161 |
version = " |
|
|
3162 | src = fetchurl { | |
|
3163 |
url = "https://registry.npmjs.org/get-stream/-/get-stream- |
|
|
3164 | sha1 = "8e943d1358dc37555054ecbe2edb05aa174ede14"; | |
|
3098 | version = "4.1.0"; | |
|
3099 | src = fetchurl { | |
|
3100 | url = "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz"; | |
|
3101 | sha512 = "GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w=="; | |
|
3165 | 3102 | }; |
|
3166 | 3103 | }; |
|
3167 | 3104 | "get-value-2.0.6" = { |
@@ -3236,13 +3173,13 b' let' | |||
|
3236 | 3173 | sha512 = "sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg=="; |
|
3237 | 3174 | }; |
|
3238 | 3175 | }; |
|
3239 |
"global-modules-path-2.3. |
|
|
3176 | "global-modules-path-2.3.1" = { | |
|
3240 | 3177 | name = "global-modules-path"; |
|
3241 | 3178 | packageName = "global-modules-path"; |
|
3242 |
version = "2.3. |
|
|
3243 | src = fetchurl { | |
|
3244 |
url = "https://registry.npmjs.org/global-modules-path/-/global-modules-path-2.3. |
|
|
3245 | sha512 = "HchvMJNYh9dGSCy8pOQ2O8u/hoXaL+0XhnrwH0RyLiSXMMTl9W3N6KUU73+JFOg5PGjtzl6VZzUQsnrpm7Szag=="; | |
|
3179 | version = "2.3.1"; | |
|
3180 | src = fetchurl { | |
|
3181 | url = "https://registry.npmjs.org/global-modules-path/-/global-modules-path-2.3.1.tgz"; | |
|
3182 | sha512 = "y+shkf4InI7mPRHSo2b/k6ix6+NLDtyccYv86whhxrSGX9wjPX1VMITmrDbE1eh7zkzhiWtW2sHklJYoQ62Cxg=="; | |
|
3246 | 3183 | }; |
|
3247 | 3184 | }; |
|
3248 | 3185 | "global-prefix-1.0.2" = { |
@@ -3533,22 +3470,13 b' let' | |||
|
3533 | 3470 | sha1 = "5fc8686847ecd73499403319a6b0a3f3f6ae4918"; |
|
3534 | 3471 | }; |
|
3535 | 3472 | }; |
|
3536 |
"hash.js-1.1. |
|
|
3473 | "hash.js-1.1.7" = { | |
|
3537 | 3474 | name = "hash.js"; |
|
3538 | 3475 | packageName = "hash.js"; |
|
3539 |
version = "1.1. |
|
|
3540 | src = fetchurl { | |
|
3541 |
url = "https://registry.npmjs.org/hash.js/-/hash.js-1.1. |
|
|
3542 | sha512 = "eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA=="; | |
|
3543 | }; | |
|
3544 | }; | |
|
3545 | "hasha-2.2.0" = { | |
|
3546 | name = "hasha"; | |
|
3547 | packageName = "hasha"; | |
|
3548 | version = "2.2.0"; | |
|
3549 | src = fetchurl { | |
|
3550 | url = "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz"; | |
|
3551 | sha1 = "78d7cbfc1e6d66303fe79837365984517b2f6ee1"; | |
|
3476 | version = "1.1.7"; | |
|
3477 | src = fetchurl { | |
|
3478 | url = "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz"; | |
|
3479 | sha512 = "taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA=="; | |
|
3552 | 3480 | }; |
|
3553 | 3481 | }; |
|
3554 | 3482 | "hawk-3.1.3" = { |
@@ -4217,13 +4145,13 b' let' | |||
|
4217 | 4145 | sha1 = "dd8b74278b27102d29df63eae28308a8cfa1b583"; |
|
4218 | 4146 | }; |
|
4219 | 4147 | }; |
|
4220 |
"js-base64-2. |
|
|
4148 | "js-base64-2.5.0" = { | |
|
4221 | 4149 | name = "js-base64"; |
|
4222 | 4150 | packageName = "js-base64"; |
|
4223 |
version = "2. |
|
|
4224 | src = fetchurl { | |
|
4225 |
url = "https://registry.npmjs.org/js-base64/-/js-base64-2. |
|
|
4226 | sha512 = "xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ=="; | |
|
4151 | version = "2.5.0"; | |
|
4152 | src = fetchurl { | |
|
4153 | url = "https://registry.npmjs.org/js-base64/-/js-base64-2.5.0.tgz"; | |
|
4154 | sha512 = "wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g=="; | |
|
4227 | 4155 | }; |
|
4228 | 4156 | }; |
|
4229 | 4157 | "js-tokens-3.0.2" = { |
@@ -4280,13 +4208,13 b' let' | |||
|
4280 | 4208 | sha1 = "46c3fec8c1892b12b0833db9bc7622176dbab34b"; |
|
4281 | 4209 | }; |
|
4282 | 4210 | }; |
|
4283 |
"jshint-2.9. |
|
|
4211 | "jshint-2.9.7" = { | |
|
4284 | 4212 | name = "jshint"; |
|
4285 | 4213 | packageName = "jshint"; |
|
4286 |
version = "2.9. |
|
|
4287 | src = fetchurl { | |
|
4288 |
url = "https://registry.npmjs.org/jshint/-/jshint-2.9. |
|
|
4289 | sha512 = "KO9SIAKTlJQOM4lE64GQUtGBRpTOuvbrRrSZw3AhUxMNG266nX9hK2cKA4SBhXOj0irJGyNyGSLT62HGOVDEOA=="; | |
|
4214 | version = "2.9.7"; | |
|
4215 | src = fetchurl { | |
|
4216 | url = "https://registry.npmjs.org/jshint/-/jshint-2.9.7.tgz"; | |
|
4217 | sha512 = "Q8XN38hGsVQhdlM+4gd1Xl7OB1VieSuCJf+fEJjpo59JH99bVJhXRXAh26qQ15wfdd1VPMuDWNeSWoNl53T4YA=="; | |
|
4290 | 4218 | }; |
|
4291 | 4219 | }; |
|
4292 | 4220 | "json-parse-better-errors-1.0.2" = { |
@@ -4343,13 +4271,13 b' let' | |||
|
4343 | 4271 | sha1 = "1eade7acc012034ad84e2396767ead9fa5495821"; |
|
4344 | 4272 | }; |
|
4345 | 4273 | }; |
|
4346 |
"json |
|
|
4347 |
name = "json |
|
|
4348 |
packageName = "json |
|
|
4349 |
version = " |
|
|
4350 | src = fetchurl { | |
|
4351 |
url = "https://registry.npmjs.org/json |
|
|
4352 | sha1 = "3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"; | |
|
4274 | "json5-1.0.1" = { | |
|
4275 | name = "json5"; | |
|
4276 | packageName = "json5"; | |
|
4277 | version = "1.0.1"; | |
|
4278 | src = fetchurl { | |
|
4279 | url = "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz"; | |
|
4280 | sha512 = "aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow=="; | |
|
4353 | 4281 | }; |
|
4354 | 4282 | }; |
|
4355 | 4283 | "jsonify-0.0.0" = { |
@@ -4370,15 +4298,6 b' let' | |||
|
4370 | 4298 | sha1 = "313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"; |
|
4371 | 4299 | }; |
|
4372 | 4300 | }; |
|
4373 | "kew-0.7.0" = { | |
|
4374 | name = "kew"; | |
|
4375 | packageName = "kew"; | |
|
4376 | version = "0.7.0"; | |
|
4377 | src = fetchurl { | |
|
4378 | url = "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz"; | |
|
4379 | sha1 = "79d93d2d33363d6fdd2970b335d9141ad591d79b"; | |
|
4380 | }; | |
|
4381 | }; | |
|
4382 | 4301 | "kind-of-3.2.2" = { |
|
4383 | 4302 | name = "kind-of"; |
|
4384 | 4303 | packageName = "kind-of"; |
@@ -4415,15 +4334,6 b' let' | |||
|
4415 | 4334 | sha512 = "s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="; |
|
4416 | 4335 | }; |
|
4417 | 4336 | }; |
|
4418 | "klaw-1.3.1" = { | |
|
4419 | name = "klaw"; | |
|
4420 | packageName = "klaw"; | |
|
4421 | version = "1.3.1"; | |
|
4422 | src = fetchurl { | |
|
4423 | url = "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz"; | |
|
4424 | sha1 = "4088433b46b3b1ba259d78785d8e96f73ba02439"; | |
|
4425 | }; | |
|
4426 | }; | |
|
4427 | 4337 | "lazy-cache-1.0.4" = { |
|
4428 | 4338 | name = "lazy-cache"; |
|
4429 | 4339 | packageName = "lazy-cache"; |
@@ -4478,13 +4388,13 b' let' | |||
|
4478 | 4388 | sha1 = "f86e6374d43205a6e6c60e9196f17c0299bfb348"; |
|
4479 | 4389 | }; |
|
4480 | 4390 | }; |
|
4481 |
"loader-utils-1. |
|
|
4391 | "loader-utils-1.2.3" = { | |
|
4482 | 4392 | name = "loader-utils"; |
|
4483 | 4393 | packageName = "loader-utils"; |
|
4484 |
version = "1. |
|
|
4485 | src = fetchurl { | |
|
4486 |
url = "https://registry.npmjs.org/loader-utils/-/loader-utils-1. |
|
|
4487 | sha1 = "c98aef488bcceda2ffb5e2de646d6a754429f5cd"; | |
|
4394 | version = "1.2.3"; | |
|
4395 | src = fetchurl { | |
|
4396 | url = "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz"; | |
|
4397 | sha512 = "fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA=="; | |
|
4488 | 4398 | }; |
|
4489 | 4399 | }; |
|
4490 | 4400 | "locate-path-2.0.0" = { |
@@ -4676,6 +4586,15 b' let' | |||
|
4676 | 4586 | sha1 = "ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"; |
|
4677 | 4587 | }; |
|
4678 | 4588 | }; |
|
4589 | "mark.js-8.11.1" = { | |
|
4590 | name = "mark.js"; | |
|
4591 | packageName = "mark.js"; | |
|
4592 | version = "8.11.1"; | |
|
4593 | src = fetchurl { | |
|
4594 | url = "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz"; | |
|
4595 | sha1 = "180f1f9ebef8b0e638e4166ad52db879beb2ffc5"; | |
|
4596 | }; | |
|
4597 | }; | |
|
4679 | 4598 | "math-expression-evaluator-1.2.17" = { |
|
4680 | 4599 | name = "math-expression-evaluator"; |
|
4681 | 4600 | packageName = "math-expression-evaluator"; |
@@ -4820,6 +4739,15 b' let' | |||
|
4820 | 4739 | sha1 = "857fcabfc3397d2625b8228262e86aa7a011b05d"; |
|
4821 | 4740 | }; |
|
4822 | 4741 | }; |
|
4742 | "minimist-1.2.0" = { | |
|
4743 | name = "minimist"; | |
|
4744 | packageName = "minimist"; | |
|
4745 | version = "1.2.0"; | |
|
4746 | src = fetchurl { | |
|
4747 | url = "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"; | |
|
4748 | sha1 = "a35008b20f41383eec1fb914f4cd5df79a264284"; | |
|
4749 | }; | |
|
4750 | }; | |
|
4823 | 4751 | "mississippi-2.0.0" = { |
|
4824 | 4752 | name = "mississippi"; |
|
4825 | 4753 | packageName = "mississippi"; |
@@ -4847,13 +4775,13 b' let' | |||
|
4847 | 4775 | sha1 = "30057438eac6cf7f8c4767f38648d6697d75c903"; |
|
4848 | 4776 | }; |
|
4849 | 4777 | }; |
|
4850 |
"moment-2.2 |
|
|
4778 | "moment-2.23.0" = { | |
|
4851 | 4779 | name = "moment"; |
|
4852 | 4780 | packageName = "moment"; |
|
4853 |
version = "2.2 |
|
|
4854 | src = fetchurl { | |
|
4855 |
url = "https://registry.npmjs.org/moment/-/moment-2.2 |
|
|
4856 | sha1 = "3c257f9839fc0e93ff53149632239eb90783ff66"; | |
|
4781 | version = "2.23.0"; | |
|
4782 | src = fetchurl { | |
|
4783 | url = "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz"; | |
|
4784 | sha512 = "3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA=="; | |
|
4857 | 4785 | }; |
|
4858 | 4786 | }; |
|
4859 | 4787 | "mousetrap-1.6.2" = { |
@@ -4883,13 +4811,13 b' let' | |||
|
4883 | 4811 | sha1 = "5608aeadfc00be6c2901df5f9861788de0d597c8"; |
|
4884 | 4812 | }; |
|
4885 | 4813 | }; |
|
4886 |
"nan-2.1 |
|
|
4814 | "nan-2.12.1" = { | |
|
4887 | 4815 | name = "nan"; |
|
4888 | 4816 | packageName = "nan"; |
|
4889 |
version = "2.1 |
|
|
4890 | src = fetchurl { | |
|
4891 |
url = "https://registry.npmjs.org/nan/-/nan-2.1 |
|
|
4892 | sha512 = "iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA=="; | |
|
4817 | version = "2.12.1"; | |
|
4818 | src = fetchurl { | |
|
4819 | url = "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz"; | |
|
4820 | sha512 = "JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw=="; | |
|
4893 | 4821 | }; |
|
4894 | 4822 | }; |
|
4895 | 4823 | "nanomatch-1.2.13" = { |
@@ -5144,13 +5072,13 b' let' | |||
|
5144 | 5072 | sha1 = "ffbc4988336e0e833de0c168c7ef152121aa7fb3"; |
|
5145 | 5073 | }; |
|
5146 | 5074 | }; |
|
5147 |
"os-locale-3.0 |
|
|
5075 | "os-locale-3.1.0" = { | |
|
5148 | 5076 | name = "os-locale"; |
|
5149 | 5077 | packageName = "os-locale"; |
|
5150 |
version = "3.0 |
|
|
5151 | src = fetchurl { | |
|
5152 |
url = "https://registry.npmjs.org/os-locale/-/os-locale-3.0 |
|
|
5153 | sha512 = "7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw=="; | |
|
5078 | version = "3.1.0"; | |
|
5079 | src = fetchurl { | |
|
5080 | url = "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz"; | |
|
5081 | sha512 = "Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q=="; | |
|
5154 | 5082 | }; |
|
5155 | 5083 | }; |
|
5156 | 5084 | "os-tmpdir-1.0.2" = { |
@@ -5207,13 +5135,13 b' let' | |||
|
5207 | 5135 | sha512 = "vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q=="; |
|
5208 | 5136 | }; |
|
5209 | 5137 | }; |
|
5210 |
"p-limit-2. |
|
|
5138 | "p-limit-2.1.0" = { | |
|
5211 | 5139 | name = "p-limit"; |
|
5212 | 5140 | packageName = "p-limit"; |
|
5213 |
version = "2. |
|
|
5214 | src = fetchurl { | |
|
5215 |
url = "https://registry.npmjs.org/p-limit/-/p-limit-2. |
|
|
5216 | sha512 = "fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A=="; | |
|
5141 | version = "2.1.0"; | |
|
5142 | src = fetchurl { | |
|
5143 | url = "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz"; | |
|
5144 | sha512 = "NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g=="; | |
|
5217 | 5145 | }; |
|
5218 | 5146 | }; |
|
5219 | 5147 | "p-locate-2.0.0" = { |
@@ -5432,15 +5360,6 b' let' | |||
|
5432 | 5360 | sha512 = "U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA=="; |
|
5433 | 5361 | }; |
|
5434 | 5362 | }; |
|
5435 | "pend-1.2.0" = { | |
|
5436 | name = "pend"; | |
|
5437 | packageName = "pend"; | |
|
5438 | version = "1.2.0"; | |
|
5439 | src = fetchurl { | |
|
5440 | url = "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz"; | |
|
5441 | sha1 = "7a57eb550a6783f9115331fcf4663d5c8e007a50"; | |
|
5442 | }; | |
|
5443 | }; | |
|
5444 | 5363 | "performance-now-0.2.0" = { |
|
5445 | 5364 | name = "performance-now"; |
|
5446 | 5365 | packageName = "performance-now"; |
@@ -5450,24 +5369,6 b' let' | |||
|
5450 | 5369 | sha1 = "33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"; |
|
5451 | 5370 | }; |
|
5452 | 5371 | }; |
|
5453 | "phantom-4.0.12" = { | |
|
5454 | name = "phantom"; | |
|
5455 | packageName = "phantom"; | |
|
5456 | version = "4.0.12"; | |
|
5457 | src = fetchurl { | |
|
5458 | url = "https://registry.npmjs.org/phantom/-/phantom-4.0.12.tgz"; | |
|
5459 | sha512 = "Tz82XhtPmwCk1FFPmecy7yRGZG2btpzY2KI9fcoPT7zT9det0CcMyfBFPp1S8DqzsnQnm8ZYEfdy528mwVtksA=="; | |
|
5460 | }; | |
|
5461 | }; | |
|
5462 | "phantomjs-prebuilt-2.1.16" = { | |
|
5463 | name = "phantomjs-prebuilt"; | |
|
5464 | packageName = "phantomjs-prebuilt"; | |
|
5465 | version = "2.1.16"; | |
|
5466 | src = fetchurl { | |
|
5467 | url = "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz"; | |
|
5468 | sha1 = "efd212a4a3966d3647684ea8ba788549be2aefef"; | |
|
5469 | }; | |
|
5470 | }; | |
|
5471 | 5372 | "pify-3.0.0" = { |
|
5472 | 5373 | name = "pify"; |
|
5473 | 5374 | packageName = "pify"; |
@@ -5477,24 +5378,6 b' let' | |||
|
5477 | 5378 | sha1 = "e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"; |
|
5478 | 5379 | }; |
|
5479 | 5380 | }; |
|
5480 | "pinkie-2.0.4" = { | |
|
5481 | name = "pinkie"; | |
|
5482 | packageName = "pinkie"; | |
|
5483 | version = "2.0.4"; | |
|
5484 | src = fetchurl { | |
|
5485 | url = "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz"; | |
|
5486 | sha1 = "72556b80cfa0d48a974e80e77248e80ed4f7f870"; | |
|
5487 | }; | |
|
5488 | }; | |
|
5489 | "pinkie-promise-2.0.1" = { | |
|
5490 | name = "pinkie-promise"; | |
|
5491 | packageName = "pinkie-promise"; | |
|
5492 | version = "2.0.1"; | |
|
5493 | src = fetchurl { | |
|
5494 | url = "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"; | |
|
5495 | sha1 = "2135d6dfa7a358c069ac9b178776288228450ffa"; | |
|
5496 | }; | |
|
5497 | }; | |
|
5498 | 5381 | "pkg-dir-2.0.0" = { |
|
5499 | 5382 | name = "pkg-dir"; |
|
5500 | 5383 | packageName = "pkg-dir"; |
@@ -5882,15 +5765,6 b' let' | |||
|
5882 | 5765 | sha512 = "MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="; |
|
5883 | 5766 | }; |
|
5884 | 5767 | }; |
|
5885 | "progress-1.1.8" = { | |
|
5886 | name = "progress"; | |
|
5887 | packageName = "progress"; | |
|
5888 | version = "1.1.8"; | |
|
5889 | src = fetchurl { | |
|
5890 | url = "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz"; | |
|
5891 | sha1 = "e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"; | |
|
5892 | }; | |
|
5893 | }; | |
|
5894 | 5768 | "promise-7.3.1" = { |
|
5895 | 5769 | name = "promise"; |
|
5896 | 5770 | packageName = "promise"; |
@@ -5945,6 +5819,15 b' let' | |||
|
5945 | 5819 | sha512 = "ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA=="; |
|
5946 | 5820 | }; |
|
5947 | 5821 | }; |
|
5822 | "pump-3.0.0" = { | |
|
5823 | name = "pump"; | |
|
5824 | packageName = "pump"; | |
|
5825 | version = "3.0.0"; | |
|
5826 | src = fetchurl { | |
|
5827 | url = "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz"; | |
|
5828 | sha512 = "LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="; | |
|
5829 | }; | |
|
5830 | }; | |
|
5948 | 5831 | "pumpify-1.5.1" = { |
|
5949 | 5832 | name = "pumpify"; |
|
5950 | 5833 | packageName = "pumpify"; |
@@ -6278,15 +6161,6 b' let' | |||
|
6278 | 6161 | sha1 = "c6928946a0e06c5f8d6f8a9333469ffda46298a0"; |
|
6279 | 6162 | }; |
|
6280 | 6163 | }; |
|
6281 | "request-progress-2.0.1" = { | |
|
6282 | name = "request-progress"; | |
|
6283 | packageName = "request-progress"; | |
|
6284 | version = "2.0.1"; | |
|
6285 | src = fetchurl { | |
|
6286 | url = "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz"; | |
|
6287 | sha1 = "5d36bb57961c673aa5b788dbc8141fdf23b44e08"; | |
|
6288 | }; | |
|
6289 | }; | |
|
6290 | 6164 | "require-directory-2.1.1" = { |
|
6291 | 6165 | name = "require-directory"; |
|
6292 | 6166 | packageName = "require-directory"; |
@@ -6305,13 +6179,13 b' let' | |||
|
6305 | 6179 | sha1 = "97f717b69d48784f5f526a6c5aa8ffdda055a4d1"; |
|
6306 | 6180 | }; |
|
6307 | 6181 | }; |
|
6308 |
"resolve-1. |
|
|
6182 | "resolve-1.9.0" = { | |
|
6309 | 6183 | name = "resolve"; |
|
6310 | 6184 | packageName = "resolve"; |
|
6311 |
version = "1. |
|
|
6312 | src = fetchurl { | |
|
6313 |
url = "https://registry.npmjs.org/resolve/-/resolve-1. |
|
|
6314 | sha512 = "AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA=="; | |
|
6185 | version = "1.9.0"; | |
|
6186 | src = fetchurl { | |
|
6187 | url = "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz"; | |
|
6188 | sha512 = "TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ=="; | |
|
6315 | 6189 | }; |
|
6316 | 6190 | }; |
|
6317 | 6191 | "resolve-cwd-2.0.0" = { |
@@ -6377,13 +6251,13 b' let' | |||
|
6377 | 6251 | sha1 = "e439be2aaee327321952730f99a8929e4fc50582"; |
|
6378 | 6252 | }; |
|
6379 | 6253 | }; |
|
6380 |
"rimraf-2.6. |
|
|
6254 | "rimraf-2.6.3" = { | |
|
6381 | 6255 | name = "rimraf"; |
|
6382 | 6256 | packageName = "rimraf"; |
|
6383 |
version = "2.6. |
|
|
6384 | src = fetchurl { | |
|
6385 |
url = "https://registry.npmjs.org/rimraf/-/rimraf-2.6. |
|
|
6386 | sha512 = "lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w=="; | |
|
6257 | version = "2.6.3"; | |
|
6258 | src = fetchurl { | |
|
6259 | url = "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz"; | |
|
6260 | sha512 = "mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="; | |
|
6387 | 6261 | }; |
|
6388 | 6262 | }; |
|
6389 | 6263 | "ripemd160-2.0.2" = { |
@@ -6467,13 +6341,13 b' let' | |||
|
6467 | 6341 | sha512 = "RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="; |
|
6468 | 6342 | }; |
|
6469 | 6343 | }; |
|
6470 |
"serialize-javascript-1. |
|
|
6344 | "serialize-javascript-1.6.1" = { | |
|
6471 | 6345 | name = "serialize-javascript"; |
|
6472 | 6346 | packageName = "serialize-javascript"; |
|
6473 |
version = "1. |
|
|
6474 | src = fetchurl { | |
|
6475 |
url = "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1. |
|
|
6476 | sha512 = "Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ=="; | |
|
6347 | version = "1.6.1"; | |
|
6348 | src = fetchurl { | |
|
6349 | url = "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz"; | |
|
6350 | sha512 = "A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw=="; | |
|
6477 | 6351 | }; |
|
6478 | 6352 | }; |
|
6479 | 6353 | "set-blocking-2.0.0" = { |
@@ -6701,15 +6575,6 b' let' | |||
|
6701 | 6575 | sha1 = "3e935d7ddd73631b97659956d55128e87b5084a3"; |
|
6702 | 6576 | }; |
|
6703 | 6577 | }; |
|
6704 | "split-1.0.1" = { | |
|
6705 | name = "split"; | |
|
6706 | packageName = "split"; | |
|
6707 | version = "1.0.1"; | |
|
6708 | src = fetchurl { | |
|
6709 | url = "https://registry.npmjs.org/split/-/split-1.0.1.tgz"; | |
|
6710 | sha512 = "mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg=="; | |
|
6711 | }; | |
|
6712 | }; | |
|
6713 | 6578 | "split-string-3.1.0" = { |
|
6714 | 6579 | name = "split-string"; |
|
6715 | 6580 | packageName = "split-string"; |
@@ -6728,13 +6593,13 b' let' | |||
|
6728 | 6593 | sha1 = "04e6926f662895354f3dd015203633b857297e2c"; |
|
6729 | 6594 | }; |
|
6730 | 6595 | }; |
|
6731 |
"sshpk-1.1 |
|
|
6596 | "sshpk-1.16.0" = { | |
|
6732 | 6597 | name = "sshpk"; |
|
6733 | 6598 | packageName = "sshpk"; |
|
6734 |
version = "1.1 |
|
|
6735 | src = fetchurl { | |
|
6736 |
url = "https://registry.npmjs.org/sshpk/-/sshpk-1.1 |
|
|
6737 | sha512 = "Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA=="; | |
|
6599 | version = "1.16.0"; | |
|
6600 | src = fetchurl { | |
|
6601 | url = "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz"; | |
|
6602 | sha512 = "Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ=="; | |
|
6738 | 6603 | }; |
|
6739 | 6604 | }; |
|
6740 | 6605 | "ssri-5.3.0" = { |
@@ -6746,15 +6611,6 b' let' | |||
|
6746 | 6611 | sha512 = "XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ=="; |
|
6747 | 6612 | }; |
|
6748 | 6613 | }; |
|
6749 | "stack-trace-0.0.10" = { | |
|
6750 | name = "stack-trace"; | |
|
6751 | packageName = "stack-trace"; | |
|
6752 | version = "0.0.10"; | |
|
6753 | src = fetchurl { | |
|
6754 | url = "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz"; | |
|
6755 | sha1 = "547c70b347e8d32b4e108ea1a2a159e5fdde19c0"; | |
|
6756 | }; | |
|
6757 | }; | |
|
6758 | 6614 | "static-extend-0.1.2" = { |
|
6759 | 6615 | name = "static-extend"; |
|
6760 | 6616 | packageName = "static-extend"; |
@@ -6989,15 +6845,6 b' let' | |||
|
6989 | 6845 | sha512 = "9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA=="; |
|
6990 | 6846 | }; |
|
6991 | 6847 | }; |
|
6992 | "throttleit-1.0.0" = { | |
|
6993 | name = "throttleit"; | |
|
6994 | packageName = "throttleit"; | |
|
6995 | version = "1.0.0"; | |
|
6996 | src = fetchurl { | |
|
6997 | url = "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz"; | |
|
6998 | sha1 = "9e785836daf46743145a5984b6268d828528ac6c"; | |
|
6999 | }; | |
|
7000 | }; | |
|
7001 | 6848 | "through-2.3.8" = { |
|
7002 | 6849 | name = "through"; |
|
7003 | 6850 | packageName = "through"; |
@@ -7259,15 +7106,6 b' let' | |||
|
7259 | 7106 | sha1 = "8cdd8fbac4e2d2ea1e7e2e8097c42f442280f85b"; |
|
7260 | 7107 | }; |
|
7261 | 7108 | }; |
|
7262 | "unicode-5.2.0-0.7.5" = { | |
|
7263 | name = "unicode-5.2.0"; | |
|
7264 | packageName = "unicode-5.2.0"; | |
|
7265 | version = "0.7.5"; | |
|
7266 | src = fetchurl { | |
|
7267 | url = "https://registry.npmjs.org/unicode-5.2.0/-/unicode-5.2.0-0.7.5.tgz"; | |
|
7268 | sha512 = "KVGLW1Bri30x00yv4HNM8kBxoqFXr0Sbo55735nvrlsx4PYBZol3UtoWgO492fSwmsetzPEZzy73rbU8OGXJcA=="; | |
|
7269 | }; | |
|
7270 | }; | |
|
7271 | 7109 | "union-value-1.0.0" = { |
|
7272 | 7110 | name = "union-value"; |
|
7273 | 7111 | packageName = "union-value"; |
@@ -7439,13 +7277,13 b' let' | |||
|
7439 | 7277 | sha512 = "1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw=="; |
|
7440 | 7278 | }; |
|
7441 | 7279 | }; |
|
7442 |
"v8flags-3.1. |
|
|
7280 | "v8flags-3.1.2" = { | |
|
7443 | 7281 | name = "v8flags"; |
|
7444 | 7282 | packageName = "v8flags"; |
|
7445 |
version = "3.1. |
|
|
7446 | src = fetchurl { | |
|
7447 |
url = "https://registry.npmjs.org/v8flags/-/v8flags-3.1. |
|
|
7448 | sha512 = "iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ=="; | |
|
7283 | version = "3.1.2"; | |
|
7284 | src = fetchurl { | |
|
7285 | url = "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz"; | |
|
7286 | sha512 = "MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw=="; | |
|
7449 | 7287 | }; |
|
7450 | 7288 | }; |
|
7451 | 7289 | "vendors-1.0.2" = { |
@@ -7583,15 +7421,6 b' let' | |||
|
7583 | 7421 | sha1 = "5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"; |
|
7584 | 7422 | }; |
|
7585 | 7423 | }; |
|
7586 | "winston-2.4.4" = { | |
|
7587 | name = "winston"; | |
|
7588 | packageName = "winston"; | |
|
7589 | version = "2.4.4"; | |
|
7590 | src = fetchurl { | |
|
7591 | url = "https://registry.npmjs.org/winston/-/winston-2.4.4.tgz"; | |
|
7592 | sha512 = "NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q=="; | |
|
7593 | }; | |
|
7594 | }; | |
|
7595 | 7424 | "wordwrap-0.0.2" = { |
|
7596 | 7425 | name = "wordwrap"; |
|
7597 | 7426 | packageName = "wordwrap"; |
@@ -7682,15 +7511,6 b' let' | |||
|
7682 | 7511 | sha512 = "C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ=="; |
|
7683 | 7512 | }; |
|
7684 | 7513 | }; |
|
7685 | "yauzl-2.4.1" = { | |
|
7686 | name = "yauzl"; | |
|
7687 | packageName = "yauzl"; | |
|
7688 | version = "2.4.1"; | |
|
7689 | src = fetchurl { | |
|
7690 | url = "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz"; | |
|
7691 | sha1 = "9528f442dab1b2284e58b4379bb194e22e0c4005"; | |
|
7692 | }; | |
|
7693 | }; | |
|
7694 | 7514 | }; |
|
7695 | 7515 | args = { |
|
7696 | 7516 | name = "rhodecode-enterprise"; |
@@ -7743,7 +7563,7 b' let' | |||
|
7743 | 7563 | sources."@webassemblyjs/wasm-parser-1.7.10" |
|
7744 | 7564 | sources."@webassemblyjs/wast-parser-1.7.10" |
|
7745 | 7565 | sources."@webassemblyjs/wast-printer-1.7.10" |
|
7746 |
sources."@webcomponents/shadycss-1. |
|
|
7566 | sources."@webcomponents/shadycss-1.7.1" | |
|
7747 | 7567 | sources."@webcomponents/webcomponentsjs-2.2.1" |
|
7748 | 7568 | sources."@xtuc/ieee754-1.2.0" |
|
7749 | 7569 | sources."@xtuc/long-4.2.1" |
@@ -7818,6 +7638,7 b' let' | |||
|
7818 | 7638 | }) |
|
7819 | 7639 | (sources."babel-core-6.26.3" // { |
|
7820 | 7640 | dependencies = [ |
|
7641 | sources."json5-0.5.1" | |
|
7821 | 7642 | sources."lodash-4.17.11" |
|
7822 | 7643 | sources."minimatch-3.0.4" |
|
7823 | 7644 | ]; |
@@ -7916,7 +7737,7 b' let' | |||
|
7916 | 7737 | }) |
|
7917 | 7738 | sources."base64-js-1.3.0" |
|
7918 | 7739 | sources."bcrypt-pbkdf-1.0.2" |
|
7919 |
sources."big.js- |
|
|
7740 | sources."big.js-5.2.2" | |
|
7920 | 7741 | sources."binary-extensions-1.12.0" |
|
7921 | 7742 | sources."bluebird-3.5.3" |
|
7922 | 7743 | sources."bn.js-4.11.8" |
@@ -7946,7 +7767,7 b' let' | |||
|
7946 | 7767 | sources."graceful-fs-4.1.15" |
|
7947 | 7768 | sources."lru-cache-4.1.5" |
|
7948 | 7769 | sources."minimatch-3.0.4" |
|
7949 |
sources."rimraf-2.6. |
|
|
7770 | sources."rimraf-2.6.3" | |
|
7950 | 7771 | ]; |
|
7951 | 7772 | }) |
|
7952 | 7773 | sources."cache-base-1.0.1" |
@@ -7957,8 +7778,8 b' let' | |||
|
7957 | 7778 | sources."browserslist-1.7.7" |
|
7958 | 7779 | ]; |
|
7959 | 7780 | }) |
|
7960 |
sources."caniuse-db-1.0.300009 |
|
|
7961 |
sources."caniuse-lite-1.0.300009 |
|
|
7781 | sources."caniuse-db-1.0.30000927" | |
|
7782 | sources."caniuse-lite-1.0.30000927" | |
|
7962 | 7783 | sources."caseless-0.12.0" |
|
7963 | 7784 | sources."center-align-0.1.3" |
|
7964 | 7785 | sources."chalk-0.5.1" |
@@ -8045,7 +7866,7 b' let' | |||
|
8045 | 7866 | dependencies = [ |
|
8046 | 7867 | sources."glob-7.1.3" |
|
8047 | 7868 | sources."minimatch-3.0.4" |
|
8048 |
sources."rimraf-2.6. |
|
|
7869 | sources."rimraf-2.6.3" | |
|
8049 | 7870 | ]; |
|
8050 | 7871 | }) |
|
8051 | 7872 | sources."copy-descriptor-0.1.1" |
@@ -8055,7 +7876,7 b' let' | |||
|
8055 | 7876 | sources."minimatch-3.0.4" |
|
8056 | 7877 | ]; |
|
8057 | 7878 | }) |
|
8058 |
sources."core-js-2. |
|
|
7879 | sources."core-js-2.6.1" | |
|
8059 | 7880 | sources."core-util-is-1.0.2" |
|
8060 | 7881 | sources."create-ecdh-4.0.3" |
|
8061 | 7882 | sources."create-hash-1.2.0" |
@@ -8079,7 +7900,6 b' let' | |||
|
8079 | 7900 | sources."cssesc-0.1.0" |
|
8080 | 7901 | sources."cssnano-3.10.0" |
|
8081 | 7902 | sources."csso-2.3.2" |
|
8082 | sources."cycle-1.0.3" | |
|
8083 | 7903 | sources."cyclist-0.2.2" |
|
8084 | 7904 | (sources."dashdash-1.14.1" // { |
|
8085 | 7905 | dependencies = [ |
@@ -8116,7 +7936,7 b' let' | |||
|
8116 | 7936 | ]; |
|
8117 | 7937 | }) |
|
8118 | 7938 | sources."domain-browser-1.2.0" |
|
8119 |
sources."domelementtype-1.3. |
|
|
7939 | sources."domelementtype-1.3.1" | |
|
8120 | 7940 | sources."domhandler-2.3.0" |
|
8121 | 7941 | sources."domutils-1.5.1" |
|
8122 | 7942 | (sources."duplexify-3.6.1" // { |
@@ -8126,7 +7946,7 b' let' | |||
|
8126 | 7946 | ]; |
|
8127 | 7947 | }) |
|
8128 | 7948 | sources."ecc-jsbn-0.1.2" |
|
8129 |
sources."electron-to-chromium-1.3.8 |
|
|
7949 | sources."electron-to-chromium-1.3.98" | |
|
8130 | 7950 | sources."elliptic-6.4.1" |
|
8131 | 7951 | sources."emojis-list-2.1.0" |
|
8132 | 7952 | sources."end-of-stream-1.4.1" |
@@ -8137,9 +7957,8 b' let' | |||
|
8137 | 7957 | }) |
|
8138 | 7958 | sources."entities-1.0.0" |
|
8139 | 7959 | sources."errno-0.1.7" |
|
8140 |
sources."es-abstract-1.1 |
|
|
7960 | sources."es-abstract-1.13.0" | |
|
8141 | 7961 | sources."es-to-primitive-1.2.0" |
|
8142 | sources."es6-promise-4.2.5" | |
|
8143 | 7962 | sources."es6-templates-0.2.3" |
|
8144 | 7963 | sources."escape-string-regexp-1.0.5" |
|
8145 | 7964 | sources."eslint-scope-4.0.0" |
@@ -8151,7 +7970,7 b' let' | |||
|
8151 | 7970 | sources."eventemitter2-0.4.14" |
|
8152 | 7971 | sources."events-1.1.1" |
|
8153 | 7972 | sources."evp_bytestokey-1.0.3" |
|
8154 |
sources."execa- |
|
|
7973 | sources."execa-1.0.0" | |
|
8155 | 7974 | sources."exit-0.1.2" |
|
8156 | 7975 | (sources."expand-brackets-2.1.4" // { |
|
8157 | 7976 | dependencies = [ |
@@ -8185,15 +8004,12 b' let' | |||
|
8185 | 8004 | sources."extend-shallow-2.0.1" |
|
8186 | 8005 | ]; |
|
8187 | 8006 | }) |
|
8188 | sources."extract-zip-1.6.7" | |
|
8189 | 8007 | sources."extsprintf-1.3.0" |
|
8190 | sources."eyes-0.1.8" | |
|
8191 | 8008 | sources."fast-deep-equal-2.0.1" |
|
8192 | 8009 | sources."fast-json-stable-stringify-2.0.0" |
|
8193 | 8010 | sources."fastparse-1.1.2" |
|
8194 | 8011 | sources."favico.js-0.3.10" |
|
8195 | 8012 | sources."faye-websocket-0.4.4" |
|
8196 | sources."fd-slicer-1.0.1" | |
|
8197 | 8013 | sources."file-sync-cmp-0.1.1" |
|
8198 | 8014 | (sources."fill-range-4.0.0" // { |
|
8199 | 8015 | dependencies = [ |
@@ -8209,8 +8025,8 b' let' | |||
|
8209 | 8025 | sources."minimatch-0.3.0" |
|
8210 | 8026 | ]; |
|
8211 | 8027 | }) |
|
8212 |
sources."fined-1.1. |
|
|
8213 |
sources."flagged-respawn-1.0. |
|
|
8028 | sources."fined-1.1.1" | |
|
8029 | sources."flagged-respawn-1.0.1" | |
|
8214 | 8030 | sources."flatten-1.0.2" |
|
8215 | 8031 | (sources."flush-write-stream-1.0.3" // { |
|
8216 | 8032 | dependencies = [ |
@@ -8229,11 +8045,6 b' let' | |||
|
8229 | 8045 | sources."string_decoder-1.1.1" |
|
8230 | 8046 | ]; |
|
8231 | 8047 | }) |
|
8232 | (sources."fs-extra-1.0.0" // { | |
|
8233 | dependencies = [ | |
|
8234 | sources."graceful-fs-4.1.15" | |
|
8235 | ]; | |
|
8236 | }) | |
|
8237 | 8048 | (sources."fs-write-stream-atomic-1.0.10" // { |
|
8238 | 8049 | dependencies = [ |
|
8239 | 8050 | sources."graceful-fs-4.1.15" |
@@ -8244,7 +8055,11 b' let' | |||
|
8244 | 8055 | sources."function-bind-1.1.1" |
|
8245 | 8056 | sources."gaze-0.5.2" |
|
8246 | 8057 | sources."get-caller-file-1.0.3" |
|
8247 |
sources."get-stream- |
|
|
8058 | (sources."get-stream-4.1.0" // { | |
|
8059 | dependencies = [ | |
|
8060 | sources."pump-3.0.0" | |
|
8061 | ]; | |
|
8062 | }) | |
|
8248 | 8063 | sources."get-value-2.0.6" |
|
8249 | 8064 | sources."getobject-0.1.0" |
|
8250 | 8065 | (sources."getpass-0.1.7" // { |
@@ -8259,7 +8074,7 b' let' | |||
|
8259 | 8074 | }) |
|
8260 | 8075 | sources."glob-parent-3.1.0" |
|
8261 | 8076 | sources."global-modules-1.0.0" |
|
8262 |
sources."global-modules-path-2.3. |
|
|
8077 | sources."global-modules-path-2.3.1" | |
|
8263 | 8078 | (sources."global-prefix-1.0.2" // { |
|
8264 | 8079 | dependencies = [ |
|
8265 | 8080 | sources."which-1.3.1" |
@@ -8351,8 +8166,7 b' let' | |||
|
8351 | 8166 | ]; |
|
8352 | 8167 | }) |
|
8353 | 8168 | sources."hash-base-3.0.4" |
|
8354 |
sources."hash.js-1.1. |
|
|
8355 | sources."hasha-2.2.0" | |
|
8169 | sources."hash.js-1.1.7" | |
|
8356 | 8170 | sources."hawk-3.1.3" |
|
8357 | 8171 | sources."he-1.2.0" |
|
8358 | 8172 | sources."hmac-drbg-1.0.1" |
@@ -8369,6 +8183,8 b' let' | |||
|
8369 | 8183 | }) |
|
8370 | 8184 | (sources."html-webpack-plugin-3.2.0" // { |
|
8371 | 8185 | dependencies = [ |
|
8186 | sources."big.js-3.2.0" | |
|
8187 | sources."json5-0.5.1" | |
|
8372 | 8188 | sources."loader-utils-0.2.17" |
|
8373 | 8189 | sources."lodash-4.17.11" |
|
8374 | 8190 | ]; |
@@ -8381,7 +8197,7 b' let' | |||
|
8381 | 8197 | (sources."icss-utils-2.1.0" // { |
|
8382 | 8198 | dependencies = [ |
|
8383 | 8199 | sources."ansi-styles-3.2.1" |
|
8384 |
sources."chalk-2.4. |
|
|
8200 | sources."chalk-2.4.2" | |
|
8385 | 8201 | sources."postcss-6.0.23" |
|
8386 | 8202 | sources."source-map-0.6.1" |
|
8387 | 8203 | sources."supports-color-5.5.0" |
@@ -8395,7 +8211,7 b' let' | |||
|
8395 | 8211 | dependencies = [ |
|
8396 | 8212 | sources."find-up-3.0.0" |
|
8397 | 8213 | sources."locate-path-3.0.0" |
|
8398 |
sources."p-limit-2. |
|
|
8214 | sources."p-limit-2.1.0" | |
|
8399 | 8215 | sources."p-locate-3.0.0" |
|
8400 | 8216 | sources."p-try-2.0.0" |
|
8401 | 8217 | sources."pkg-dir-3.0.0" |
@@ -8445,12 +8261,12 b' let' | |||
|
8445 | 8261 | sources."isobject-3.0.1" |
|
8446 | 8262 | sources."isstream-0.1.2" |
|
8447 | 8263 | sources."jquery-1.11.3" |
|
8448 |
sources."js-base64-2. |
|
|
8264 | sources."js-base64-2.5.0" | |
|
8449 | 8265 | sources."js-tokens-3.0.2" |
|
8450 | 8266 | sources."js-yaml-2.0.5" |
|
8451 | 8267 | sources."jsbn-0.1.1" |
|
8452 | 8268 | sources."jsesc-1.3.0" |
|
8453 |
(sources."jshint-2.9. |
|
|
8269 | (sources."jshint-2.9.7" // { | |
|
8454 | 8270 | dependencies = [ |
|
8455 | 8271 | sources."lodash-4.17.11" |
|
8456 | 8272 | sources."minimatch-3.0.4" |
@@ -8461,25 +8277,14 b' let' | |||
|
8461 | 8277 | sources."json-schema-traverse-0.4.1" |
|
8462 | 8278 | sources."json-stable-stringify-1.0.1" |
|
8463 | 8279 | sources."json-stringify-safe-5.0.1" |
|
8464 |
sources."json5-0 |
|
|
8465 | (sources."jsonfile-2.4.0" // { | |
|
8466 | dependencies = [ | |
|
8467 | sources."graceful-fs-4.1.15" | |
|
8468 | ]; | |
|
8469 | }) | |
|
8280 | sources."json5-1.0.1" | |
|
8470 | 8281 | sources."jsonify-0.0.0" |
|
8471 | 8282 | (sources."jsprim-1.4.1" // { |
|
8472 | 8283 | dependencies = [ |
|
8473 | 8284 | sources."assert-plus-1.0.0" |
|
8474 | 8285 | ]; |
|
8475 | 8286 | }) |
|
8476 | sources."kew-0.7.0" | |
|
8477 | 8287 | sources."kind-of-6.0.2" |
|
8478 | (sources."klaw-1.3.1" // { | |
|
8479 | dependencies = [ | |
|
8480 | sources."graceful-fs-4.1.15" | |
|
8481 | ]; | |
|
8482 | }) | |
|
8483 | 8288 | sources."lazy-cache-1.0.4" |
|
8484 | 8289 | sources."lcid-2.0.0" |
|
8485 | 8290 | (sources."less-2.7.3" // { |
@@ -8493,7 +8298,7 b' let' | |||
|
8493 | 8298 | ]; |
|
8494 | 8299 | }) |
|
8495 | 8300 | sources."loader-runner-2.3.1" |
|
8496 |
sources."loader-utils-1. |
|
|
8301 | sources."loader-utils-1.2.3" | |
|
8497 | 8302 | sources."locate-path-2.0.0" |
|
8498 | 8303 | sources."lodash-0.9.2" |
|
8499 | 8304 | sources."lodash.camelcase-4.3.0" |
@@ -8510,6 +8315,7 b' let' | |||
|
8510 | 8315 | sources."map-age-cleaner-0.1.3" |
|
8511 | 8316 | sources."map-cache-0.2.2" |
|
8512 | 8317 | sources."map-visit-1.0.0" |
|
8318 | sources."mark.js-8.11.1" | |
|
8513 | 8319 | sources."math-expression-evaluator-1.2.17" |
|
8514 | 8320 | sources."md5.js-1.3.5" |
|
8515 | 8321 | sources."mem-4.0.0" |
@@ -8528,25 +8334,29 b' let' | |||
|
8528 | 8334 | sources."minimalistic-assert-1.0.1" |
|
8529 | 8335 | sources."minimalistic-crypto-utils-1.0.1" |
|
8530 | 8336 | sources."minimatch-0.2.14" |
|
8531 |
sources."minimist- |
|
|
8337 | sources."minimist-1.2.0" | |
|
8532 | 8338 | sources."mississippi-2.0.0" |
|
8533 | 8339 | (sources."mixin-deep-1.3.1" // { |
|
8534 | 8340 | dependencies = [ |
|
8535 | 8341 | sources."is-extendable-1.0.1" |
|
8536 | 8342 | ]; |
|
8537 | 8343 | }) |
|
8538 | sources."mkdirp-0.5.1" | |
|
8539 | sources."moment-2.22.2" | |
|
8344 | (sources."mkdirp-0.5.1" // { | |
|
8345 | dependencies = [ | |
|
8346 | sources."minimist-0.0.8" | |
|
8347 | ]; | |
|
8348 | }) | |
|
8349 | sources."moment-2.23.0" | |
|
8540 | 8350 | sources."mousetrap-1.6.2" |
|
8541 | 8351 | (sources."move-concurrently-1.0.1" // { |
|
8542 | 8352 | dependencies = [ |
|
8543 | 8353 | sources."glob-7.1.3" |
|
8544 | 8354 | sources."minimatch-3.0.4" |
|
8545 |
sources."rimraf-2.6. |
|
|
8355 | sources."rimraf-2.6.3" | |
|
8546 | 8356 | ]; |
|
8547 | 8357 | }) |
|
8548 | 8358 | sources."ms-2.0.0" |
|
8549 |
sources."nan-2.1 |
|
|
8359 | sources."nan-2.12.1" | |
|
8550 | 8360 | sources."nanomatch-1.2.13" |
|
8551 | 8361 | sources."neo-async-2.6.0" |
|
8552 | 8362 | sources."nice-try-1.0.5" |
@@ -8598,7 +8408,7 b' let' | |||
|
8598 | 8408 | sources."once-1.4.0" |
|
8599 | 8409 | sources."os-browserify-0.3.0" |
|
8600 | 8410 | sources."os-homedir-1.0.2" |
|
8601 |
sources."os-locale-3.0 |
|
|
8411 | sources."os-locale-3.1.0" | |
|
8602 | 8412 | sources."os-tmpdir-1.0.2" |
|
8603 | 8413 | sources."osenv-0.1.5" |
|
8604 | 8414 | sources."p-defer-1.0.0" |
@@ -8635,22 +8445,13 b' let' | |||
|
8635 | 8445 | sources."path-root-regex-0.1.2" |
|
8636 | 8446 | sources."path-type-3.0.0" |
|
8637 | 8447 | sources."pbkdf2-3.0.17" |
|
8638 | sources."pend-1.2.0" | |
|
8639 | 8448 | sources."performance-now-0.2.0" |
|
8640 | sources."phantom-4.0.12" | |
|
8641 | (sources."phantomjs-prebuilt-2.1.16" // { | |
|
8642 | dependencies = [ | |
|
8643 | sources."which-1.3.1" | |
|
8644 | ]; | |
|
8645 | }) | |
|
8646 | 8449 | sources."pify-3.0.0" |
|
8647 | sources."pinkie-2.0.4" | |
|
8648 | sources."pinkie-promise-2.0.1" | |
|
8649 | 8450 | sources."pkg-dir-2.0.0" |
|
8650 | 8451 | (sources."polymer-webpack-loader-2.0.3" // { |
|
8651 | 8452 | dependencies = [ |
|
8652 | 8453 | sources."ansi-styles-3.2.1" |
|
8653 |
sources."chalk-2.4. |
|
|
8454 | sources."chalk-2.4.2" | |
|
8654 | 8455 | sources."html-loader-0.5.5" |
|
8655 | 8456 | (sources."postcss-6.0.23" // { |
|
8656 | 8457 | dependencies = [ |
@@ -8700,7 +8501,7 b' let' | |||
|
8700 | 8501 | (sources."postcss-modules-extract-imports-1.2.1" // { |
|
8701 | 8502 | dependencies = [ |
|
8702 | 8503 | sources."ansi-styles-3.2.1" |
|
8703 |
sources."chalk-2.4. |
|
|
8504 | sources."chalk-2.4.2" | |
|
8704 | 8505 | sources."postcss-6.0.23" |
|
8705 | 8506 | sources."source-map-0.6.1" |
|
8706 | 8507 | sources."supports-color-5.5.0" |
@@ -8709,7 +8510,7 b' let' | |||
|
8709 | 8510 | (sources."postcss-modules-local-by-default-1.2.0" // { |
|
8710 | 8511 | dependencies = [ |
|
8711 | 8512 | sources."ansi-styles-3.2.1" |
|
8712 |
sources."chalk-2.4. |
|
|
8513 | sources."chalk-2.4.2" | |
|
8713 | 8514 | sources."postcss-6.0.23" |
|
8714 | 8515 | sources."source-map-0.6.1" |
|
8715 | 8516 | sources."supports-color-5.5.0" |
@@ -8718,7 +8519,7 b' let' | |||
|
8718 | 8519 | (sources."postcss-modules-scope-1.1.0" // { |
|
8719 | 8520 | dependencies = [ |
|
8720 | 8521 | sources."ansi-styles-3.2.1" |
|
8721 |
sources."chalk-2.4. |
|
|
8522 | sources."chalk-2.4.2" | |
|
8722 | 8523 | sources."postcss-6.0.23" |
|
8723 | 8524 | sources."source-map-0.6.1" |
|
8724 | 8525 | sources."supports-color-5.5.0" |
@@ -8727,7 +8528,7 b' let' | |||
|
8727 | 8528 | (sources."postcss-modules-values-1.3.0" // { |
|
8728 | 8529 | dependencies = [ |
|
8729 | 8530 | sources."ansi-styles-3.2.1" |
|
8730 |
sources."chalk-2.4. |
|
|
8531 | sources."chalk-2.4.2" | |
|
8731 | 8532 | sources."postcss-6.0.23" |
|
8732 | 8533 | sources."source-map-0.6.1" |
|
8733 | 8534 | sources."supports-color-5.5.0" |
@@ -8749,7 +8550,6 b' let' | |||
|
8749 | 8550 | sources."private-0.1.8" |
|
8750 | 8551 | sources."process-0.11.10" |
|
8751 | 8552 | sources."process-nextick-args-2.0.0" |
|
8752 | sources."progress-1.1.8" | |
|
8753 | 8553 | sources."promise-7.3.1" |
|
8754 | 8554 | sources."promise-inflight-1.0.1" |
|
8755 | 8555 | sources."prr-1.0.1" |
@@ -8823,10 +8623,9 b' let' | |||
|
8823 | 8623 | sources."repeat-string-1.6.1" |
|
8824 | 8624 | sources."repeating-2.0.1" |
|
8825 | 8625 | sources."request-2.81.0" |
|
8826 | sources."request-progress-2.0.1" | |
|
8827 | 8626 | sources."require-directory-2.1.1" |
|
8828 | 8627 | sources."require-main-filename-1.0.1" |
|
8829 |
sources."resolve-1. |
|
|
8628 | sources."resolve-1.9.0" | |
|
8830 | 8629 | sources."resolve-cwd-2.0.0" |
|
8831 | 8630 | sources."resolve-dir-1.0.1" |
|
8832 | 8631 | sources."resolve-from-3.0.0" |
@@ -8842,12 +8641,12 b' let' | |||
|
8842 | 8641 | sources."sax-1.2.4" |
|
8843 | 8642 | (sources."schema-utils-0.4.7" // { |
|
8844 | 8643 | dependencies = [ |
|
8845 |
sources."ajv-6.6. |
|
|
8644 | sources."ajv-6.6.2" | |
|
8846 | 8645 | ]; |
|
8847 | 8646 | }) |
|
8848 | 8647 | sources."select-1.1.2" |
|
8849 | 8648 | sources."semver-5.6.0" |
|
8850 |
sources."serialize-javascript-1. |
|
|
8649 | sources."serialize-javascript-1.6.1" | |
|
8851 | 8650 | sources."set-blocking-2.0.0" |
|
8852 | 8651 | (sources."set-value-2.0.0" // { |
|
8853 | 8652 | dependencies = [ |
@@ -8897,16 +8696,14 b' let' | |||
|
8897 | 8696 | sources."source-map-resolve-0.5.2" |
|
8898 | 8697 | sources."source-map-support-0.4.18" |
|
8899 | 8698 | sources."source-map-url-0.4.0" |
|
8900 | sources."split-1.0.1" | |
|
8901 | 8699 | sources."split-string-3.1.0" |
|
8902 | 8700 | sources."sprintf-js-1.0.3" |
|
8903 |
(sources."sshpk-1.1 |
|
|
8701 | (sources."sshpk-1.16.0" // { | |
|
8904 | 8702 | dependencies = [ |
|
8905 | 8703 | sources."assert-plus-1.0.0" |
|
8906 | 8704 | ]; |
|
8907 | 8705 | }) |
|
8908 | 8706 | sources."ssri-5.3.0" |
|
8909 | sources."stack-trace-0.0.10" | |
|
8910 | 8707 | (sources."static-extend-0.1.2" // { |
|
8911 | 8708 | dependencies = [ |
|
8912 | 8709 | sources."define-property-0.2.5" |
@@ -8963,7 +8760,6 b' let' | |||
|
8963 | 8760 | ]; |
|
8964 | 8761 | }) |
|
8965 | 8762 | sources."tapable-1.1.1" |
|
8966 | sources."throttleit-1.0.0" | |
|
8967 | 8763 | sources."through-2.3.8" |
|
8968 | 8764 | (sources."through2-2.0.5" // { |
|
8969 | 8765 | dependencies = [ |
@@ -8993,9 +8789,11 b' let' | |||
|
8993 | 8789 | sources."trim-right-1.0.1" |
|
8994 | 8790 | (sources."ts-loader-1.3.3" // { |
|
8995 | 8791 | dependencies = [ |
|
8996 |
sources." |
|
|
8792 | sources."big.js-3.2.0" | |
|
8793 | sources."colors-1.3.3" | |
|
8997 | 8794 | sources."enhanced-resolve-3.4.1" |
|
8998 | 8795 | sources."graceful-fs-4.1.15" |
|
8796 | sources."json5-0.5.1" | |
|
8999 | 8797 | sources."loader-utils-0.2.17" |
|
9000 | 8798 | sources."tapable-0.2.9" |
|
9001 | 8799 | ]; |
@@ -9025,7 +8823,6 b' let' | |||
|
9025 | 8823 | sources."unc-path-regex-0.1.2" |
|
9026 | 8824 | sources."underscore-1.7.0" |
|
9027 | 8825 | sources."underscore.string-2.2.1" |
|
9028 | sources."unicode-5.2.0-0.7.5" | |
|
9029 | 8826 | (sources."union-value-1.0.0" // { |
|
9030 | 8827 | dependencies = [ |
|
9031 | 8828 | sources."extend-shallow-2.0.1" |
@@ -9066,7 +8863,7 b' let' | |||
|
9066 | 8863 | sources."utila-0.4.0" |
|
9067 | 8864 | sources."uuid-3.3.2" |
|
9068 | 8865 | sources."v8-compile-cache-2.0.2" |
|
9069 |
sources."v8flags-3.1. |
|
|
8866 | sources."v8flags-3.1.2" | |
|
9070 | 8867 | sources."vendors-1.0.2" |
|
9071 | 8868 | (sources."verror-1.10.0" // { |
|
9072 | 8869 | dependencies = [ |
@@ -9082,13 +8879,13 b' let' | |||
|
9082 | 8879 | sources."waypoints-4.0.1" |
|
9083 | 8880 | (sources."webpack-4.23.1" // { |
|
9084 | 8881 | dependencies = [ |
|
9085 |
sources."ajv-6.6. |
|
|
8882 | sources."ajv-6.6.2" | |
|
9086 | 8883 | ]; |
|
9087 | 8884 | }) |
|
9088 | 8885 | (sources."webpack-cli-3.1.2" // { |
|
9089 | 8886 | dependencies = [ |
|
9090 | 8887 | sources."ansi-styles-3.2.1" |
|
9091 |
sources."chalk-2.4. |
|
|
8888 | sources."chalk-2.4.2" | |
|
9092 | 8889 | sources."supports-color-5.5.0" |
|
9093 | 8890 | ]; |
|
9094 | 8891 | }) |
@@ -9121,12 +8918,6 b' let' | |||
|
9121 | 8918 | sources."which-1.0.9" |
|
9122 | 8919 | sources."which-module-2.0.0" |
|
9123 | 8920 | sources."window-size-0.1.0" |
|
9124 | (sources."winston-2.4.4" // { | |
|
9125 | dependencies = [ | |
|
9126 | sources."async-1.0.0" | |
|
9127 | sources."colors-1.0.3" | |
|
9128 | ]; | |
|
9129 | }) | |
|
9130 | 8921 | sources."wordwrap-0.0.2" |
|
9131 | 8922 | sources."worker-farm-1.6.0" |
|
9132 | 8923 | (sources."wrap-ansi-2.1.0" // { |
@@ -9144,13 +8935,12 b' let' | |||
|
9144 | 8935 | dependencies = [ |
|
9145 | 8936 | sources."find-up-3.0.0" |
|
9146 | 8937 | sources."locate-path-3.0.0" |
|
9147 |
sources."p-limit-2. |
|
|
8938 | sources."p-limit-2.1.0" | |
|
9148 | 8939 | sources."p-locate-3.0.0" |
|
9149 | 8940 | sources."p-try-2.0.0" |
|
9150 | 8941 | ]; |
|
9151 | 8942 | }) |
|
9152 | 8943 | sources."yargs-parser-11.1.1" |
|
9153 | sources."yauzl-2.4.1" | |
|
9154 | 8944 | ]; |
|
9155 | 8945 | buildInputs = globalBuildInputs; |
|
9156 | 8946 | meta = { |
@@ -219,11 +219,11 b' self: super: {' | |||
|
219 | 219 | }; |
|
220 | 220 | }; |
|
221 | 221 | "click" = super.buildPythonPackage { |
|
222 |
name = "click- |
|
|
222 | name = "click-7.0"; | |
|
223 | 223 | doCheck = false; |
|
224 | 224 | src = fetchurl { |
|
225 |
url = "https://files.pythonhosted.org/packages/7 |
|
|
226 | sha256 = "1sggipyz52crrybwbr9xvwxd4aqigvplf53k9w3ygxmzivd1jsnc"; | |
|
225 | url = "https://files.pythonhosted.org/packages/f8/5c/f60e9d8a1e77005f664b76ff8aeaee5bc05d0a91798afd7f53fc998dbc47/Click-7.0.tar.gz"; | |
|
226 | sha256 = "1mzjixd4vjbjvzb6vylki9w1556a9qmdh35kzmq6cign46av952v"; | |
|
227 | 227 | }; |
|
228 | 228 | meta = { |
|
229 | 229 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -260,11 +260,11 b' self: super: {' | |||
|
260 | 260 | }; |
|
261 | 261 | }; |
|
262 | 262 | "configparser" = super.buildPythonPackage { |
|
263 |
name = "configparser-3. |
|
|
263 | name = "configparser-3.7.1"; | |
|
264 | 264 | doCheck = false; |
|
265 | 265 | src = fetchurl { |
|
266 |
url = "https://files.pythonhosted.org/packages/7c |
|
|
267 | sha256 = "0fi7vf09vi1588jd8f16a021m5y6ih2hy7rpbjb408xw45qb822k"; | |
|
266 | url = "https://files.pythonhosted.org/packages/b6/a6/eceea7c5a5dbcf56815bed411c38cabd8a879386be10717b160e7362b5a2/configparser-3.7.1.tar.gz"; | |
|
267 | sha256 = "0cnz213il9lhgda6x70fw7mfqr8da43s3wm343lwzhqx94mgmmav"; | |
|
268 | 268 | }; |
|
269 | 269 | meta = { |
|
270 | 270 | license = [ pkgs.lib.licenses.mit ]; |
@@ -374,11 +374,14 b' self: super: {' | |||
|
374 | 374 | }; |
|
375 | 375 | }; |
|
376 | 376 | "dogpile.cache" = super.buildPythonPackage { |
|
377 |
name = "dogpile.cache-0. |
|
|
377 | name = "dogpile.cache-0.7.1"; | |
|
378 | 378 | doCheck = false; |
|
379 | propagatedBuildInputs = [ | |
|
380 | self."decorator" | |
|
381 | ]; | |
|
379 | 382 | src = fetchurl { |
|
380 |
url = "https://files.pythonhosted.org/packages/ |
|
|
381 | sha256 = "1aw8rx8vhb75y7zc6gi67g21sw057jdx7i8m3jq7kf3nqavxx9zw"; | |
|
383 | url = "https://files.pythonhosted.org/packages/84/3e/dbf1cfc5228f1d3dca80ef714db2c5aaec5cd9efaf54d7e3daef6bc48b19/dogpile.cache-0.7.1.tar.gz"; | |
|
384 | sha256 = "0caazmrzhnfqb5yrp8myhw61ny637jj69wcngrpbvi31jlcpy6v9"; | |
|
382 | 385 | }; |
|
383 | 386 | meta = { |
|
384 | 387 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -407,30 +410,75 b' self: super: {' | |||
|
407 | 410 | }; |
|
408 | 411 | }; |
|
409 | 412 | "elasticsearch" = super.buildPythonPackage { |
|
410 |
name = "elasticsearch- |
|
|
413 | name = "elasticsearch-6.3.1"; | |
|
411 | 414 | doCheck = false; |
|
412 | 415 | propagatedBuildInputs = [ |
|
413 | 416 | self."urllib3" |
|
414 | 417 | ]; |
|
415 | 418 | src = fetchurl { |
|
416 |
url = "https://files.pythonhosted.org/packages/10 |
|
|
417 | sha256 = "10ad2dk73xsys9vajwsncibs69asa63w1hgwz6lz1prjpyi80c5y"; | |
|
419 | url = "https://files.pythonhosted.org/packages/9d/ce/c4664e8380e379a9402ecfbaf158e56396da90d520daba21cfa840e0eb71/elasticsearch-6.3.1.tar.gz"; | |
|
420 | sha256 = "12y93v0yn7a4xmf969239g8gb3l4cdkclfpbk1qc8hx5qkymrnma"; | |
|
418 | 421 | }; |
|
419 | 422 | meta = { |
|
420 | 423 | license = [ pkgs.lib.licenses.asl20 ]; |
|
421 | 424 | }; |
|
422 | 425 | }; |
|
423 | 426 | "elasticsearch-dsl" = super.buildPythonPackage { |
|
424 |
name = "elasticsearch-dsl- |
|
|
427 | name = "elasticsearch-dsl-6.3.1"; | |
|
425 | 428 | doCheck = false; |
|
426 | 429 | propagatedBuildInputs = [ |
|
427 | 430 | self."six" |
|
428 | 431 | self."python-dateutil" |
|
429 | 432 | self."elasticsearch" |
|
433 | self."ipaddress" | |
|
434 | ]; | |
|
435 | src = fetchurl { | |
|
436 | url = "https://files.pythonhosted.org/packages/4c/0d/1549f50c591db6bb4e66cbcc8d34a6e537c3d89aa426b167c244fd46420a/elasticsearch-dsl-6.3.1.tar.gz"; | |
|
437 | sha256 = "1gh8a0shqi105k325hgwb9avrpdjh0mc6mxwfg9ba7g6lssb702z"; | |
|
438 | }; | |
|
439 | meta = { | |
|
440 | license = [ pkgs.lib.licenses.asl20 ]; | |
|
441 | }; | |
|
442 | }; | |
|
443 | "elasticsearch1" = super.buildPythonPackage { | |
|
444 | name = "elasticsearch1-1.10.0"; | |
|
445 | doCheck = false; | |
|
446 | propagatedBuildInputs = [ | |
|
447 | self."urllib3" | |
|
430 | 448 | ]; |
|
431 | 449 | src = fetchurl { |
|
432 |
url = "https://files.pythonhosted.org/packages/ |
|
|
433 | sha256 = "1g4kxzxsdwlsl2a9kscmx11pafgimhj7y8wrfksv8pgvpkfb9fwr"; | |
|
450 | url = "https://files.pythonhosted.org/packages/a6/eb/73e75f9681fa71e3157b8ee878534235d57f24ee64f0e77f8d995fb57076/elasticsearch1-1.10.0.tar.gz"; | |
|
451 | sha256 = "0g89444kd5zwql4vbvyrmi2m6l6dcj6ga98j4hqxyyyz6z20aki2"; | |
|
452 | }; | |
|
453 | meta = { | |
|
454 | license = [ pkgs.lib.licenses.asl20 ]; | |
|
455 | }; | |
|
456 | }; | |
|
457 | "elasticsearch1-dsl" = super.buildPythonPackage { | |
|
458 | name = "elasticsearch1-dsl-0.0.12"; | |
|
459 | doCheck = false; | |
|
460 | propagatedBuildInputs = [ | |
|
461 | self."six" | |
|
462 | self."python-dateutil" | |
|
463 | self."elasticsearch1" | |
|
464 | ]; | |
|
465 | src = fetchurl { | |
|
466 | url = "https://files.pythonhosted.org/packages/eb/9d/785342775cb10eddc9b8d7457d618a423b4f0b89d8b2b2d1bc27190d71db/elasticsearch1-dsl-0.0.12.tar.gz"; | |
|
467 | sha256 = "0ig1ly39v93hba0z975wnhbmzwj28w6w1sqlr2g7cn5spp732bhk"; | |
|
468 | }; | |
|
469 | meta = { | |
|
470 | license = [ pkgs.lib.licenses.asl20 ]; | |
|
471 | }; | |
|
472 | }; | |
|
473 | "elasticsearch2" = super.buildPythonPackage { | |
|
474 | name = "elasticsearch2-2.5.0"; | |
|
475 | doCheck = false; | |
|
476 | propagatedBuildInputs = [ | |
|
477 | self."urllib3" | |
|
478 | ]; | |
|
479 | src = fetchurl { | |
|
480 | url = "https://files.pythonhosted.org/packages/84/77/63cf63d4ba11d913b5278406f2a37b0712bec6fc85edfb6151a33eaeba25/elasticsearch2-2.5.0.tar.gz"; | |
|
481 | sha256 = "0ky0q16lbvz022yv6q3pix7aamf026p1y994537ccjf0p0dxnbxr"; | |
|
434 | 482 | }; |
|
435 | 483 | meta = { |
|
436 | 484 | license = [ pkgs.lib.licenses.asl20 ]; |
@@ -517,14 +565,14 b' self: super: {' | |||
|
517 | 565 | }; |
|
518 | 566 | }; |
|
519 | 567 | "gevent" = super.buildPythonPackage { |
|
520 |
name = "gevent-1. |
|
|
568 | name = "gevent-1.4.0"; | |
|
521 | 569 | doCheck = false; |
|
522 | 570 | propagatedBuildInputs = [ |
|
523 | 571 | self."greenlet" |
|
524 | 572 | ]; |
|
525 | 573 | src = fetchurl { |
|
526 |
url = "https://files.pythonhosted.org/packages/ |
|
|
527 | sha256 = "0b0fr04qdk1p4sniv87fh8z5psac60x01pv054kpgi94520g81iz"; | |
|
574 | url = "https://files.pythonhosted.org/packages/ed/27/6c49b70808f569b66ec7fac2e78f076e9b204db9cf5768740cff3d5a07ae/gevent-1.4.0.tar.gz"; | |
|
575 | sha256 = "1lchr4akw2jkm5v4kz7bdm4wv3knkfhbfn9vkkz4s5yrkcxzmdqy"; | |
|
528 | 576 | }; |
|
529 | 577 | meta = { |
|
530 | 578 | license = [ pkgs.lib.licenses.mit ]; |
@@ -673,11 +721,11 b' self: super: {' | |||
|
673 | 721 | }; |
|
674 | 722 | }; |
|
675 | 723 | "iso8601" = super.buildPythonPackage { |
|
676 |
name = "iso8601-0.1.1 |
|
|
724 | name = "iso8601-0.1.12"; | |
|
677 | 725 | doCheck = false; |
|
678 | 726 | src = fetchurl { |
|
679 |
url = "https://files.pythonhosted.org/packages/c0 |
|
|
680 | sha256 = "0c7gh3lsdjds262h0v1sqc66l7hqgfwbakn96qrhdbl0i3vm5yz8"; | |
|
727 | url = "https://files.pythonhosted.org/packages/45/13/3db24895497345fb44c4248c08b16da34a9eb02643cea2754b21b5ed08b0/iso8601-0.1.12.tar.gz"; | |
|
728 | sha256 = "10nyvvnrhw2w3p09v1ica4lgj6f4g9j3kkfx17qmraiq3w7b5i29"; | |
|
681 | 729 | }; |
|
682 | 730 | meta = { |
|
683 | 731 | license = [ pkgs.lib.licenses.mit ]; |
@@ -768,14 +816,14 b' self: super: {' | |||
|
768 | 816 | }; |
|
769 | 817 | }; |
|
770 | 818 | "kombu" = super.buildPythonPackage { |
|
771 |
name = "kombu-4.2. |
|
|
819 | name = "kombu-4.2.1"; | |
|
772 | 820 | doCheck = false; |
|
773 | 821 | propagatedBuildInputs = [ |
|
774 | 822 | self."amqp" |
|
775 | 823 | ]; |
|
776 | 824 | src = fetchurl { |
|
777 |
url = "https://files.pythonhosted.org/packages/ab |
|
|
778 | sha256 = "1yz19qlqf0inl1mnwlpq9j6kj9r67clpy0xg99phyg4329rw80fn"; | |
|
825 | url = "https://files.pythonhosted.org/packages/39/9f/556b988833abede4a80dbd18b2bdf4e8ff4486dd482ed45da961347e8ed2/kombu-4.2.1.tar.gz"; | |
|
826 | sha256 = "10lh3hncvw67fz0k5vgbx3yh9gjfpqdlia1f13i28cgnc1nfrbc6"; | |
|
779 | 827 | }; |
|
780 | 828 | meta = { |
|
781 | 829 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -818,11 +866,11 b' self: super: {' | |||
|
818 | 866 | }; |
|
819 | 867 | }; |
|
820 | 868 | "markupsafe" = super.buildPythonPackage { |
|
821 | name = "markupsafe-1.0"; | |
|
869 | name = "markupsafe-1.1.0"; | |
|
822 | 870 | doCheck = false; |
|
823 | 871 | src = fetchurl { |
|
824 |
url = "https://files.pythonhosted.org/packages/ |
|
|
825 | sha256 = "0rdn1s8x9ni7ss8rfiacj7x1085lx8mh2zdwqslnw8xc3l4nkgm6"; | |
|
872 | url = "https://files.pythonhosted.org/packages/ac/7e/1b4c2e05809a4414ebce0892fe1e32c14ace86ca7d50c70f00979ca9b3a3/MarkupSafe-1.1.0.tar.gz"; | |
|
873 | sha256 = "1lxirjypbdd3l9jl4vliilhfnhy7c7f2vlldqg1b0i74khn375sf"; | |
|
826 | 874 | }; |
|
827 | 875 | meta = { |
|
828 | 876 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -862,14 +910,14 b' self: super: {' | |||
|
862 | 910 | }; |
|
863 | 911 | }; |
|
864 | 912 | "more-itertools" = super.buildPythonPackage { |
|
865 |
name = "more-itertools- |
|
|
913 | name = "more-itertools-5.0.0"; | |
|
866 | 914 | doCheck = false; |
|
867 | 915 | propagatedBuildInputs = [ |
|
868 | 916 | self."six" |
|
869 | 917 | ]; |
|
870 | 918 | src = fetchurl { |
|
871 |
url = "https://files.pythonhosted.org/packages/88 |
|
|
872 | sha256 = "17h3na0rdh8xq30w4b9pizgkdxmm51896bxw600x84jflg9vaxn4"; | |
|
919 | url = "https://files.pythonhosted.org/packages/dd/26/30fc0d541d9fdf55faf5ba4b0fd68f81d5bd2447579224820ad525934178/more-itertools-5.0.0.tar.gz"; | |
|
920 | sha256 = "1r12cm6mcdwdzz7d47a6g4l437xsvapdlgyhqay3i2nrlv03da9q"; | |
|
873 | 921 | }; |
|
874 | 922 | meta = { |
|
875 | 923 | license = [ pkgs.lib.licenses.mit ]; |
@@ -960,32 +1008,32 b' self: super: {' | |||
|
960 | 1008 | }; |
|
961 | 1009 | }; |
|
962 | 1010 | "paste" = super.buildPythonPackage { |
|
963 |
name = "paste- |
|
|
1011 | name = "paste-3.0.5"; | |
|
964 | 1012 | doCheck = false; |
|
965 | 1013 | propagatedBuildInputs = [ |
|
966 | 1014 | self."six" |
|
967 | 1015 | ]; |
|
968 | 1016 | src = fetchurl { |
|
969 |
url = "https://files.pythonhosted.org/packages/3 |
|
|
970 | sha256 = "062jk0nlxf6lb2wwj6zc20rlvrwsnikpkh90y0dn8cjch93s6ii3"; | |
|
1017 | url = "https://files.pythonhosted.org/packages/d4/41/91bde422400786b1b06357c1e6e3a5379f54dc3002aeb337cb767233304e/Paste-3.0.5.tar.gz"; | |
|
1018 | sha256 = "1a6i8fh1fg8r4x800fvy9r82m15clwjim6yf2g9r4dff0y40dchv"; | |
|
971 | 1019 | }; |
|
972 | 1020 | meta = { |
|
973 | 1021 | license = [ pkgs.lib.licenses.mit ]; |
|
974 | 1022 | }; |
|
975 | 1023 | }; |
|
976 | 1024 | "pastedeploy" = super.buildPythonPackage { |
|
977 |
name = "pastedeploy-1 |
|
|
1025 | name = "pastedeploy-2.0.1"; | |
|
978 | 1026 | doCheck = false; |
|
979 | 1027 | src = fetchurl { |
|
980 |
url = "https://files.pythonhosted.org/packages/ |
|
|
981 | sha256 = "1jz3m4hq8v6hyhfjz9425nd3nvn52cvbfipdcd72krjmla4qz1fm"; | |
|
1028 | url = "https://files.pythonhosted.org/packages/19/a0/5623701df7e2478a68a1b685d1a84518024eef994cde7e4da8449a31616f/PasteDeploy-2.0.1.tar.gz"; | |
|
1029 | sha256 = "02imfbbx1mi2h546f3sr37m47dk9qizaqhzzlhx8bkzxa6fzn8yl"; | |
|
982 | 1030 | }; |
|
983 | 1031 | meta = { |
|
984 | 1032 | license = [ pkgs.lib.licenses.mit ]; |
|
985 | 1033 | }; |
|
986 | 1034 | }; |
|
987 | 1035 | "pastescript" = super.buildPythonPackage { |
|
988 |
name = "pastescript- |
|
|
1036 | name = "pastescript-3.0.0"; | |
|
989 | 1037 | doCheck = false; |
|
990 | 1038 | propagatedBuildInputs = [ |
|
991 | 1039 | self."paste" |
@@ -993,23 +1041,23 b' self: super: {' | |||
|
993 | 1041 | self."six" |
|
994 | 1042 | ]; |
|
995 | 1043 | src = fetchurl { |
|
996 | url = "https://files.pythonhosted.org/packages/e5/f0/78e766c3dcc61a4f3a6f71dd8c95168ae9c7a31722b5663d19c1fdf62cb6/PasteScript-2.0.2.tar.gz"; | |
|
997 | sha256 = "1h3nnhn45kf4pbcv669ik4faw04j58k8vbj1hwrc532k0nc28gy0"; | |
|
1044 | url = "https://files.pythonhosted.org/packages/08/2a/3797377a884ab9a064ad4d564ed612e54d26d7997caa8229c9c9df4eac31/PasteScript-3.0.0.tar.gz"; | |
|
1045 | sha256 = "1hvmyz1sbn7ws1syw567ph7km9fi0wi75r3vlyzx6sk0z26xkm6r"; | |
|
998 | 1046 | }; |
|
999 | 1047 | meta = { |
|
1000 | 1048 | license = [ pkgs.lib.licenses.mit ]; |
|
1001 | 1049 | }; |
|
1002 | 1050 | }; |
|
1003 | 1051 | "pathlib2" = super.buildPythonPackage { |
|
1004 |
name = "pathlib2-2.3. |
|
|
1052 | name = "pathlib2-2.3.3"; | |
|
1005 | 1053 | doCheck = false; |
|
1006 | 1054 | propagatedBuildInputs = [ |
|
1007 | 1055 | self."six" |
|
1008 | 1056 | self."scandir" |
|
1009 | 1057 | ]; |
|
1010 | 1058 | src = fetchurl { |
|
1011 |
url = "https://files.pythonhosted.org/packages/d |
|
|
1012 | sha256 = "10yb0iv5x2hs631rcppkhbddx799d3h8pcwmkbh2a66ns3w71ccf"; | |
|
1059 | url = "https://files.pythonhosted.org/packages/bf/d7/a2568f4596b75d2c6e2b4094a7e64f620decc7887f69a1f2811931ea15b9/pathlib2-2.3.3.tar.gz"; | |
|
1060 | sha256 = "0hpp92vqqgcd8h92msm9slv161b1q160igjwnkf2ag6cx0c96695"; | |
|
1013 | 1061 | }; |
|
1014 | 1062 | meta = { |
|
1015 | 1063 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1084,11 +1132,11 b' self: super: {' | |||
|
1084 | 1132 | }; |
|
1085 | 1133 | }; |
|
1086 | 1134 | "pluggy" = super.buildPythonPackage { |
|
1087 |
name = "pluggy-0.8. |
|
|
1135 | name = "pluggy-0.8.1"; | |
|
1088 | 1136 | doCheck = false; |
|
1089 | 1137 | src = fetchurl { |
|
1090 |
url = "https://files.pythonhosted.org/packages/ |
|
|
1091 | sha256 = "1580p47l2zqzsza8jcnw1h2wh3vvmygk6ly8bvi4w0g8j14sjys4"; | |
|
1138 | url = "https://files.pythonhosted.org/packages/38/e1/83b10c17688af7b2998fa5342fec58ecbd2a5a7499f31e606ae6640b71ac/pluggy-0.8.1.tar.gz"; | |
|
1139 | sha256 = "05l6g42p9ilmabw0hlbiyxy6gyzjri41m5l11a8dzgvi77q35p4d"; | |
|
1092 | 1140 | }; |
|
1093 | 1141 | meta = { |
|
1094 | 1142 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1110,11 +1158,11 b' self: super: {' | |||
|
1110 | 1158 | }; |
|
1111 | 1159 | }; |
|
1112 | 1160 | "psutil" = super.buildPythonPackage { |
|
1113 |
name = "psutil-5.4. |
|
|
1161 | name = "psutil-5.4.8"; | |
|
1114 | 1162 | doCheck = false; |
|
1115 | 1163 | src = fetchurl { |
|
1116 |
url = "https://files.pythonhosted.org/packages/7d |
|
|
1117 | sha256 = "0fsgmvzwbdbszkwfnqhib8jcxm4w6zyhvlxlcda0rfm5cyqj4qsv"; | |
|
1164 | url = "https://files.pythonhosted.org/packages/e3/58/0eae6e4466e5abf779d7e2b71fac7fba5f59e00ea36ddb3ed690419ccb0f/psutil-5.4.8.tar.gz"; | |
|
1165 | sha256 = "1hyna338sml2cl1mfb2gs89np18z27mvyhmq4ifh22x07n7mq9kf"; | |
|
1118 | 1166 | }; |
|
1119 | 1167 | meta = { |
|
1120 | 1168 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -1180,25 +1228,25 b' self: super: {' | |||
|
1180 | 1228 | }; |
|
1181 | 1229 | }; |
|
1182 | 1230 | "pyasn1" = super.buildPythonPackage { |
|
1183 |
name = "pyasn1-0.4. |
|
|
1231 | name = "pyasn1-0.4.5"; | |
|
1184 | 1232 | doCheck = false; |
|
1185 | 1233 | src = fetchurl { |
|
1186 | url = "https://files.pythonhosted.org/packages/10/46/059775dc8e50f722d205452bced4b3cc965d27e8c3389156acd3b1123ae3/pyasn1-0.4.4.tar.gz"; | |
|
1187 | sha256 = "0drilmx5j25aplfr5wrml0030cs5fgxp9yp94fhllxgx28yjm3zm"; | |
|
1234 | url = "https://files.pythonhosted.org/packages/46/60/b7e32f6ff481b8a1f6c8f02b0fd9b693d1c92ddd2efb038ec050d99a7245/pyasn1-0.4.5.tar.gz"; | |
|
1235 | sha256 = "1xqh3jh2nfi2bflk5a0vn59y3pp1vn54f3ksx652sid92gz2096s"; | |
|
1188 | 1236 | }; |
|
1189 | 1237 | meta = { |
|
1190 | 1238 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1191 | 1239 | }; |
|
1192 | 1240 | }; |
|
1193 | 1241 | "pyasn1-modules" = super.buildPythonPackage { |
|
1194 |
name = "pyasn1-modules-0.2. |
|
|
1242 | name = "pyasn1-modules-0.2.4"; | |
|
1195 | 1243 | doCheck = false; |
|
1196 | 1244 | propagatedBuildInputs = [ |
|
1197 | 1245 | self."pyasn1" |
|
1198 | 1246 | ]; |
|
1199 | 1247 | src = fetchurl { |
|
1200 |
url = "https://files.pythonhosted.org/packages/ |
|
|
1201 | sha256 = "0ivm850yi7ajjbi8j115qpsj95bgxdsx48nbjzg0zip788c3xkx0"; | |
|
1248 | url = "https://files.pythonhosted.org/packages/bd/a5/ef7bf693e8a8f015386c9167483199f54f8a8ec01d1c737e05524f16e792/pyasn1-modules-0.2.4.tar.gz"; | |
|
1249 | sha256 = "0z3w5dqrrvdplg9ma45j8n23xvyrj9ki8mg4ibqbn7l4qpl90855"; | |
|
1202 | 1250 | }; |
|
1203 | 1251 | meta = { |
|
1204 | 1252 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -1238,30 +1286,16 b' self: super: {' | |||
|
1238 | 1286 | }; |
|
1239 | 1287 | }; |
|
1240 | 1288 | "pygments" = super.buildPythonPackage { |
|
1241 |
name = "pygments-2.3. |
|
|
1289 | name = "pygments-2.3.1"; | |
|
1242 | 1290 | doCheck = false; |
|
1243 | 1291 | src = fetchurl { |
|
1244 |
url = "https://files.pythonhosted.org/packages/63 |
|
|
1245 | sha256 = "1z34ms51dh4jq4h3cizp7vd1dmsxcbvffkjsd2xxfav22nn6lrl2"; | |
|
1292 | url = "https://files.pythonhosted.org/packages/64/69/413708eaf3a64a6abb8972644e0f20891a55e621c6759e2c3f3891e05d63/Pygments-2.3.1.tar.gz"; | |
|
1293 | sha256 = "0ji87g09jph8jqcvclgb02qvxasdnr9pzvk90rl66d90yqcxmyjz"; | |
|
1246 | 1294 | }; |
|
1247 | 1295 | meta = { |
|
1248 | 1296 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1249 | 1297 | }; |
|
1250 | 1298 | }; |
|
1251 | "pygments-markdown-lexer" = super.buildPythonPackage { | |
|
1252 | name = "pygments-markdown-lexer-0.1.0.dev39"; | |
|
1253 | doCheck = false; | |
|
1254 | propagatedBuildInputs = [ | |
|
1255 | self."pygments" | |
|
1256 | ]; | |
|
1257 | src = fetchurl { | |
|
1258 | url = "https://files.pythonhosted.org/packages/c3/12/674cdee66635d638cedb2c5d9c85ce507b7b2f91bdba29e482f1b1160ff6/pygments-markdown-lexer-0.1.0.dev39.zip"; | |
|
1259 | sha256 = "1pzb5wy23q3fhs0rqzasjnw6hdzwjngpakb73i98cn0b8lk8q4jc"; | |
|
1260 | }; | |
|
1261 | meta = { | |
|
1262 | license = [ pkgs.lib.licenses.asl20 ]; | |
|
1263 | }; | |
|
1264 | }; | |
|
1265 | 1299 | "pymysql" = super.buildPythonPackage { |
|
1266 | 1300 | name = "pymysql-0.8.1"; |
|
1267 | 1301 | doCheck = false; |
@@ -1285,35 +1319,34 b' self: super: {' | |||
|
1285 | 1319 | }; |
|
1286 | 1320 | }; |
|
1287 | 1321 | "pyparsing" = super.buildPythonPackage { |
|
1288 |
name = "pyparsing- |
|
|
1322 | name = "pyparsing-2.3.0"; | |
|
1289 | 1323 | doCheck = false; |
|
1290 | 1324 | src = fetchurl { |
|
1291 | url = "https://files.pythonhosted.org/packages/6f/2c/47457771c02a8ff0f302b695e094ec309e30452232bd79198ee94fda689f/pyparsing-1.5.7.tar.gz"; | |
|
1292 | sha256 = "17z7ws076z977sclj628fvwrp8y9j2rvdjcsq42v129n1gwi8vk4"; | |
|
1325 | url = "https://files.pythonhosted.org/packages/d0/09/3e6a5eeb6e04467b737d55f8bba15247ac0876f98fae659e58cd744430c6/pyparsing-2.3.0.tar.gz"; | |
|
1326 | sha256 = "14k5v7n3xqw8kzf42x06bzp184spnlkya2dpjyflax6l3yrallzk"; | |
|
1293 | 1327 | }; |
|
1294 | 1328 | meta = { |
|
1295 | 1329 | license = [ pkgs.lib.licenses.mit ]; |
|
1296 | 1330 | }; |
|
1297 | 1331 | }; |
|
1298 | 1332 | "pyramid" = super.buildPythonPackage { |
|
1299 |
name = "pyramid-1. |
|
|
1333 | name = "pyramid-1.10.1"; | |
|
1300 | 1334 | doCheck = false; |
|
1301 | 1335 | propagatedBuildInputs = [ |
|
1302 |
self." |
|
|
1303 | self."webob" | |
|
1304 | self."repoze.lru" | |
|
1305 | self."zope.interface" | |
|
1306 | self."zope.deprecation" | |
|
1307 | self."venusian" | |
|
1308 | self."translationstring" | |
|
1309 | self."pastedeploy" | |
|
1336 | self."hupper" | |
|
1310 | 1337 | self."plaster" |
|
1311 | 1338 | self."plaster-pastedeploy" |
|
1312 |
self." |
|
|
1339 | self."setuptools" | |
|
1340 | self."translationstring" | |
|
1341 | self."venusian" | |
|
1342 | self."webob" | |
|
1343 | self."zope.deprecation" | |
|
1344 | self."zope.interface" | |
|
1345 | self."repoze.lru" | |
|
1313 | 1346 | ]; |
|
1314 | 1347 | src = fetchurl { |
|
1315 |
url = "https://files.pythonhosted.org/packages/a0 |
|
|
1316 | sha256 = "09drsl0346nchgxp2j7sa5hlk7mkhfld9wvbd0wicacrp26a92fg"; | |
|
1348 | url = "https://files.pythonhosted.org/packages/0a/3e/22e3ac9be1b70a01139adba8906ee4b8f628bb469fea3c52f6c97b73063c/pyramid-1.10.1.tar.gz"; | |
|
1349 | sha256 = "1h5105nfh6rsrfjiyw20aavyibj36la3hajy6vh1fa77xb4y3hrp"; | |
|
1317 | 1350 | }; |
|
1318 | 1351 | meta = { |
|
1319 | 1352 | license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
@@ -1335,7 +1368,7 b' self: super: {' | |||
|
1335 | 1368 | }; |
|
1336 | 1369 | }; |
|
1337 | 1370 | "pyramid-debugtoolbar" = super.buildPythonPackage { |
|
1338 |
name = "pyramid-debugtoolbar-4. |
|
|
1371 | name = "pyramid-debugtoolbar-4.5"; | |
|
1339 | 1372 | doCheck = false; |
|
1340 | 1373 | propagatedBuildInputs = [ |
|
1341 | 1374 | self."pyramid" |
@@ -1345,8 +1378,8 b' self: super: {' | |||
|
1345 | 1378 | self."ipaddress" |
|
1346 | 1379 | ]; |
|
1347 | 1380 | src = fetchurl { |
|
1348 |
url = "https://files.pythonhosted.org/packages/ |
|
|
1349 | sha256 = "17p7nxvapvy2hab1rah3ndq2kbs4v83pixj8x2n4m7008ai9lxsz"; | |
|
1381 | url = "https://files.pythonhosted.org/packages/14/28/1f240239af340d19ee271ac62958158c79edb01a44ad8c9885508dd003d2/pyramid_debugtoolbar-4.5.tar.gz"; | |
|
1382 | sha256 = "0x2p3409pnx66n6dx5vc0mk2r1cp1ydr8mp120w44r9pwcngbibl"; | |
|
1350 | 1383 | }; |
|
1351 | 1384 | meta = { |
|
1352 | 1385 | license = [ { fullName = "Repoze Public License"; } pkgs.lib.licenses.bsdOriginal ]; |
@@ -1519,11 +1552,11 b' self: super: {' | |||
|
1519 | 1552 | }; |
|
1520 | 1553 | }; |
|
1521 | 1554 | "python-editor" = super.buildPythonPackage { |
|
1522 |
name = "python-editor-1.0. |
|
|
1555 | name = "python-editor-1.0.4"; | |
|
1523 | 1556 | doCheck = false; |
|
1524 | 1557 | src = fetchurl { |
|
1525 |
url = "https://files.pythonhosted.org/packages/ |
|
|
1526 | sha256 = "0rf5xz8vw93v7mhdcvind7fkykipzga430wkcd7wk892xsn6dh53"; | |
|
1558 | url = "https://files.pythonhosted.org/packages/0a/85/78f4a216d28343a67b7397c99825cff336330893f00601443f7c7b2f2234/python-editor-1.0.4.tar.gz"; | |
|
1559 | sha256 = "0yrjh8w72ivqxi4i7xsg5b1vz15x8fg51xra7c3bgfyxqnyadzai"; | |
|
1527 | 1560 | }; |
|
1528 | 1561 | meta = { |
|
1529 | 1562 | license = [ pkgs.lib.licenses.asl20 { fullName = "Apache"; } ]; |
@@ -1657,7 +1690,7 b' self: super: {' | |||
|
1657 | 1690 | }; |
|
1658 | 1691 | }; |
|
1659 | 1692 | "rhodecode-enterprise-ce" = super.buildPythonPackage { |
|
1660 |
name = "rhodecode-enterprise-ce-4.1 |
|
|
1693 | name = "rhodecode-enterprise-ce-4.16.0"; | |
|
1661 | 1694 | buildInputs = [ |
|
1662 | 1695 | self."pytest" |
|
1663 | 1696 | self."py" |
@@ -1668,9 +1701,10 b' self: super: {' | |||
|
1668 | 1701 | self."pytest-timeout" |
|
1669 | 1702 | self."gprof2dot" |
|
1670 | 1703 | self."mock" |
|
1671 | self."webtest" | |
|
1672 | 1704 | self."cov-core" |
|
1673 | 1705 | self."coverage" |
|
1706 | self."webtest" | |
|
1707 | self."beautifulsoup4" | |
|
1674 | 1708 | self."configobj" |
|
1675 | 1709 | ]; |
|
1676 | 1710 | doCheck = true; |
@@ -1723,7 +1757,6 b' self: super: {' | |||
|
1723 | 1757 | self."pycrypto" |
|
1724 | 1758 | self."pycurl" |
|
1725 | 1759 | self."pyflakes" |
|
1726 | self."pygments-markdown-lexer" | |
|
1727 | 1760 | self."pygments" |
|
1728 | 1761 | self."pyparsing" |
|
1729 | 1762 | self."pyramid-beaker" |
@@ -1794,9 +1827,10 b' self: super: {' | |||
|
1794 | 1827 | self."pytest-timeout" |
|
1795 | 1828 | self."gprof2dot" |
|
1796 | 1829 | self."mock" |
|
1797 | self."webtest" | |
|
1798 | 1830 | self."cov-core" |
|
1799 | 1831 | self."coverage" |
|
1832 | self."webtest" | |
|
1833 | self."beautifulsoup4" | |
|
1800 | 1834 | ]; |
|
1801 | 1835 | src = ./.; |
|
1802 | 1836 | meta = { |
@@ -1804,7 +1838,7 b' self: super: {' | |||
|
1804 | 1838 | }; |
|
1805 | 1839 | }; |
|
1806 | 1840 | "rhodecode-tools" = super.buildPythonPackage { |
|
1807 |
name = "rhodecode-tools-1. |
|
|
1841 | name = "rhodecode-tools-1.2.1"; | |
|
1808 | 1842 | doCheck = false; |
|
1809 | 1843 | propagatedBuildInputs = [ |
|
1810 | 1844 | self."click" |
@@ -1813,14 +1847,16 b' self: super: {' | |||
|
1813 | 1847 | self."mako" |
|
1814 | 1848 | self."markupsafe" |
|
1815 | 1849 | self."requests" |
|
1816 | self."elasticsearch" | |
|
1817 | self."elasticsearch-dsl" | |
|
1818 | 1850 | self."urllib3" |
|
1819 | 1851 | self."whoosh" |
|
1852 | self."elasticsearch" | |
|
1853 | self."elasticsearch-dsl" | |
|
1854 | self."elasticsearch2" | |
|
1855 | self."elasticsearch1-dsl" | |
|
1820 | 1856 | ]; |
|
1821 | 1857 | src = fetchurl { |
|
1822 |
url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v1. |
|
|
1823 | sha256 = "0nr300s4sg685qs4wgbwlplwriawrwi6jq79z37frcnpyc89gpvm"; | |
|
1858 | url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v1.2.1.tar.gz?md5=25bc2f7de1da318e547236d3fb463d28"; | |
|
1859 | sha256 = "1k8l3s4mvshza1zay6dfxprq54fyb5dc85dqdva9wa3f466y0adk"; | |
|
1824 | 1860 | }; |
|
1825 | 1861 | meta = { |
|
1826 | 1862 | license = [ { fullName = "Apache 2.0 and Proprietary"; } ]; |
@@ -1864,11 +1900,11 b' self: super: {' | |||
|
1864 | 1900 | }; |
|
1865 | 1901 | }; |
|
1866 | 1902 | "setuptools" = super.buildPythonPackage { |
|
1867 |
name = "setuptools-40. |
|
|
1903 | name = "setuptools-40.8.0"; | |
|
1868 | 1904 | doCheck = false; |
|
1869 | 1905 | src = fetchurl { |
|
1870 | url = "https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip"; | |
|
1871 | sha256 = "0r2c5hapirlzm34h7pl1lgkm6gk7bcrlrdj28qgsvaqg3f74vfw6"; | |
|
1906 | url = "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip"; | |
|
1907 | sha256 = "0k9hifpgahnw2a26w3cr346iy733k6d3nwh3f7g9m13y6f8fqkkf"; | |
|
1872 | 1908 | }; |
|
1873 | 1909 | meta = { |
|
1874 | 1910 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1897,11 +1933,11 b' self: super: {' | |||
|
1897 | 1933 | }; |
|
1898 | 1934 | }; |
|
1899 | 1935 | "simplejson" = super.buildPythonPackage { |
|
1900 |
name = "simplejson-3.1 |
|
|
1936 | name = "simplejson-3.16.0"; | |
|
1901 | 1937 | doCheck = false; |
|
1902 | 1938 | src = fetchurl { |
|
1903 |
url = "https://files.pythonhosted.org/packages/08 |
|
|
1904 | sha256 = "1rr58dppsq73p0qcd9bsw066cdd3v63sqv7j6sqni8frvm4jv8h1"; | |
|
1939 | url = "https://files.pythonhosted.org/packages/e3/24/c35fb1c1c315fc0fffe61ea00d3f88e85469004713dab488dee4f35b0aff/simplejson-3.16.0.tar.gz"; | |
|
1940 | sha256 = "19cws1syk8jzq2pw43878dv6fjkb0ifvjpx0i9aajix6kc9jkwxi"; | |
|
1905 | 1941 | }; |
|
1906 | 1942 | meta = { |
|
1907 | 1943 | license = [ { fullName = "Academic Free License (AFL)"; } pkgs.lib.licenses.mit ]; |
@@ -1945,25 +1981,25 b' self: super: {' | |||
|
1945 | 1981 | }; |
|
1946 | 1982 | }; |
|
1947 | 1983 | "subprocess32" = super.buildPythonPackage { |
|
1948 |
name = "subprocess32-3.5. |
|
|
1984 | name = "subprocess32-3.5.3"; | |
|
1949 | 1985 | doCheck = false; |
|
1950 | 1986 | src = fetchurl { |
|
1951 |
url = "https://files.pythonhosted.org/packages/c |
|
|
1952 | sha256 = "11v62shwmdys48g7ncs3a8jwwnkcl8d4zcwy6dk73z1zy2f9hazb"; | |
|
1987 | url = "https://files.pythonhosted.org/packages/be/2b/beeba583e9877e64db10b52a96915afc0feabf7144dcbf2a0d0ea68bf73d/subprocess32-3.5.3.tar.gz"; | |
|
1988 | sha256 = "1hr5fan8i719hmlmz73hf8rhq74014w07d8ryg7krvvf6692kj3b"; | |
|
1953 | 1989 | }; |
|
1954 | 1990 | meta = { |
|
1955 | 1991 | license = [ pkgs.lib.licenses.psfl ]; |
|
1956 | 1992 | }; |
|
1957 | 1993 | }; |
|
1958 | 1994 | "supervisor" = super.buildPythonPackage { |
|
1959 |
name = "supervisor-3.3. |
|
|
1995 | name = "supervisor-3.3.5"; | |
|
1960 | 1996 | doCheck = false; |
|
1961 | 1997 | propagatedBuildInputs = [ |
|
1962 | 1998 | self."meld3" |
|
1963 | 1999 | ]; |
|
1964 | 2000 | src = fetchurl { |
|
1965 |
url = "https://files.pythonhosted.org/packages/ |
|
|
1966 | sha256 = "0wp62z9xprvz2krg02xnbwcnq6pxfq3byd8cxx8c2d8xznih28i1"; | |
|
2001 | url = "https://files.pythonhosted.org/packages/ba/65/92575a8757ed576beaee59251f64a3287bde82bdc03964b89df9e1d29e1b/supervisor-3.3.5.tar.gz"; | |
|
2002 | sha256 = "1w3ahridzbc6rxfpbyx8lij6pjlcgf2ymzyg53llkjqxalp6sk8v"; | |
|
1967 | 2003 | }; |
|
1968 | 2004 | meta = { |
|
1969 | 2005 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
@@ -2059,11 +2095,11 b' self: super: {' | |||
|
2059 | 2095 | }; |
|
2060 | 2096 | }; |
|
2061 | 2097 | "urllib3" = super.buildPythonPackage { |
|
2062 | name = "urllib3-1.21"; | |
|
2098 | name = "urllib3-1.24.1"; | |
|
2063 | 2099 | doCheck = false; |
|
2064 | 2100 | src = fetchurl { |
|
2065 |
url = "https://files.pythonhosted.org/packages/3 |
|
|
2066 | sha256 = "0irnj4wvh2y36s4q3l2vas9qr9m766w6w418nb490j3mf8a8zw6h"; | |
|
2101 | url = "https://files.pythonhosted.org/packages/b1/53/37d82ab391393565f2f831b8eedbffd57db5a718216f82f1a8b4d381a1c1/urllib3-1.24.1.tar.gz"; | |
|
2102 | sha256 = "08lwd9f3hqznyf32vnzwvp87pchx062nkbgyrf67rwlkgj0jk5fy"; | |
|
2067 | 2103 | }; |
|
2068 | 2104 | meta = { |
|
2069 | 2105 | license = [ pkgs.lib.licenses.mit ]; |
@@ -2081,22 +2117,22 b' self: super: {' | |||
|
2081 | 2117 | }; |
|
2082 | 2118 | }; |
|
2083 | 2119 | "venusian" = super.buildPythonPackage { |
|
2084 |
name = "venusian-1. |
|
|
2120 | name = "venusian-1.2.0"; | |
|
2085 | 2121 | doCheck = false; |
|
2086 | 2122 | src = fetchurl { |
|
2087 |
url = "https://files.pythonhosted.org/packages/ |
|
|
2088 | sha256 = "0zapz131686qm0gazwy8bh11vr57pr89jbwbl50s528sqy9f80lr"; | |
|
2123 | url = "https://files.pythonhosted.org/packages/7e/6f/40a9d43ac77cb51cb62be5b5662d170f43f8037bdc4eab56336c4ca92bb7/venusian-1.2.0.tar.gz"; | |
|
2124 | sha256 = "0ghyx66g8ikx9nx1mnwqvdcqm11i1vlq0hnvwl50s48bp22q5v34"; | |
|
2089 | 2125 | }; |
|
2090 | 2126 | meta = { |
|
2091 | 2127 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
2092 | 2128 | }; |
|
2093 | 2129 | }; |
|
2094 | 2130 | "vine" = super.buildPythonPackage { |
|
2095 |
name = "vine-1. |
|
|
2131 | name = "vine-1.2.0"; | |
|
2096 | 2132 | doCheck = false; |
|
2097 | 2133 | src = fetchurl { |
|
2098 |
url = "https://files.pythonhosted.org/packages/3 |
|
|
2099 | sha256 = "0wkskb2hb494v9gixqnf4bl972p4ibcmxdykzpwjlfa5picns4aj"; | |
|
2134 | url = "https://files.pythonhosted.org/packages/46/1a/c94317efa98040c5d50fe3cf9080cafb0372ff5afb0283dc018c751c6746/vine-1.2.0.tar.gz"; | |
|
2135 | sha256 = "0xjz2sjbr5jrpjk411b7alkghdskhphgsqqrbi7abqfh2pli6j7f"; | |
|
2100 | 2136 | }; |
|
2101 | 2137 | meta = { |
|
2102 | 2138 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -2182,18 +2218,18 b' self: super: {' | |||
|
2182 | 2218 | }; |
|
2183 | 2219 | }; |
|
2184 | 2220 | "webob" = super.buildPythonPackage { |
|
2185 |
name = "webob-1. |
|
|
2221 | name = "webob-1.8.4"; | |
|
2186 | 2222 | doCheck = false; |
|
2187 | 2223 | src = fetchurl { |
|
2188 |
url = "https://files.pythonhosted.org/packages/ |
|
|
2189 | sha256 = "1na01ljg04z40il7vcrn8g29vaw7nvg1xvhk64cr4jys5wcay44d"; | |
|
2224 | url = "https://files.pythonhosted.org/packages/e4/6c/99e322c3d4cc11d9060a67a9bf2f7c9c581f40988c11fffe89bb8c36bc5e/WebOb-1.8.4.tar.gz"; | |
|
2225 | sha256 = "16cfg5y4n6sihz59vsmns2yqbfm0gfsn3l5xgz2g0pdhilaib0x4"; | |
|
2190 | 2226 | }; |
|
2191 | 2227 | meta = { |
|
2192 | 2228 | license = [ pkgs.lib.licenses.mit ]; |
|
2193 | 2229 | }; |
|
2194 | 2230 | }; |
|
2195 | 2231 | "webtest" = super.buildPythonPackage { |
|
2196 |
name = "webtest-2.0.2 |
|
|
2232 | name = "webtest-2.0.32"; | |
|
2197 | 2233 | doCheck = false; |
|
2198 | 2234 | propagatedBuildInputs = [ |
|
2199 | 2235 | self."six" |
@@ -2202,8 +2238,8 b' self: super: {' | |||
|
2202 | 2238 | self."beautifulsoup4" |
|
2203 | 2239 | ]; |
|
2204 | 2240 | src = fetchurl { |
|
2205 |
url = "https://files.pythonhosted.org/packages/94 |
|
|
2206 | sha256 = "0bcj1ica5lnmj5zbvk46x28kgphcsgh7sfnwjmn0cr94mhawrg6v"; | |
|
2241 | url = "https://files.pythonhosted.org/packages/27/9f/9e74449d272ffbef4fb3012e6dbc53c0b24822d545e7a33a342f80131e59/WebTest-2.0.32.tar.gz"; | |
|
2242 | sha256 = "0qp0nnbazzm4ibjiyqfcn6f230svk09i4g58zg2i9x1ga06h48a2"; | |
|
2207 | 2243 | }; |
|
2208 | 2244 | meta = { |
|
2209 | 2245 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1,12 +1,15 b'' | |||
|
1 | 1 | # This file defines how to "build" for packaging. |
|
2 | 2 | |
|
3 | { doCheck ? false | |
|
3 | { pkgs ? import <nixpkgs> {} | |
|
4 | , system ? builtins.currentSystem | |
|
5 | , doCheck ? false | |
|
4 | 6 | }: |
|
5 | 7 | |
|
6 | 8 | let |
|
7 | 9 | enterprise_ce = import ./default.nix { |
|
8 | 10 | inherit |
|
9 |
doCheck |
|
|
11 | doCheck | |
|
12 | system; | |
|
10 | 13 | |
|
11 | 14 | # disable checkPhase for build |
|
12 | 15 | checkPhase = '' |
@@ -12,7 +12,7 b' bleach==3.0.2' | |||
|
12 | 12 | celery==4.1.1 |
|
13 | 13 | chameleon==2.24 |
|
14 | 14 | channelstream==0.5.2 |
|
15 |
click== |
|
|
15 | click==7.0 | |
|
16 | 16 | colander==1.5.1 |
|
17 | 17 | # our custom configobj |
|
18 | 18 | https://code.rhodecode.com/upstream/configobj/archive/a11ff0a0bd4fbda9e3a91267e720f88329efb4a6.tar.gz?md5=9916c524ea11a6c418217af6b28d4b3c#egg=configobj==5.0.6 |
@@ -20,7 +20,7 b' cssselect==1.0.3' | |||
|
20 | 20 | decorator==4.1.2 |
|
21 | 21 | deform==2.0.7 |
|
22 | 22 | docutils==0.14.0 |
|
23 |
dogpile.cache==0. |
|
|
23 | dogpile.cache==0.7.1 | |
|
24 | 24 | dogpile.core==0.4.1 |
|
25 | 25 | ecdsa==0.13 |
|
26 | 26 | formencode==1.2.4 |
@@ -28,42 +28,41 b' future==0.14.3' | |||
|
28 | 28 | futures==3.0.2 |
|
29 | 29 | gnureadline==6.3.8 |
|
30 | 30 | infrae.cache==1.0.1 |
|
31 |
iso8601==0.1.1 |
|
|
31 | iso8601==0.1.12 | |
|
32 | 32 | itsdangerous==0.24 |
|
33 | 33 | jinja2==2.9.6 |
|
34 | 34 | billiard==3.5.0.3 |
|
35 |
kombu==4.2. |
|
|
35 | kombu==4.2.1 | |
|
36 | 36 | lxml==4.2.5 |
|
37 | 37 | mako==1.0.7 |
|
38 | 38 | markdown==2.6.11 |
|
39 |
markupsafe==1. |
|
|
39 | markupsafe==1.1.0 | |
|
40 | 40 | msgpack-python==0.5.6 |
|
41 | 41 | pyotp==2.2.7 |
|
42 | 42 | packaging==15.2 |
|
43 |
paste== |
|
|
44 |
pastedeploy== |
|
|
45 |
pastescript== |
|
|
46 |
pathlib2==2.3. |
|
|
43 | paste==3.0.5 | |
|
44 | pastedeploy==2.0.1 | |
|
45 | pastescript==3.0.0 | |
|
46 | pathlib2==2.3.3 | |
|
47 | 47 | peppercorn==0.6 |
|
48 |
psutil==5.4. |
|
|
48 | psutil==5.4.8 | |
|
49 | 49 | py-bcrypt==0.4 |
|
50 | 50 | pycrypto==2.6.1 |
|
51 | 51 | pycurl==7.43.0.2 |
|
52 | 52 | pyflakes==0.8.1 |
|
53 | pygments-markdown-lexer==0.1.0.dev39 | |
|
54 |
pyg |
|
|
55 | pyparsing==1.5.7 | |
|
53 | pygments==2.3.1 | |
|
54 | pyparsing==2.3.0 | |
|
56 | 55 | pyramid-beaker==0.8 |
|
57 |
pyramid-debugtoolbar==4. |
|
|
56 | pyramid-debugtoolbar==4.5.0 | |
|
58 | 57 | pyramid-jinja2==2.7 |
|
59 | 58 | pyramid-mako==1.0.2 |
|
60 |
pyramid==1. |
|
|
59 | pyramid==1.10.1 | |
|
61 | 60 | pyramid_mailer==0.15.1 |
|
62 | 61 | python-dateutil |
|
63 | 62 | python-ldap==3.1.0 |
|
64 | 63 | python-memcached==1.59 |
|
65 | 64 | python-pam==1.8.4 |
|
66 | python-saml | |
|
65 | python-saml==2.4.2 | |
|
67 | 66 | pytz==2018.4 |
|
68 | 67 | tzlocal==1.5.1 |
|
69 | 68 | pyzmq==14.6.0 |
@@ -72,21 +71,21 b' redis==2.10.6' | |||
|
72 | 71 | repoze.lru==0.7 |
|
73 | 72 | requests==2.9.1 |
|
74 | 73 | routes==2.4.1 |
|
75 |
simplejson==3.1 |
|
|
74 | simplejson==3.16.0 | |
|
76 | 75 | six==1.11.0 |
|
77 | 76 | sqlalchemy==1.1.18 |
|
78 | 77 | sshpubkeys==2.2.0 |
|
79 |
subprocess32==3.5. |
|
|
80 |
supervisor==3.3. |
|
|
78 | subprocess32==3.5.3 | |
|
79 | supervisor==3.3.5 | |
|
81 | 80 | tempita==0.5.2 |
|
82 | 81 | translationstring==1.3 |
|
83 | urllib3==1.21 | |
|
82 | urllib3==1.24.1 | |
|
84 | 83 | urlobject==2.4.3 |
|
85 |
venusian==1. |
|
|
84 | venusian==1.2.0 | |
|
86 | 85 | weberror==0.10.3 |
|
87 | 86 | webhelpers2==2.0 |
|
88 | 87 | webhelpers==1.3 |
|
89 |
webob==1. |
|
|
88 | webob==1.8.4 | |
|
90 | 89 | whoosh==2.7.4 |
|
91 | 90 | wsgiref==0.1.2 |
|
92 | 91 | zope.cachedescriptors==4.3.1 |
@@ -113,7 +112,7 b' invoke==0.13.0' | |||
|
113 | 112 | bumpversion==0.5.3 |
|
114 | 113 | |
|
115 | 114 | ## http servers |
|
116 |
gevent==1. |
|
|
115 | gevent==1.4.0 | |
|
117 | 116 | greenlet==0.4.15 |
|
118 | 117 | gunicorn==19.9.0 |
|
119 | 118 | waitress==1.1.0 |
@@ -124,7 +123,7 b' ipdb==0.11.0' | |||
|
124 | 123 | ipython==5.1.0 |
|
125 | 124 | |
|
126 | 125 | ## rhodecode-tools, special case |
|
127 |
https://code.rhodecode.com/rhodecode-tools-ce/archive/v1. |
|
|
126 | https://code.rhodecode.com/rhodecode-tools-ce/archive/v1.2.1.tar.gz?md5=25bc2f7de1da318e547236d3fb463d28#egg=rhodecode-tools==1.2.1 | |
|
128 | 127 | |
|
129 | 128 | ## appenlight |
|
130 | 129 | appenlight-client==0.6.26 |
@@ -9,6 +9,8 b' pytest-timeout==1.3.2' | |||
|
9 | 9 | gprof2dot==2017.9.19 |
|
10 | 10 | |
|
11 | 11 | mock==1.0.1 |
|
12 | webtest==2.0.29 | |
|
13 | 12 | cov-core==1.15.0 |
|
14 | 13 | coverage==4.5.1 |
|
14 | ||
|
15 | webtest==2.0.32 | |
|
16 | beautifulsoup4==4.6.3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -18,12 +18,6 b'' | |||
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | """ | |
|
22 | ||
|
23 | RhodeCode, a web based repository management software | |
|
24 | versioning implementation: http://www.python.org/dev/peps/pep-0386/ | |
|
25 | """ | |
|
26 | ||
|
27 | 21 | import os |
|
28 | 22 | import sys |
|
29 | 23 | import platform |
@@ -51,7 +45,7 b' PYRAMID_SETTINGS = {}' | |||
|
51 | 45 | EXTENSIONS = {} |
|
52 | 46 | |
|
53 | 47 | __version__ = ('.'.join((str(each) for each in VERSION[:3]))) |
|
54 |
__dbversion__ = 9 |
|
|
48 | __dbversion__ = 95 # defines current db version for migrations | |
|
55 | 49 | __platform__ = platform.system() |
|
56 | 50 | __license__ = 'AGPLv3, and Commercial License' |
|
57 | 51 | __author__ = 'RhodeCode GmbH' |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -21,6 +21,7 b'' | |||
|
21 | 21 | import inspect |
|
22 | 22 | import itertools |
|
23 | 23 | import logging |
|
24 | import sys | |
|
24 | 25 | import types |
|
25 | 26 | import fnmatch |
|
26 | 27 | |
@@ -38,6 +39,7 b' from rhodecode.api.exc import (' | |||
|
38 | 39 | from rhodecode.apps._base import TemplateArgs |
|
39 | 40 | from rhodecode.lib.auth import AuthUser |
|
40 | 41 | from rhodecode.lib.base import get_ip_addr, attach_context_attributes |
|
42 | from rhodecode.lib.exc_tracking import store_exception | |
|
41 | 43 | from rhodecode.lib.ext_json import json |
|
42 | 44 | from rhodecode.lib.utils2 import safe_str |
|
43 | 45 | from rhodecode.lib.plugins.utils import get_plugin_settings |
@@ -140,15 +142,14 b' def jsonrpc_error(request, message, reti' | |||
|
140 | 142 | def exception_view(exc, request): |
|
141 | 143 | rpc_id = getattr(request, 'rpc_id', None) |
|
142 | 144 | |
|
143 | fault_message = 'undefined error' | |
|
144 | 145 | if isinstance(exc, JSONRPCError): |
|
145 | fault_message = exc.message | |
|
146 | fault_message = safe_str(exc.message) | |
|
146 | 147 | log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message) |
|
147 | 148 | elif isinstance(exc, JSONRPCValidationError): |
|
148 | 149 | colander_exc = exc.colander_exception |
|
149 | 150 | # TODO(marcink): think maybe of nicer way to serialize errors ? |
|
150 | 151 | fault_message = colander_exc.asdict() |
|
151 | log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message) | |
|
152 | log.debug('json-rpc colander error rpc_id:%s "%s"', rpc_id, fault_message) | |
|
152 | 153 | elif isinstance(exc, JSONRPCForbidden): |
|
153 | 154 | fault_message = 'Access was denied to this resource.' |
|
154 | 155 | log.warning('json-rpc forbidden call rpc_id:%s "%s"', rpc_id, fault_message) |
@@ -170,6 +171,10 b' def exception_view(exc, request):' | |||
|
170 | 171 | |
|
171 | 172 | fault_message = "No such method: {}. Similar methods: {}".format( |
|
172 | 173 | method, similar) |
|
174 | else: | |
|
175 | fault_message = 'undefined error' | |
|
176 | exc_info = exc.exc_info() | |
|
177 | store_exception(id(exc_info), exc_info, prefix='rhodecode-api') | |
|
173 | 178 | |
|
174 | 179 | return jsonrpc_error(request, fault_message, rpc_id) |
|
175 | 180 | |
@@ -292,8 +297,10 b' def request_view(request):' | |||
|
292 | 297 | raise |
|
293 | 298 | except Exception: |
|
294 | 299 | log.exception('Unhandled exception occurred on api call: %s', func) |
|
295 | return jsonrpc_error(request, retid=request.rpc_id, | |
|
296 | message='Internal server error') | |
|
300 | exc_info = sys.exc_info() | |
|
301 | store_exception(id(exc_info), exc_info, prefix='rhodecode-api') | |
|
302 | return jsonrpc_error( | |
|
303 | request, retid=request.rpc_id, message='Internal server error') | |
|
297 | 304 | |
|
298 | 305 | |
|
299 | 306 | def setup_request(request): |
@@ -414,8 +421,7 b' def add_jsonrpc_method(config, view, **k' | |||
|
414 | 421 | |
|
415 | 422 | if method is None: |
|
416 | 423 | raise ConfigurationError( |
|
417 | 'Cannot register a JSON-RPC method without specifying the ' | |
|
418 | '"method"') | |
|
424 | 'Cannot register a JSON-RPC method without specifying the "method"') | |
|
419 | 425 | |
|
420 | 426 | # we define custom predicate, to enable to detect conflicting methods, |
|
421 | 427 | # those predicates are kind of "translation" from the decorator variables |
@@ -524,6 +530,7 b' def includeme(config):' | |||
|
524 | 530 | |
|
525 | 531 | # match filter by given method only |
|
526 | 532 | config.add_view_predicate('jsonrpc_method', MethodPredicate) |
|
533 | config.add_view_predicate('jsonrpc_method_not_found', NotFoundPredicate) | |
|
527 | 534 | |
|
528 | 535 | config.add_renderer(DEFAULT_RENDERER, ExtJsonRenderer( |
|
529 | 536 | serializer=json.dumps, indent=4)) |
@@ -538,5 +545,4 b' def includeme(config):' | |||
|
538 | 545 | config.scan(plugin_module, ignore='rhodecode.api.tests') |
|
539 | 546 | # register some exception handling view |
|
540 | 547 | config.add_view(exception_view, context=JSONRPCBaseError) |
|
541 | config.add_view_predicate('jsonrpc_method_not_found', NotFoundPredicate) | |
|
542 | 548 | config.add_notfound_view(exception_view, jsonrpc_method_not_found=True) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -86,7 +86,9 b' class TestApi(object):' | |||
|
86 | 86 | def test_api_non_existing_method_have_similar(self, request): |
|
87 | 87 | id_, params = build_data(self.apikey, 'comment', args='xx') |
|
88 | 88 | response = api_call(self.app, params) |
|
89 | expected = 'No such method: comment. Similar methods: changeset_comment, comment_pull_request, get_pull_request_comments, comment_commit' | |
|
89 | expected = 'No such method: comment. ' \ | |
|
90 | 'Similar methods: changeset_comment, comment_pull_request, ' \ | |
|
91 | 'get_pull_request_comments, comment_commit, get_repo_comments' | |
|
90 | 92 | assert_error(id_, expected, given=response.body) |
|
91 | 93 | |
|
92 | 94 | def test_api_disabled_user(self, request): |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2017-201 |
|
|
3 | # Copyright (C) 2017-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -38,7 +38,7 b' class TestGetMethod(object):' | |||
|
38 | 38 | response = api_call(self.app, params) |
|
39 | 39 | |
|
40 | 40 | expected = ['changeset_comment', 'comment_pull_request', |
|
41 | 'get_pull_request_comments', 'comment_commit'] | |
|
41 | 'get_pull_request_comments', 'comment_commit', 'get_repo_comments'] | |
|
42 | 42 | assert_ok(id_, expected, given=response.body) |
|
43 | 43 | |
|
44 | 44 | def test_get_methods_on_single_match(self): |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -65,6 +65,7 b' class TestGetPullRequest(object):' | |||
|
65 | 65 | 'title': pull_request.title, |
|
66 | 66 | 'description': pull_request.description, |
|
67 | 67 | 'status': pull_request.status, |
|
68 | 'state': pull_request.pull_request_state, | |
|
68 | 69 | 'created_on': pull_request.created_on, |
|
69 | 70 | 'updated_on': pull_request.updated_on, |
|
70 | 71 | 'commit_ids': pull_request.revisions, |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -59,6 +59,7 b' class TestGetPullRequestComments(object)' | |||
|
59 | 59 | 'status_lbl': 'Under Review'}, |
|
60 | 60 | 'comment_text': 'Auto status change to |new_status|\n\n.. |new_status| replace:: *"Under Review"*', |
|
61 | 61 | 'comment_type': 'note', |
|
62 | 'comment_resolved_by': None, | |
|
62 | 63 | 'pull_request_version': None} |
|
63 | 64 | ] |
|
64 | 65 | assert_ok(id_, expected, response.body) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -29,11 +29,10 b' from rhodecode.api.tests.utils import (' | |||
|
29 | 29 | |
|
30 | 30 | @pytest.mark.usefixtures("testuser_api", "app") |
|
31 | 31 | class TestMergePullRequest(object): |
|
32 | ||
|
32 | 33 | @pytest.mark.backends("git", "hg") |
|
33 | 34 | def test_api_merge_pull_request_merge_failed(self, pr_util, no_notifications): |
|
34 | 35 | pull_request = pr_util.create_pull_request(mergeable=True) |
|
35 | author = pull_request.user_id | |
|
36 | repo = pull_request.target_repo.repo_id | |
|
37 | 36 | pull_request_id = pull_request.pull_request_id |
|
38 | 37 | pull_request_repo = pull_request.target_repo.repo_name |
|
39 | 38 | |
@@ -46,8 +45,7 b' class TestMergePullRequest(object):' | |||
|
46 | 45 | |
|
47 | 46 | # The above api call detaches the pull request DB object from the |
|
48 | 47 | # session because of an unconditional transaction rollback in our |
|
49 | # middleware. Therefore we need to add it back here if we want to use | |
|
50 | # it. | |
|
48 | # middleware. Therefore we need to add it back here if we want to use it. | |
|
51 | 49 | Session().add(pull_request) |
|
52 | 50 | |
|
53 | 51 | expected = 'merge not possible for following reasons: ' \ |
@@ -55,6 +53,29 b' class TestMergePullRequest(object):' | |||
|
55 | 53 | assert_error(id_, expected, given=response.body) |
|
56 | 54 | |
|
57 | 55 | @pytest.mark.backends("git", "hg") |
|
56 | def test_api_merge_pull_request_merge_failed_disallowed_state( | |
|
57 | self, pr_util, no_notifications): | |
|
58 | pull_request = pr_util.create_pull_request(mergeable=True, approved=True) | |
|
59 | pull_request_id = pull_request.pull_request_id | |
|
60 | pull_request_repo = pull_request.target_repo.repo_name | |
|
61 | ||
|
62 | pr = PullRequest.get(pull_request_id) | |
|
63 | pr.pull_request_state = pull_request.STATE_UPDATING | |
|
64 | Session().add(pr) | |
|
65 | Session().commit() | |
|
66 | ||
|
67 | id_, params = build_data( | |
|
68 | self.apikey, 'merge_pull_request', | |
|
69 | repoid=pull_request_repo, | |
|
70 | pullrequestid=pull_request_id) | |
|
71 | ||
|
72 | response = api_call(self.app, params) | |
|
73 | expected = 'Operation forbidden because pull request is in state {}, '\ | |
|
74 | 'only state {} is allowed.'.format(PullRequest.STATE_UPDATING, | |
|
75 | PullRequest.STATE_CREATED) | |
|
76 | assert_error(id_, expected, given=response.body) | |
|
77 | ||
|
78 | @pytest.mark.backends("git", "hg") | |
|
58 | 79 | def test_api_merge_pull_request(self, pr_util, no_notifications): |
|
59 | 80 | pull_request = pr_util.create_pull_request(mergeable=True, approved=True) |
|
60 | 81 | author = pull_request.user_id |
@@ -88,6 +109,7 b' class TestMergePullRequest(object):' | |||
|
88 | 109 | expected = { |
|
89 | 110 | 'executed': True, |
|
90 | 111 | 'failure_reason': 0, |
|
112 | 'merge_status_message': 'This pull request can be automatically merged.', | |
|
91 | 113 | 'possible': True, |
|
92 | 114 | 'merge_commit_id': pull_request.shadow_merge_ref.commit_id, |
|
93 | 115 | 'merge_ref': pull_request.shadow_merge_ref._asdict() |
@@ -112,6 +134,107 b' class TestMergePullRequest(object):' | |||
|
112 | 134 | assert_error(id_, expected, given=response.body) |
|
113 | 135 | |
|
114 | 136 | @pytest.mark.backends("git", "hg") |
|
137 | def test_api_merge_pull_request_as_another_user_no_perms_to_merge( | |
|
138 | self, pr_util, no_notifications, user_util): | |
|
139 | merge_user = user_util.create_user() | |
|
140 | merge_user_id = merge_user.user_id | |
|
141 | merge_user_username = merge_user.username | |
|
142 | ||
|
143 | pull_request = pr_util.create_pull_request(mergeable=True, approved=True) | |
|
144 | ||
|
145 | pull_request_id = pull_request.pull_request_id | |
|
146 | pull_request_repo = pull_request.target_repo.repo_name | |
|
147 | ||
|
148 | id_, params = build_data( | |
|
149 | self.apikey, 'comment_pull_request', | |
|
150 | repoid=pull_request_repo, | |
|
151 | pullrequestid=pull_request_id, | |
|
152 | status='approved') | |
|
153 | ||
|
154 | response = api_call(self.app, params) | |
|
155 | expected = { | |
|
156 | 'comment_id': response.json.get('result', {}).get('comment_id'), | |
|
157 | 'pull_request_id': pull_request_id, | |
|
158 | 'status': {'given': 'approved', 'was_changed': True} | |
|
159 | } | |
|
160 | assert_ok(id_, expected, given=response.body) | |
|
161 | id_, params = build_data( | |
|
162 | self.apikey, 'merge_pull_request', | |
|
163 | repoid=pull_request_repo, | |
|
164 | pullrequestid=pull_request_id, | |
|
165 | userid=merge_user_id | |
|
166 | ) | |
|
167 | ||
|
168 | response = api_call(self.app, params) | |
|
169 | expected = 'merge not possible for following reasons: User `{}` ' \ | |
|
170 | 'not allowed to perform merge.'.format(merge_user_username) | |
|
171 | assert_error(id_, expected, response.body) | |
|
172 | ||
|
173 | @pytest.mark.backends("git", "hg") | |
|
174 | def test_api_merge_pull_request_as_another_user(self, pr_util, no_notifications, user_util): | |
|
175 | merge_user = user_util.create_user() | |
|
176 | merge_user_id = merge_user.user_id | |
|
177 | pull_request = pr_util.create_pull_request(mergeable=True, approved=True) | |
|
178 | user_util.grant_user_permission_to_repo( | |
|
179 | pull_request.target_repo, merge_user, 'repository.write') | |
|
180 | author = pull_request.user_id | |
|
181 | repo = pull_request.target_repo.repo_id | |
|
182 | pull_request_id = pull_request.pull_request_id | |
|
183 | pull_request_repo = pull_request.target_repo.repo_name | |
|
184 | ||
|
185 | id_, params = build_data( | |
|
186 | self.apikey, 'comment_pull_request', | |
|
187 | repoid=pull_request_repo, | |
|
188 | pullrequestid=pull_request_id, | |
|
189 | status='approved') | |
|
190 | ||
|
191 | response = api_call(self.app, params) | |
|
192 | expected = { | |
|
193 | 'comment_id': response.json.get('result', {}).get('comment_id'), | |
|
194 | 'pull_request_id': pull_request_id, | |
|
195 | 'status': {'given': 'approved', 'was_changed': True} | |
|
196 | } | |
|
197 | assert_ok(id_, expected, given=response.body) | |
|
198 | ||
|
199 | id_, params = build_data( | |
|
200 | self.apikey, 'merge_pull_request', | |
|
201 | repoid=pull_request_repo, | |
|
202 | pullrequestid=pull_request_id, | |
|
203 | userid=merge_user_id | |
|
204 | ) | |
|
205 | ||
|
206 | response = api_call(self.app, params) | |
|
207 | ||
|
208 | pull_request = PullRequest.get(pull_request_id) | |
|
209 | ||
|
210 | expected = { | |
|
211 | 'executed': True, | |
|
212 | 'failure_reason': 0, | |
|
213 | 'merge_status_message': 'This pull request can be automatically merged.', | |
|
214 | 'possible': True, | |
|
215 | 'merge_commit_id': pull_request.shadow_merge_ref.commit_id, | |
|
216 | 'merge_ref': pull_request.shadow_merge_ref._asdict() | |
|
217 | } | |
|
218 | ||
|
219 | assert_ok(id_, expected, response.body) | |
|
220 | ||
|
221 | journal = UserLog.query() \ | |
|
222 | .filter(UserLog.user_id == merge_user_id) \ | |
|
223 | .filter(UserLog.repository_id == repo) \ | |
|
224 | .order_by('user_log_id') \ | |
|
225 | .all() | |
|
226 | assert journal[-2].action == 'repo.pull_request.merge' | |
|
227 | assert journal[-1].action == 'repo.pull_request.close' | |
|
228 | ||
|
229 | id_, params = build_data( | |
|
230 | self.apikey, 'merge_pull_request', | |
|
231 | repoid=pull_request_repo, pullrequestid=pull_request_id, userid=merge_user_id) | |
|
232 | response = api_call(self.app, params) | |
|
233 | ||
|
234 | expected = 'merge not possible for following reasons: This pull request is closed.' | |
|
235 | assert_error(id_, expected, given=response.body) | |
|
236 | ||
|
237 | @pytest.mark.backends("git", "hg") | |
|
115 | 238 | def test_api_merge_pull_request_repo_error(self, pr_util): |
|
116 | 239 | pull_request = pr_util.create_pull_request() |
|
117 | 240 | id_, params = build_data( |
@@ -123,8 +246,7 b' class TestMergePullRequest(object):' | |||
|
123 | 246 | assert_error(id_, expected, given=response.body) |
|
124 | 247 | |
|
125 | 248 | @pytest.mark.backends("git", "hg") |
|
126 | def test_api_merge_pull_request_non_admin_with_userid_error(self, | |
|
127 | pr_util): | |
|
249 | def test_api_merge_pull_request_non_admin_with_userid_error(self, pr_util): | |
|
128 | 250 | pull_request = pr_util.create_pull_request(mergeable=True) |
|
129 | 251 | id_, params = build_data( |
|
130 | 252 | self.apikey_regular, 'merge_pull_request', |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -28,6 +28,19 b' from rhodecode.lib.ext_json import json' | |||
|
28 | 28 | API_URL = '/_admin/api' |
|
29 | 29 | |
|
30 | 30 | |
|
31 | def assert_call_ok(id_, given): | |
|
32 | expected = jsonify({ | |
|
33 | 'id': id_, | |
|
34 | 'error': None, | |
|
35 | 'result': None | |
|
36 | }) | |
|
37 | given = json.loads(given) | |
|
38 | ||
|
39 | assert expected['id'] == given['id'] | |
|
40 | assert expected['error'] == given['error'] | |
|
41 | return given['result'] | |
|
42 | ||
|
43 | ||
|
31 | 44 | def assert_ok(id_, expected, given): |
|
32 | 45 | expected = jsonify({ |
|
33 | 46 | 'id': id_, |
@@ -55,8 +68,6 b' def jsonify(obj):' | |||
|
55 | 68 | def build_data(apikey, method, **kw): |
|
56 | 69 | """ |
|
57 | 70 | Builds API data with given random ID |
|
58 | ||
|
59 | :param random_id: | |
|
60 | 71 | """ |
|
61 | 72 | random_id = random.randrange(1, 9999) |
|
62 | 73 | return random_id, json.dumps({ |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2014-201 |
|
|
3 | # Copyright (C) 2014-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -30,7 +30,7 b' from rhodecode.lib.auth import (' | |||
|
30 | 30 | HasPermissionAnyApi, HasRepoPermissionAnyApi, HasRepoGroupPermissionAnyApi) |
|
31 | 31 | from rhodecode.lib.utils import safe_unicode |
|
32 | 32 | from rhodecode.lib.vcs.exceptions import RepositoryError |
|
33 |
from rhodecode. |
|
|
33 | from rhodecode.lib.view_utils import get_commit_from_ref_name | |
|
34 | 34 | from rhodecode.lib.utils2 import str2bool |
|
35 | 35 | |
|
36 | 36 | log = logging.getLogger(__name__) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2015-201 |
|
|
3 | # Copyright (C) 2015-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -26,13 +26,13 b' from rhodecode.api import jsonrpc_method' | |||
|
26 | 26 | from rhodecode.api.utils import ( |
|
27 | 27 | has_superadmin_permission, Optional, OAttr, get_repo_or_error, |
|
28 | 28 | get_pull_request_or_error, get_commit_or_error, get_user_or_error, |
|
29 | validate_repo_permissions, resolve_ref_or_error) | |
|
29 | validate_repo_permissions, resolve_ref_or_error, validate_set_owner_permissions) | |
|
30 | 30 | from rhodecode.lib.auth import (HasRepoPermissionAnyApi) |
|
31 | 31 | from rhodecode.lib.base import vcs_operation_context |
|
32 | 32 | from rhodecode.lib.utils2 import str2bool |
|
33 | 33 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
34 | 34 | from rhodecode.model.comment import CommentsModel |
|
35 | from rhodecode.model.db import Session, ChangesetStatus, ChangesetComment | |
|
35 | from rhodecode.model.db import Session, ChangesetStatus, ChangesetComment, PullRequest | |
|
36 | 36 | from rhodecode.model.pull_request import PullRequestModel, MergeCheck |
|
37 | 37 | from rhodecode.model.settings import SettingsModel |
|
38 | 38 | from rhodecode.model.validation_schema import Invalid |
@@ -128,16 +128,21 b' def get_pull_request(request, apiuser, p' | |||
|
128 | 128 | else: |
|
129 | 129 | repo = pull_request.target_repo |
|
130 | 130 | |
|
131 | if not PullRequestModel().check_user_read( | |
|
132 | pull_request, apiuser, api=True): | |
|
131 | if not PullRequestModel().check_user_read(pull_request, apiuser, api=True): | |
|
133 | 132 | raise JSONRPCError('repository `%s` or pull request `%s` ' |
|
134 | 133 | 'does not exist' % (repoid, pullrequestid)) |
|
135 | data = pull_request.get_api_data() | |
|
134 | ||
|
135 | # NOTE(marcink): only calculate and return merge state if the pr state is 'created' | |
|
136 | # otherwise we can lock the repo on calculation of merge state while update/merge | |
|
137 | # is happening. | |
|
138 | merge_state = pull_request.pull_request_state == pull_request.STATE_CREATED | |
|
139 | data = pull_request.get_api_data(with_merge_state=merge_state) | |
|
136 | 140 | return data |
|
137 | 141 | |
|
138 | 142 | |
|
139 | 143 | @jsonrpc_method() |
|
140 |
def get_pull_requests(request, apiuser, repoid, status=Optional('new') |
|
|
144 | def get_pull_requests(request, apiuser, repoid, status=Optional('new'), | |
|
145 | merge_state=Optional(True)): | |
|
141 | 146 | """ |
|
142 | 147 | Get all pull requests from the repository specified in `repoid`. |
|
143 | 148 | |
@@ -151,6 +156,9 b' def get_pull_requests(request, apiuser, ' | |||
|
151 | 156 | * ``open`` |
|
152 | 157 | * ``closed`` |
|
153 | 158 | :type status: str |
|
159 | :param merge_state: Optional calculate merge state for each repository. | |
|
160 | This could result in longer time to fetch the data | |
|
161 | :type merge_state: bool | |
|
154 | 162 | |
|
155 | 163 | Example output: |
|
156 | 164 | |
@@ -228,8 +236,10 b' def get_pull_requests(request, apiuser, ' | |||
|
228 | 236 | validate_repo_permissions(apiuser, repoid, repo, _perms) |
|
229 | 237 | |
|
230 | 238 | status = Optional.extract(status) |
|
231 | pull_requests = PullRequestModel().get_all(repo, statuses=[status]) | |
|
232 | data = [pr.get_api_data() for pr in pull_requests] | |
|
239 | merge_state = Optional.extract(merge_state, binary=True) | |
|
240 | pull_requests = PullRequestModel().get_all(repo, statuses=[status], | |
|
241 | order_by='id', order_dir='desc') | |
|
242 | data = [pr.get_api_data(with_merge_state=merge_state) for pr in pull_requests] | |
|
233 | 243 | return data |
|
234 | 244 | |
|
235 | 245 | |
@@ -257,10 +267,11 b' def merge_pull_request(' | |||
|
257 | 267 | |
|
258 | 268 | "id": <id_given_in_input>, |
|
259 | 269 | "result": { |
|
260 | "executed": "<bool>", | |
|
261 | "failure_reason": "<int>", | |
|
262 |
"merge_ |
|
|
263 |
" |
|
|
270 | "executed": "<bool>", | |
|
271 | "failure_reason": "<int>", | |
|
272 | "merge_status_message": "<str>", | |
|
273 | "merge_commit_id": "<merge_commit_id>", | |
|
274 | "possible": "<bool>", | |
|
264 | 275 | "merge_ref": { |
|
265 | 276 | "commit_id": "<commit_id>", |
|
266 | 277 | "type": "<type>", |
@@ -274,17 +285,25 b' def merge_pull_request(' | |||
|
274 | 285 | repo = get_repo_or_error(repoid) |
|
275 | 286 | else: |
|
276 | 287 | repo = pull_request.target_repo |
|
277 | ||
|
288 | auth_user = apiuser | |
|
278 | 289 | if not isinstance(userid, Optional): |
|
279 | 290 | if (has_superadmin_permission(apiuser) or |
|
280 | 291 | HasRepoPermissionAnyApi('repository.admin')( |
|
281 | 292 | user=apiuser, repo_name=repo.repo_name)): |
|
282 | 293 | apiuser = get_user_or_error(userid) |
|
294 | auth_user = apiuser.AuthUser() | |
|
283 | 295 | else: |
|
284 | 296 | raise JSONRPCError('userid is not the same as your user') |
|
285 | 297 | |
|
286 | check = MergeCheck.validate( | |
|
287 | pull_request, auth_user=apiuser, translator=request.translate) | |
|
298 | if pull_request.pull_request_state != PullRequest.STATE_CREATED: | |
|
299 | raise JSONRPCError( | |
|
300 | 'Operation forbidden because pull request is in state {}, ' | |
|
301 | 'only state {} is allowed.'.format( | |
|
302 | pull_request.pull_request_state, PullRequest.STATE_CREATED)) | |
|
303 | ||
|
304 | with pull_request.set_state(PullRequest.STATE_UPDATING): | |
|
305 | check = MergeCheck.validate(pull_request, auth_user=auth_user, | |
|
306 | translator=request.translate) | |
|
288 | 307 | merge_possible = not check.failed |
|
289 | 308 | |
|
290 | 309 | if not merge_possible: |
@@ -300,20 +319,20 b' def merge_pull_request(' | |||
|
300 | 319 | target_repo = pull_request.target_repo |
|
301 | 320 | extras = vcs_operation_context( |
|
302 | 321 | request.environ, repo_name=target_repo.repo_name, |
|
303 |
username=a |
|
|
322 | username=auth_user.username, action='push', | |
|
304 | 323 | scm=target_repo.repo_type) |
|
305 | merge_response = PullRequestModel().merge_repo( | |
|
306 | pull_request, apiuser, extras=extras) | |
|
324 | with pull_request.set_state(PullRequest.STATE_UPDATING): | |
|
325 | merge_response = PullRequestModel().merge_repo( | |
|
326 | pull_request, apiuser, extras=extras) | |
|
307 | 327 | if merge_response.executed: |
|
308 | PullRequestModel().close_pull_request( | |
|
309 | pull_request.pull_request_id, apiuser) | |
|
328 | PullRequestModel().close_pull_request(pull_request.pull_request_id, auth_user) | |
|
310 | 329 | |
|
311 | 330 | Session().commit() |
|
312 | 331 | |
|
313 | 332 | # In previous versions the merge response directly contained the merge |
|
314 | 333 | # commit id. It is now contained in the merge reference object. To be |
|
315 | 334 | # backwards compatible we have to extract it again. |
|
316 |
merge_response = merge_response. |
|
|
335 | merge_response = merge_response.asdict() | |
|
317 | 336 | merge_response['merge_commit_id'] = merge_response['merge_ref'].commit_id |
|
318 | 337 | |
|
319 | 338 | return merge_response |
@@ -474,14 +493,21 b' def comment_pull_request(' | |||
|
474 | 493 | else: |
|
475 | 494 | repo = pull_request.target_repo |
|
476 | 495 | |
|
496 | auth_user = apiuser | |
|
477 | 497 | if not isinstance(userid, Optional): |
|
478 | 498 | if (has_superadmin_permission(apiuser) or |
|
479 | 499 | HasRepoPermissionAnyApi('repository.admin')( |
|
480 | 500 | user=apiuser, repo_name=repo.repo_name)): |
|
481 | 501 | apiuser = get_user_or_error(userid) |
|
502 | auth_user = apiuser.AuthUser() | |
|
482 | 503 | else: |
|
483 | 504 | raise JSONRPCError('userid is not the same as your user') |
|
484 | 505 | |
|
506 | if pull_request.is_closed(): | |
|
507 | raise JSONRPCError( | |
|
508 | 'pull request `%s` comment failed, pull request is closed' % ( | |
|
509 | pullrequestid,)) | |
|
510 | ||
|
485 | 511 | if not PullRequestModel().check_user_read( |
|
486 | 512 | pull_request, apiuser, api=True): |
|
487 | 513 | raise JSONRPCError('repository `%s` does not exist' % (repoid,)) |
@@ -549,7 +575,7 b' def comment_pull_request(' | |||
|
549 | 575 | renderer=renderer, |
|
550 | 576 | comment_type=comment_type, |
|
551 | 577 | resolves_comment_id=resolves_comment_id, |
|
552 |
auth_user=a |
|
|
578 | auth_user=auth_user | |
|
553 | 579 | ) |
|
554 | 580 | |
|
555 | 581 | if allowed_to_change_status and status: |
@@ -589,8 +615,8 b' def comment_pull_request(' | |||
|
589 | 615 | @jsonrpc_method() |
|
590 | 616 | def create_pull_request( |
|
591 | 617 | request, apiuser, source_repo, target_repo, source_ref, target_ref, |
|
592 |
title=Optional(''), description=Optional(''), |
|
|
593 | reviewers=Optional(None)): | |
|
618 | owner=Optional(OAttr('apiuser')), title=Optional(''), description=Optional(''), | |
|
619 | description_renderer=Optional(''), reviewers=Optional(None)): | |
|
594 | 620 | """ |
|
595 | 621 | Creates a new pull request. |
|
596 | 622 | |
@@ -611,6 +637,8 b' def create_pull_request(' | |||
|
611 | 637 | :type source_ref: str |
|
612 | 638 | :param target_ref: Set the target ref name. |
|
613 | 639 | :type target_ref: str |
|
640 | :param owner: user_id or username | |
|
641 | :type owner: Optional(str) | |
|
614 | 642 | :param title: Optionally Set the pull request title, it's generated otherwise |
|
615 | 643 | :type title: str |
|
616 | 644 | :param description: Set the pull request description. |
@@ -634,6 +662,8 b' def create_pull_request(' | |||
|
634 | 662 | _perms = ('repository.admin', 'repository.write', 'repository.read',) |
|
635 | 663 | validate_repo_permissions(apiuser, source_repo, source_db_repo, _perms) |
|
636 | 664 | |
|
665 | owner = validate_set_owner_permissions(apiuser, owner) | |
|
666 | ||
|
637 | 667 | full_source_ref = resolve_ref_or_error(source_ref, source_db_repo) |
|
638 | 668 | full_target_ref = resolve_ref_or_error(target_ref, target_db_repo) |
|
639 | 669 | |
@@ -679,7 +709,7 b' def create_pull_request(' | |||
|
679 | 709 | |
|
680 | 710 | # recalculate reviewers logic, to make sure we can validate this |
|
681 | 711 | reviewer_rules = get_default_reviewers_data( |
|
682 |
|
|
|
712 | owner, source_db_repo, | |
|
683 | 713 | source_commit, target_db_repo, target_commit) |
|
684 | 714 | |
|
685 | 715 | # now MERGE our given with the calculated |
@@ -706,7 +736,7 b' def create_pull_request(' | |||
|
706 | 736 | description_renderer = Optional.extract(description_renderer) or default_system_renderer |
|
707 | 737 | |
|
708 | 738 | pull_request = PullRequestModel().create( |
|
709 |
created_by= |
|
|
739 | created_by=owner.user_id, | |
|
710 | 740 | source_repo=source_repo, |
|
711 | 741 | source_ref=full_source_ref, |
|
712 | 742 | target_repo=target_repo, |
@@ -844,11 +874,18 b' def update_pull_request(' | |||
|
844 | 874 | |
|
845 | 875 | commit_changes = {"added": [], "common": [], "removed": []} |
|
846 | 876 | if str2bool(Optional.extract(update_commits)): |
|
847 | if PullRequestModel().has_valid_update_type(pull_request): | |
|
848 | update_response = PullRequestModel().update_commits( | |
|
849 | pull_request) | |
|
850 | commit_changes = update_response.changes or commit_changes | |
|
851 | Session().commit() | |
|
877 | ||
|
878 | if pull_request.pull_request_state != PullRequest.STATE_CREATED: | |
|
879 | raise JSONRPCError( | |
|
880 | 'Operation forbidden because pull request is in state {}, ' | |
|
881 | 'only state {} is allowed.'.format( | |
|
882 | pull_request.pull_request_state, PullRequest.STATE_CREATED)) | |
|
883 | ||
|
884 | with pull_request.set_state(PullRequest.STATE_UPDATING): | |
|
885 | if PullRequestModel().has_valid_update_type(pull_request): | |
|
886 | update_response = PullRequestModel().update_commits(pull_request) | |
|
887 | commit_changes = update_response.changes or commit_changes | |
|
888 | Session().commit() | |
|
852 | 889 | |
|
853 | 890 | reviewers_changes = {"added": [], "removed": []} |
|
854 | 891 | if reviewers: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -29,13 +29,15 b' from rhodecode.api.utils import (' | |||
|
29 | 29 | get_user_group_or_error, get_user_or_error, validate_repo_permissions, |
|
30 | 30 | get_perm_or_error, parse_args, get_origin, build_commit_data, |
|
31 | 31 | validate_set_owner_permissions) |
|
32 | from rhodecode.lib import audit_logger | |
|
32 | from rhodecode.lib import audit_logger, rc_cache | |
|
33 | 33 | from rhodecode.lib import repo_maintenance |
|
34 | 34 | from rhodecode.lib.auth import HasPermissionAnyApi, HasUserGroupPermissionAnyApi |
|
35 | 35 | from rhodecode.lib.celerylib.utils import get_task_id |
|
36 | from rhodecode.lib.utils2 import str2bool, time_to_datetime, safe_str | |
|
36 | from rhodecode.lib.utils2 import str2bool, time_to_datetime, safe_str, safe_int | |
|
37 | 37 | from rhodecode.lib.ext_json import json |
|
38 | 38 | from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError |
|
39 | from rhodecode.lib.vcs import RepositoryError | |
|
40 | from rhodecode.lib.vcs.exceptions import NodeDoesNotExistError | |
|
39 | 41 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
40 | 42 | from rhodecode.model.comment import CommentsModel |
|
41 | 43 | from rhodecode.model.db import ( |
@@ -380,7 +382,7 b' def get_repo_changesets(request, apiuser' | |||
|
380 | 382 | |
|
381 | 383 | try: |
|
382 | 384 | commits = vcs_repo.get_commits( |
|
383 | start_id=start_rev, pre_load=pre_load) | |
|
385 | start_id=start_rev, pre_load=pre_load, translate_tags=False) | |
|
384 | 386 | except TypeError as e: |
|
385 | 387 | raise JSONRPCError(safe_str(e)) |
|
386 | 388 | except Exception: |
@@ -428,8 +430,8 b' def get_repo_nodes(request, apiuser, rep' | |||
|
428 | 430 | ``all`` (default), ``files`` and ``dirs``. |
|
429 | 431 | :type ret_type: Optional(str) |
|
430 | 432 | :param details: Returns extended information about nodes, such as |
|
431 |
md5, binary, and or content. |
|
|
432 | ``full``. | |
|
433 | md5, binary, and or content. | |
|
434 | The valid options are ``basic`` and ``full``. | |
|
433 | 435 | :type details: Optional(str) |
|
434 | 436 | :param max_file_bytes: Only return file content under this file size bytes |
|
435 | 437 | :type details: Optional(int) |
@@ -440,12 +442,17 b' def get_repo_nodes(request, apiuser, rep' | |||
|
440 | 442 | |
|
441 | 443 | id : <id_given_in_input> |
|
442 | 444 | result: [ |
|
443 | { | |
|
444 |
|
|
|
445 |
|
|
|
446 | "binary": "<true|false>" (only in extended mode) | |
|
447 | "md5" : "<md5 of file content>" (only in extended mode) | |
|
448 | }, | |
|
445 | { | |
|
446 | "binary": false, | |
|
447 | "content": "File line\nLine2\n", | |
|
448 | "extension": "md", | |
|
449 | "lines": 2, | |
|
450 | "md5": "059fa5d29b19c0657e384749480f6422", | |
|
451 | "mimetype": "text/x-minidsrc", | |
|
452 | "name": "file.md", | |
|
453 | "size": 580, | |
|
454 | "type": "file" | |
|
455 | }, | |
|
449 | 456 | ... |
|
450 | 457 | ] |
|
451 | 458 | error: null |
@@ -453,16 +460,14 b' def get_repo_nodes(request, apiuser, rep' | |||
|
453 | 460 | |
|
454 | 461 | repo = get_repo_or_error(repoid) |
|
455 | 462 | if not has_superadmin_permission(apiuser): |
|
456 | _perms = ( | |
|
457 | 'repository.admin', 'repository.write', 'repository.read',) | |
|
463 | _perms = ('repository.admin', 'repository.write', 'repository.read',) | |
|
458 | 464 | validate_repo_permissions(apiuser, repoid, repo, _perms) |
|
459 | 465 | |
|
460 | 466 | ret_type = Optional.extract(ret_type) |
|
461 | 467 | details = Optional.extract(details) |
|
462 | 468 | _extended_types = ['basic', 'full'] |
|
463 | 469 | if details not in _extended_types: |
|
464 | raise JSONRPCError( | |
|
465 | 'ret_type must be one of %s' % (','.join(_extended_types))) | |
|
470 | raise JSONRPCError('ret_type must be one of %s' % (','.join(_extended_types))) | |
|
466 | 471 | extended_info = False |
|
467 | 472 | content = False |
|
468 | 473 | if details == 'basic': |
@@ -499,6 +504,149 b' def get_repo_nodes(request, apiuser, rep' | |||
|
499 | 504 | |
|
500 | 505 | |
|
501 | 506 | @jsonrpc_method() |
|
507 | def get_repo_file(request, apiuser, repoid, commit_id, file_path, | |
|
508 | max_file_bytes=Optional(None), details=Optional('basic'), | |
|
509 | cache=Optional(True)): | |
|
510 | """ | |
|
511 | Returns a single file from repository at given revision. | |
|
512 | ||
|
513 | This command can only be run using an |authtoken| with admin rights, | |
|
514 | or users with at least read rights to |repos|. | |
|
515 | ||
|
516 | :param apiuser: This is filled automatically from the |authtoken|. | |
|
517 | :type apiuser: AuthUser | |
|
518 | :param repoid: The repository name or repository ID. | |
|
519 | :type repoid: str or int | |
|
520 | :param commit_id: The revision for which listing should be done. | |
|
521 | :type commit_id: str | |
|
522 | :param file_path: The path from which to start displaying. | |
|
523 | :type file_path: str | |
|
524 | :param details: Returns different set of information about nodes. | |
|
525 | The valid options are ``minimal`` ``basic`` and ``full``. | |
|
526 | :type details: Optional(str) | |
|
527 | :param max_file_bytes: Only return file content under this file size bytes | |
|
528 | :type max_file_bytes: Optional(int) | |
|
529 | :param cache: Use internal caches for fetching files. If disabled fetching | |
|
530 | files is slower but more memory efficient | |
|
531 | :type cache: Optional(bool) | |
|
532 | Example output: | |
|
533 | ||
|
534 | .. code-block:: bash | |
|
535 | ||
|
536 | id : <id_given_in_input> | |
|
537 | result: { | |
|
538 | "binary": false, | |
|
539 | "extension": "py", | |
|
540 | "lines": 35, | |
|
541 | "content": "....", | |
|
542 | "md5": "76318336366b0f17ee249e11b0c99c41", | |
|
543 | "mimetype": "text/x-python", | |
|
544 | "name": "python.py", | |
|
545 | "size": 817, | |
|
546 | "type": "file", | |
|
547 | } | |
|
548 | error: null | |
|
549 | """ | |
|
550 | ||
|
551 | repo = get_repo_or_error(repoid) | |
|
552 | if not has_superadmin_permission(apiuser): | |
|
553 | _perms = ('repository.admin', 'repository.write', 'repository.read',) | |
|
554 | validate_repo_permissions(apiuser, repoid, repo, _perms) | |
|
555 | ||
|
556 | cache = Optional.extract(cache, binary=True) | |
|
557 | details = Optional.extract(details) | |
|
558 | _extended_types = ['minimal', 'minimal+search', 'basic', 'full'] | |
|
559 | if details not in _extended_types: | |
|
560 | raise JSONRPCError( | |
|
561 | 'ret_type must be one of %s, got %s' % (','.join(_extended_types)), details) | |
|
562 | extended_info = False | |
|
563 | content = False | |
|
564 | ||
|
565 | if details == 'minimal': | |
|
566 | extended_info = False | |
|
567 | ||
|
568 | elif details == 'basic': | |
|
569 | extended_info = True | |
|
570 | ||
|
571 | elif details == 'full': | |
|
572 | extended_info = content = True | |
|
573 | ||
|
574 | try: | |
|
575 | # check if repo is not empty by any chance, skip quicker if it is. | |
|
576 | _scm = repo.scm_instance() | |
|
577 | if _scm.is_empty(): | |
|
578 | return None | |
|
579 | ||
|
580 | node = ScmModel().get_node( | |
|
581 | repo, commit_id, file_path, extended_info=extended_info, | |
|
582 | content=content, max_file_bytes=max_file_bytes, cache=cache) | |
|
583 | except NodeDoesNotExistError: | |
|
584 | raise JSONRPCError('There is no file in repo: `{}` at path `{}` for commit: `{}`'.format( | |
|
585 | repo.repo_name, file_path, commit_id)) | |
|
586 | except Exception: | |
|
587 | log.exception("Exception occurred while trying to get repo %s file", | |
|
588 | repo.repo_name) | |
|
589 | raise JSONRPCError('failed to get repo: `{}` file at path {}'.format( | |
|
590 | repo.repo_name, file_path)) | |
|
591 | ||
|
592 | return node | |
|
593 | ||
|
594 | ||
|
595 | @jsonrpc_method() | |
|
596 | def get_repo_fts_tree(request, apiuser, repoid, commit_id, root_path): | |
|
597 | """ | |
|
598 | Returns a list of tree nodes for path at given revision. This api is built | |
|
599 | strictly for usage in full text search building, and shouldn't be consumed | |
|
600 | ||
|
601 | This command can only be run using an |authtoken| with admin rights, | |
|
602 | or users with at least read rights to |repos|. | |
|
603 | ||
|
604 | """ | |
|
605 | ||
|
606 | repo = get_repo_or_error(repoid) | |
|
607 | if not has_superadmin_permission(apiuser): | |
|
608 | _perms = ('repository.admin', 'repository.write', 'repository.read',) | |
|
609 | validate_repo_permissions(apiuser, repoid, repo, _perms) | |
|
610 | ||
|
611 | repo_id = repo.repo_id | |
|
612 | cache_seconds = safe_int(rhodecode.CONFIG.get('rc_cache.cache_repo.expiration_time')) | |
|
613 | cache_on = cache_seconds > 0 | |
|
614 | ||
|
615 | cache_namespace_uid = 'cache_repo.{}'.format(repo_id) | |
|
616 | region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) | |
|
617 | ||
|
618 | @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, | |
|
619 | condition=cache_on) | |
|
620 | def compute_fts_tree(repo_id, commit_id, root_path, cache_ver): | |
|
621 | return ScmModel().get_fts_data(repo_id, commit_id, root_path) | |
|
622 | ||
|
623 | try: | |
|
624 | # check if repo is not empty by any chance, skip quicker if it is. | |
|
625 | _scm = repo.scm_instance() | |
|
626 | if _scm.is_empty(): | |
|
627 | return [] | |
|
628 | except RepositoryError: | |
|
629 | log.exception("Exception occurred while trying to get repo nodes") | |
|
630 | raise JSONRPCError('failed to get repo: `%s` nodes' % repo.repo_name) | |
|
631 | ||
|
632 | try: | |
|
633 | # we need to resolve commit_id to a FULL sha for cache to work correctly. | |
|
634 | # sending 'master' is a pointer that needs to be translated to current commit. | |
|
635 | commit_id = _scm.get_commit(commit_id=commit_id).raw_id | |
|
636 | log.debug( | |
|
637 | 'Computing FTS REPO TREE for repo_id %s commit_id `%s` ' | |
|
638 | 'with caching: %s[TTL: %ss]' % ( | |
|
639 | repo_id, commit_id, cache_on, cache_seconds or 0)) | |
|
640 | ||
|
641 | tree_files = compute_fts_tree(repo_id, commit_id, root_path, 'v1') | |
|
642 | return tree_files | |
|
643 | ||
|
644 | except Exception: | |
|
645 | log.exception("Exception occurred while trying to get repo nodes") | |
|
646 | raise JSONRPCError('failed to get repo: `%s` nodes' % repo.repo_name) | |
|
647 | ||
|
648 | ||
|
649 | @jsonrpc_method() | |
|
502 | 650 | def get_repo_refs(request, apiuser, repoid): |
|
503 | 651 | """ |
|
504 | 652 | Returns a dictionary of current references. It returns |
@@ -1506,6 +1654,73 b' def comment_commit(' | |||
|
1506 | 1654 | |
|
1507 | 1655 | |
|
1508 | 1656 | @jsonrpc_method() |
|
1657 | def get_repo_comments(request, apiuser, repoid, | |
|
1658 | commit_id=Optional(None), comment_type=Optional(None), | |
|
1659 | userid=Optional(None)): | |
|
1660 | """ | |
|
1661 | Get all comments for a repository | |
|
1662 | ||
|
1663 | :param apiuser: This is filled automatically from the |authtoken|. | |
|
1664 | :type apiuser: AuthUser | |
|
1665 | :param repoid: Set the repository name or repository ID. | |
|
1666 | :type repoid: str or int | |
|
1667 | :param commit_id: Optionally filter the comments by the commit_id | |
|
1668 | :type commit_id: Optional(str), default: None | |
|
1669 | :param comment_type: Optionally filter the comments by the comment_type | |
|
1670 | one of: 'note', 'todo' | |
|
1671 | :type comment_type: Optional(str), default: None | |
|
1672 | :param userid: Optionally filter the comments by the author of comment | |
|
1673 | :type userid: Optional(str or int), Default: None | |
|
1674 | ||
|
1675 | Example error output: | |
|
1676 | ||
|
1677 | .. code-block:: bash | |
|
1678 | ||
|
1679 | { | |
|
1680 | "id" : <id_given_in_input>, | |
|
1681 | "result" : [ | |
|
1682 | { | |
|
1683 | "comment_author": <USER_DETAILS>, | |
|
1684 | "comment_created_on": "2017-02-01T14:38:16.309", | |
|
1685 | "comment_f_path": "file.txt", | |
|
1686 | "comment_id": 282, | |
|
1687 | "comment_lineno": "n1", | |
|
1688 | "comment_resolved_by": null, | |
|
1689 | "comment_status": [], | |
|
1690 | "comment_text": "This file needs a header", | |
|
1691 | "comment_type": "todo" | |
|
1692 | } | |
|
1693 | ], | |
|
1694 | "error" : null | |
|
1695 | } | |
|
1696 | ||
|
1697 | """ | |
|
1698 | repo = get_repo_or_error(repoid) | |
|
1699 | if not has_superadmin_permission(apiuser): | |
|
1700 | _perms = ('repository.read', 'repository.write', 'repository.admin') | |
|
1701 | validate_repo_permissions(apiuser, repoid, repo, _perms) | |
|
1702 | ||
|
1703 | commit_id = Optional.extract(commit_id) | |
|
1704 | ||
|
1705 | userid = Optional.extract(userid) | |
|
1706 | if userid: | |
|
1707 | user = get_user_or_error(userid) | |
|
1708 | else: | |
|
1709 | user = None | |
|
1710 | ||
|
1711 | comment_type = Optional.extract(comment_type) | |
|
1712 | if comment_type and comment_type not in ChangesetComment.COMMENT_TYPES: | |
|
1713 | raise JSONRPCError( | |
|
1714 | 'comment_type must be one of `{}` got {}'.format( | |
|
1715 | ChangesetComment.COMMENT_TYPES, comment_type) | |
|
1716 | ) | |
|
1717 | ||
|
1718 | comments = CommentsModel().get_repository_comments( | |
|
1719 | repo=repo, comment_type=comment_type, user=user, commit_id=commit_id) | |
|
1720 | return comments | |
|
1721 | ||
|
1722 | ||
|
1723 | @jsonrpc_method() | |
|
1509 | 1724 | def grant_user_permission(request, apiuser, repoid, userid, perm): |
|
1510 | 1725 | """ |
|
1511 | 1726 | Grant permissions for the specified user on the given repository, |
@@ -1543,9 +1758,18 b' def grant_user_permission(request, apius' | |||
|
1543 | 1758 | _perms = ('repository.admin',) |
|
1544 | 1759 | validate_repo_permissions(apiuser, repoid, repo, _perms) |
|
1545 | 1760 | |
|
1761 | perm_additions = [[user.user_id, perm.permission_name, "user"]] | |
|
1546 | 1762 | try: |
|
1763 | changes = RepoModel().update_permissions( | |
|
1764 | repo=repo, perm_additions=perm_additions, cur_user=apiuser) | |
|
1547 | 1765 | |
|
1548 | RepoModel().grant_user_permission(repo=repo, user=user, perm=perm) | |
|
1766 | action_data = { | |
|
1767 | 'added': changes['added'], | |
|
1768 | 'updated': changes['updated'], | |
|
1769 | 'deleted': changes['deleted'], | |
|
1770 | } | |
|
1771 | audit_logger.store_api( | |
|
1772 | 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) | |
|
1549 | 1773 | |
|
1550 | 1774 | Session().commit() |
|
1551 | 1775 | return { |
@@ -1555,8 +1779,7 b' def grant_user_permission(request, apius' | |||
|
1555 | 1779 | 'success': True |
|
1556 | 1780 | } |
|
1557 | 1781 | except Exception: |
|
1558 | log.exception( | |
|
1559 | "Exception occurred while trying edit permissions for repo") | |
|
1782 | log.exception("Exception occurred while trying edit permissions for repo") | |
|
1560 | 1783 | raise JSONRPCError( |
|
1561 | 1784 | 'failed to edit permission for user: `%s` in repo: `%s`' % ( |
|
1562 | 1785 | userid, repoid |
@@ -1597,8 +1820,19 b' def revoke_user_permission(request, apiu' | |||
|
1597 | 1820 | _perms = ('repository.admin',) |
|
1598 | 1821 | validate_repo_permissions(apiuser, repoid, repo, _perms) |
|
1599 | 1822 | |
|
1823 | perm_deletions = [[user.user_id, None, "user"]] | |
|
1600 | 1824 | try: |
|
1601 | RepoModel().revoke_user_permission(repo=repo, user=user) | |
|
1825 | changes = RepoModel().update_permissions( | |
|
1826 | repo=repo, perm_deletions=perm_deletions, cur_user=user) | |
|
1827 | ||
|
1828 | action_data = { | |
|
1829 | 'added': changes['added'], | |
|
1830 | 'updated': changes['updated'], | |
|
1831 | 'deleted': changes['deleted'], | |
|
1832 | } | |
|
1833 | audit_logger.store_api( | |
|
1834 | 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) | |
|
1835 | ||
|
1602 | 1836 | Session().commit() |
|
1603 | 1837 | return { |
|
1604 | 1838 | 'msg': 'Revoked perm for user: `%s` in repo: `%s`' % ( |
@@ -1607,8 +1841,7 b' def revoke_user_permission(request, apiu' | |||
|
1607 | 1841 | 'success': True |
|
1608 | 1842 | } |
|
1609 | 1843 | except Exception: |
|
1610 | log.exception( | |
|
1611 | "Exception occurred while trying revoke permissions to repo") | |
|
1844 | log.exception("Exception occurred while trying revoke permissions to repo") | |
|
1612 | 1845 | raise JSONRPCError( |
|
1613 | 1846 | 'failed to edit permission for user: `%s` in repo: `%s`' % ( |
|
1614 | 1847 | userid, repoid |
@@ -1674,9 +1907,17 b' def grant_user_group_permission(request,' | |||
|
1674 | 1907 | raise JSONRPCError( |
|
1675 | 1908 | 'user group `%s` does not exist' % (usergroupid,)) |
|
1676 | 1909 | |
|
1910 | perm_additions = [[user_group.users_group_id, perm.permission_name, "user_group"]] | |
|
1677 | 1911 | try: |
|
1678 |
RepoModel(). |
|
|
1679 | repo=repo, group_name=user_group, perm=perm) | |
|
1912 | changes = RepoModel().update_permissions( | |
|
1913 | repo=repo, perm_additions=perm_additions, cur_user=apiuser) | |
|
1914 | action_data = { | |
|
1915 | 'added': changes['added'], | |
|
1916 | 'updated': changes['updated'], | |
|
1917 | 'deleted': changes['deleted'], | |
|
1918 | } | |
|
1919 | audit_logger.store_api( | |
|
1920 | 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) | |
|
1680 | 1921 | |
|
1681 | 1922 | Session().commit() |
|
1682 | 1923 | return { |
@@ -1739,9 +1980,17 b' def revoke_user_group_permission(request' | |||
|
1739 | 1980 | raise JSONRPCError( |
|
1740 | 1981 | 'user group `%s` does not exist' % (usergroupid,)) |
|
1741 | 1982 | |
|
1983 | perm_deletions = [[user_group.users_group_id, None, "user_group"]] | |
|
1742 | 1984 | try: |
|
1743 |
RepoModel(). |
|
|
1744 | repo=repo, group_name=user_group) | |
|
1985 | changes = RepoModel().update_permissions( | |
|
1986 | repo=repo, perm_deletions=perm_deletions, cur_user=apiuser) | |
|
1987 | action_data = { | |
|
1988 | 'added': changes['added'], | |
|
1989 | 'updated': changes['updated'], | |
|
1990 | 'deleted': changes['deleted'], | |
|
1991 | } | |
|
1992 | audit_logger.store_api( | |
|
1993 | 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) | |
|
1745 | 1994 | |
|
1746 | 1995 | Session().commit() |
|
1747 | 1996 | return { |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -453,10 +453,19 b' def grant_user_permission_to_repo_group(' | |||
|
453 | 453 | |
|
454 | 454 | perm_additions = [[user.user_id, perm.permission_name, "user"]] |
|
455 | 455 | try: |
|
456 |
RepoGroupModel().update_permissions( |
|
|
457 |
|
|
|
458 |
|
|
|
459 | cur_user=apiuser) | |
|
456 | changes = RepoGroupModel().update_permissions( | |
|
457 | repo_group=repo_group, perm_additions=perm_additions, | |
|
458 | recursive=apply_to_children, cur_user=apiuser) | |
|
459 | ||
|
460 | action_data = { | |
|
461 | 'added': changes['added'], | |
|
462 | 'updated': changes['updated'], | |
|
463 | 'deleted': changes['deleted'], | |
|
464 | } | |
|
465 | audit_logger.store_api( | |
|
466 | 'repo_group.edit.permissions', action_data=action_data, | |
|
467 | user=apiuser) | |
|
468 | ||
|
460 | 469 | Session().commit() |
|
461 | 470 | return { |
|
462 | 471 | 'msg': 'Granted perm: `%s` (recursive:%s) for user: ' |
@@ -527,10 +536,19 b' def revoke_user_permission_from_repo_gro' | |||
|
527 | 536 | |
|
528 | 537 | perm_deletions = [[user.user_id, None, "user"]] |
|
529 | 538 | try: |
|
530 |
RepoGroupModel().update_permissions( |
|
|
531 |
|
|
|
532 |
|
|
|
533 | cur_user=apiuser) | |
|
539 | changes = RepoGroupModel().update_permissions( | |
|
540 | repo_group=repo_group, perm_deletions=perm_deletions, | |
|
541 | recursive=apply_to_children, cur_user=apiuser) | |
|
542 | ||
|
543 | action_data = { | |
|
544 | 'added': changes['added'], | |
|
545 | 'updated': changes['updated'], | |
|
546 | 'deleted': changes['deleted'], | |
|
547 | } | |
|
548 | audit_logger.store_api( | |
|
549 | 'repo_group.edit.permissions', action_data=action_data, | |
|
550 | user=apiuser) | |
|
551 | ||
|
534 | 552 | Session().commit() |
|
535 | 553 | return { |
|
536 | 554 | 'msg': 'Revoked perm (recursive:%s) for user: ' |
@@ -611,10 +629,19 b' def grant_user_group_permission_to_repo_' | |||
|
611 | 629 | |
|
612 | 630 | perm_additions = [[user_group.users_group_id, perm.permission_name, "user_group"]] |
|
613 | 631 | try: |
|
614 |
RepoGroupModel().update_permissions( |
|
|
615 |
|
|
|
616 |
|
|
|
617 | cur_user=apiuser) | |
|
632 | changes = RepoGroupModel().update_permissions( | |
|
633 | repo_group=repo_group, perm_additions=perm_additions, | |
|
634 | recursive=apply_to_children, cur_user=apiuser) | |
|
635 | ||
|
636 | action_data = { | |
|
637 | 'added': changes['added'], | |
|
638 | 'updated': changes['updated'], | |
|
639 | 'deleted': changes['deleted'], | |
|
640 | } | |
|
641 | audit_logger.store_api( | |
|
642 | 'repo_group.edit.permissions', action_data=action_data, | |
|
643 | user=apiuser) | |
|
644 | ||
|
618 | 645 | Session().commit() |
|
619 | 646 | return { |
|
620 | 647 | 'msg': 'Granted perm: `%s` (recursive:%s) ' |
@@ -694,10 +721,19 b' def revoke_user_group_permission_from_re' | |||
|
694 | 721 | |
|
695 | 722 | perm_deletions = [[user_group.users_group_id, None, "user_group"]] |
|
696 | 723 | try: |
|
697 |
RepoGroupModel().update_permissions( |
|
|
698 |
|
|
|
699 |
|
|
|
700 | cur_user=apiuser) | |
|
724 | changes = RepoGroupModel().update_permissions( | |
|
725 | repo_group=repo_group, perm_deletions=perm_deletions, | |
|
726 | recursive=apply_to_children, cur_user=apiuser) | |
|
727 | ||
|
728 | action_data = { | |
|
729 | 'added': changes['added'], | |
|
730 | 'updated': changes['updated'], | |
|
731 | 'deleted': changes['deleted'], | |
|
732 | } | |
|
733 | audit_logger.store_api( | |
|
734 | 'repo_group.edit.permissions', action_data=action_data, | |
|
735 | user=apiuser) | |
|
736 | ||
|
701 | 737 | Session().commit() |
|
702 | 738 | return { |
|
703 | 739 | 'msg': 'Revoked perm (recursive:%s) for user group: ' |
@@ -716,4 +752,3 b' def revoke_user_group_permission_from_re' | |||
|
716 | 752 | user_group.users_group_name, repo_group.name |
|
717 | 753 | ) |
|
718 | 754 | ) |
|
719 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -21,6 +21,9 b'' | |||
|
21 | 21 | import inspect |
|
22 | 22 | import logging |
|
23 | 23 | import itertools |
|
24 | import base64 | |
|
25 | ||
|
26 | from pyramid import compat | |
|
24 | 27 | |
|
25 | 28 | from rhodecode.api import ( |
|
26 | 29 | jsonrpc_method, JSONRPCError, JSONRPCForbidden, find_methods) |
@@ -30,10 +33,15 b' from rhodecode.api.utils import (' | |||
|
30 | 33 | from rhodecode.lib.utils import repo2db_mapper |
|
31 | 34 | from rhodecode.lib import system_info |
|
32 | 35 | from rhodecode.lib import user_sessions |
|
36 | from rhodecode.lib import exc_tracking | |
|
37 | from rhodecode.lib.ext_json import json | |
|
33 | 38 | from rhodecode.lib.utils2 import safe_int |
|
34 | 39 | from rhodecode.model.db import UserIpMap |
|
35 | 40 | from rhodecode.model.scm import ScmModel |
|
36 | 41 | from rhodecode.model.settings import VcsSettingsModel |
|
42 | from rhodecode.apps.file_store import utils | |
|
43 | from rhodecode.apps.file_store.exceptions import FileNotAllowedException, \ | |
|
44 | FileOverSizeException | |
|
37 | 45 | |
|
38 | 46 | log = logging.getLogger(__name__) |
|
39 | 47 | |
@@ -293,7 +301,7 b' def get_method(request, apiuser, pattern' | |||
|
293 | 301 | :param apiuser: This is filled automatically from the |authtoken|. |
|
294 | 302 | :type apiuser: AuthUser |
|
295 | 303 | :param pattern: pattern to match method names against |
|
296 |
:type |
|
|
304 | :type pattern: Optional("*") | |
|
297 | 305 | |
|
298 | 306 | Example output: |
|
299 | 307 | |
@@ -349,3 +357,63 b' def get_method(request, apiuser, pattern' | |||
|
349 | 357 | args_desc.append(func_kwargs) |
|
350 | 358 | |
|
351 | 359 | return matches.keys() + args_desc |
|
360 | ||
|
361 | ||
|
362 | @jsonrpc_method() | |
|
363 | def store_exception(request, apiuser, exc_data_json, prefix=Optional('rhodecode')): | |
|
364 | """ | |
|
365 | Stores sent exception inside the built-in exception tracker in |RCE| server. | |
|
366 | ||
|
367 | This command can only be run using an |authtoken| with admin rights to | |
|
368 | the specified repository. | |
|
369 | ||
|
370 | This command takes the following options: | |
|
371 | ||
|
372 | :param apiuser: This is filled automatically from the |authtoken|. | |
|
373 | :type apiuser: AuthUser | |
|
374 | ||
|
375 | :param exc_data_json: JSON data with exception e.g | |
|
376 | {"exc_traceback": "Value `1` is not allowed", "exc_type_name": "ValueError"} | |
|
377 | :type exc_data_json: JSON data | |
|
378 | ||
|
379 | :param prefix: prefix for error type, e.g 'rhodecode', 'vcsserver', 'rhodecode-tools' | |
|
380 | :type prefix: Optional("rhodecode") | |
|
381 | ||
|
382 | Example output: | |
|
383 | ||
|
384 | .. code-block:: bash | |
|
385 | ||
|
386 | id : <id_given_in_input> | |
|
387 | "result": { | |
|
388 | "exc_id": 139718459226384, | |
|
389 | "exc_url": "http://localhost:8080/_admin/settings/exceptions/139718459226384" | |
|
390 | } | |
|
391 | error : null | |
|
392 | """ | |
|
393 | if not has_superadmin_permission(apiuser): | |
|
394 | raise JSONRPCForbidden() | |
|
395 | ||
|
396 | prefix = Optional.extract(prefix) | |
|
397 | exc_id = exc_tracking.generate_id() | |
|
398 | ||
|
399 | try: | |
|
400 | exc_data = json.loads(exc_data_json) | |
|
401 | except Exception: | |
|
402 | log.error('Failed to parse JSON: %r', exc_data_json) | |
|
403 | raise JSONRPCError('Failed to parse JSON data from exc_data_json field. ' | |
|
404 | 'Please make sure it contains a valid JSON.') | |
|
405 | ||
|
406 | try: | |
|
407 | exc_traceback = exc_data['exc_traceback'] | |
|
408 | exc_type_name = exc_data['exc_type_name'] | |
|
409 | except KeyError as err: | |
|
410 | raise JSONRPCError('Missing exc_traceback, or exc_type_name ' | |
|
411 | 'in exc_data_json field. Missing: {}'.format(err)) | |
|
412 | ||
|
413 | exc_tracking._store_exception( | |
|
414 | exc_id=exc_id, exc_traceback=exc_traceback, | |
|
415 | exc_type_name=exc_type_name, prefix=prefix) | |
|
416 | ||
|
417 | exc_url = request.route_url( | |
|
418 | 'admin_settings_exception_tracker_show', exception_id=exc_id) | |
|
419 | return {'exc_id': exc_id, 'exc_url': exc_url} |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -19,6 +19,7 b'' | |||
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | 21 | import logging |
|
22 | from pyramid import compat | |
|
22 | 23 | |
|
23 | 24 | from rhodecode.api import ( |
|
24 | 25 | jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError) |
@@ -241,7 +242,7 b' def create_user(request, apiuser, userna' | |||
|
241 | 242 | # generate temporary password if user is external |
|
242 | 243 | password = PasswordGenerator().gen_password(length=16) |
|
243 | 244 | create_repo_group = Optional.extract(create_personal_repo_group) |
|
244 |
if isinstance(create_repo_group, |
|
|
245 | if isinstance(create_repo_group, compat.string_types): | |
|
245 | 246 | create_repo_group = str2bool(create_repo_group) |
|
246 | 247 | |
|
247 | 248 | username = Optional.extract(username) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -22,11 +22,12 b' import time' | |||
|
22 | 22 | import logging |
|
23 | 23 | import operator |
|
24 | 24 | |
|
25 | from pyramid import compat | |
|
25 | 26 | from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPBadRequest |
|
26 | 27 | |
|
27 | 28 | from rhodecode.lib import helpers as h, diffs |
|
28 | 29 | from rhodecode.lib.utils2 import ( |
|
29 | StrictAttributeDict, safe_int, datetime_to_time, safe_unicode) | |
|
30 | StrictAttributeDict, str2bool, safe_int, datetime_to_time, safe_unicode) | |
|
30 | 31 | from rhodecode.lib.vcs.exceptions import RepositoryRequirementError |
|
31 | 32 | from rhodecode.model import repo |
|
32 | 33 | from rhodecode.model import repo_group |
@@ -249,6 +250,12 b' class RepoAppView(BaseAppView):' | |||
|
249 | 250 | else: # redirect if we don't show missing requirements |
|
250 | 251 | raise HTTPFound(h.route_path('home')) |
|
251 | 252 | |
|
253 | c.has_origin_repo_read_perm = False | |
|
254 | if self.db_repo.fork: | |
|
255 | c.has_origin_repo_read_perm = h.HasRepoPermissionAny( | |
|
256 | 'repository.write', 'repository.read', 'repository.admin')( | |
|
257 | self.db_repo.fork.repo_name, 'summary fork link') | |
|
258 | ||
|
252 | 259 | return c |
|
253 | 260 | |
|
254 | 261 | def _get_f_path_unchecked(self, matchdict, default=None): |
@@ -271,6 +278,13 b' class RepoAppView(BaseAppView):' | |||
|
271 | 278 | settings = settings_model.get_general_settings() |
|
272 | 279 | return settings.get(settings_key, default) |
|
273 | 280 | |
|
281 | def get_recache_flag(self): | |
|
282 | for flag_name in ['force_recache', 'force-recache', 'no-cache']: | |
|
283 | flag_val = self.request.GET.get(flag_name) | |
|
284 | if str2bool(flag_val): | |
|
285 | return True | |
|
286 | return False | |
|
287 | ||
|
274 | 288 | |
|
275 | 289 | class PathFilter(object): |
|
276 | 290 | |
@@ -327,6 +341,13 b' class RepoGroupAppView(BaseAppView):' | |||
|
327 | 341 | self.db_repo_group = request.db_repo_group |
|
328 | 342 | self.db_repo_group_name = self.db_repo_group.group_name |
|
329 | 343 | |
|
344 | def _get_local_tmpl_context(self, include_app_defaults=True): | |
|
345 | _ = self.request.translate | |
|
346 | c = super(RepoGroupAppView, self)._get_local_tmpl_context( | |
|
347 | include_app_defaults=include_app_defaults) | |
|
348 | c.repo_group = self.db_repo_group | |
|
349 | return c | |
|
350 | ||
|
330 | 351 | def _revoke_perms_on_yourself(self, form_result): |
|
331 | 352 | _updates = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), |
|
332 | 353 | form_result['perm_updates']) |
@@ -389,7 +410,7 b' class DataGridAppView(object):' | |||
|
389 | 410 | return draw, start, length |
|
390 | 411 | |
|
391 | 412 | def _get_order_col(self, order_by, model): |
|
392 |
if isinstance(order_by, |
|
|
413 | if isinstance(order_by, compat.string_types): | |
|
393 | 414 | try: |
|
394 | 415 | return operator.attrgetter(order_by)(model) |
|
395 | 416 | except AttributeError: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -280,8 +280,12 b' def admin_routes(config):' | |||
|
280 | 280 | pattern='/users/{user_id:\d+}/delete', |
|
281 | 281 | user_route=True) |
|
282 | 282 | config.add_route( |
|
283 | name='user_force_password_reset', | |
|
284 | pattern='/users/{user_id:\d+}/password_reset', | |
|
283 | name='user_enable_force_password_reset', | |
|
284 | pattern='/users/{user_id:\d+}/password_reset_enable', | |
|
285 | user_route=True) | |
|
286 | config.add_route( | |
|
287 | name='user_disable_force_password_reset', | |
|
288 | pattern='/users/{user_id:\d+}/password_reset_disable', | |
|
285 | 289 | user_route=True) |
|
286 | 290 | config.add_route( |
|
287 | 291 | name='user_create_personal_repo_group', |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -59,8 +59,6 b' def route_path(name, params=None, **kwar' | |||
|
59 | 59 | ADMIN_PREFIX + '/users/{user_id}/update', |
|
60 | 60 | 'user_delete': |
|
61 | 61 | ADMIN_PREFIX + '/users/{user_id}/delete', |
|
62 | 'user_force_password_reset': | |
|
63 | ADMIN_PREFIX + '/users/{user_id}/password_reset', | |
|
64 | 62 | 'user_create_personal_repo_group': |
|
65 | 63 | ADMIN_PREFIX + '/users/{user_id}/create_repo_group', |
|
66 | 64 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2018-201 |
|
|
3 | # Copyright (C) 2018-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -119,8 +119,7 b' class AdminProcessManagementView(BaseApp' | |||
|
119 | 119 | result = [] |
|
120 | 120 | |
|
121 | 121 | def on_terminate(proc): |
|
122 | msg = "process `PID:{}` terminated with exit code {}".format( | |
|
123 | proc.pid, proc.returncode or 0) | |
|
122 | msg = "terminated" | |
|
124 | 123 | result.append(msg) |
|
125 | 124 | |
|
126 | 125 | procs = [] |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -666,8 +666,8 b' class AdminSettingsView(BaseAppView):' | |||
|
666 | 666 | c = self.load_default_context() |
|
667 | 667 | c.active = 'search' |
|
668 | 668 | |
|
669 | searcher = searcher_from_config(self.request.registry.settings) | |
|
670 | c.statistics = searcher.statistics(self.request.translate) | |
|
669 | c.searcher = searcher_from_config(self.request.registry.settings) | |
|
670 | c.statistics = c.searcher.statistics(self.request.translate) | |
|
671 | 671 | |
|
672 | 672 | return self._get_template_context(c) |
|
673 | 673 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -604,12 +604,9 b' class UsersView(UserAppView):' | |||
|
604 | 604 | @HasPermissionAllDecorator('hg.admin') |
|
605 | 605 | @CSRFRequired() |
|
606 | 606 | @view_config( |
|
607 | route_name='user_force_password_reset', request_method='POST', | |
|
607 | route_name='user_enable_force_password_reset', request_method='POST', | |
|
608 | 608 | renderer='rhodecode:templates/admin/users/user_edit.mako') |
|
609 | def user_force_password_reset(self): | |
|
610 | """ | |
|
611 | toggle reset password flag for this user | |
|
612 | """ | |
|
609 | def user_enable_force_password_reset(self): | |
|
613 | 610 | _ = self.request.translate |
|
614 | 611 | c = self.load_default_context() |
|
615 | 612 | |
@@ -617,19 +614,41 b' class UsersView(UserAppView):' | |||
|
617 | 614 | c.user = self.db_user |
|
618 | 615 | |
|
619 | 616 | try: |
|
620 |
|
|
|
621 | c.user.update_userdata(force_password_change=not old_value) | |
|
617 | c.user.update_userdata(force_password_change=True) | |
|
618 | ||
|
619 | msg = _('Force password change enabled for user') | |
|
620 | audit_logger.store_web('user.edit.password_reset.enabled', | |
|
621 | user=c.rhodecode_user) | |
|
622 | ||
|
623 | Session().commit() | |
|
624 | h.flash(msg, category='success') | |
|
625 | except Exception: | |
|
626 | log.exception("Exception during password reset for user") | |
|
627 | h.flash(_('An error occurred during password reset for user'), | |
|
628 | category='error') | |
|
629 | ||
|
630 | raise HTTPFound(h.route_path('user_edit_advanced', user_id=user_id)) | |
|
622 | 631 | |
|
623 | if old_value: | |
|
624 | msg = _('Force password change disabled for user') | |
|
625 | audit_logger.store_web( | |
|
626 | 'user.edit.password_reset.disabled', | |
|
627 | user=c.rhodecode_user) | |
|
628 | else: | |
|
629 | msg = _('Force password change enabled for user') | |
|
630 | audit_logger.store_web( | |
|
631 | 'user.edit.password_reset.enabled', | |
|
632 | user=c.rhodecode_user) | |
|
632 | @LoginRequired() | |
|
633 | @HasPermissionAllDecorator('hg.admin') | |
|
634 | @CSRFRequired() | |
|
635 | @view_config( | |
|
636 | route_name='user_disable_force_password_reset', request_method='POST', | |
|
637 | renderer='rhodecode:templates/admin/users/user_edit.mako') | |
|
638 | def user_disable_force_password_reset(self): | |
|
639 | _ = self.request.translate | |
|
640 | c = self.load_default_context() | |
|
641 | ||
|
642 | user_id = self.db_user_id | |
|
643 | c.user = self.db_user | |
|
644 | ||
|
645 | try: | |
|
646 | c.user.update_userdata(force_password_change=False) | |
|
647 | ||
|
648 | msg = _('Force password change disabled for user') | |
|
649 | audit_logger.store_web( | |
|
650 | 'user.edit.password_reset.disabled', | |
|
651 | user=c.rhodecode_user) | |
|
633 | 652 | |
|
634 | 653 | Session().commit() |
|
635 | 654 | h.flash(msg, category='success') |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2013-201 |
|
|
3 | # Copyright (C) 2013-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -56,6 +56,10 b' def includeme(config):' | |||
|
56 | 56 | pattern='/_repos') |
|
57 | 57 | |
|
58 | 58 | config.add_route( |
|
59 | name='repo_group_list_data', | |
|
60 | pattern='/_repo_groups') | |
|
61 | ||
|
62 | config.add_route( | |
|
59 | 63 | name='goto_switcher_data', |
|
60 | 64 | pattern='/_goto_data') |
|
61 | 65 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -31,7 +31,14 b' def assert_and_get_main_filter_content(r' | |||
|
31 | 31 | assert data_item['url'] |
|
32 | 32 | |
|
33 | 33 | if data_item['type'] == 'search': |
|
34 |
|
|
|
34 | display_val = data_item['value_display'] | |
|
35 | if data_item['id'] == -1: | |
|
36 | assert 'File search for:' in display_val, display_val | |
|
37 | elif data_item['id'] == -2: | |
|
38 | assert 'Commit search for:' in display_val, display_val | |
|
39 | else: | |
|
40 | assert False, 'No Proper ID returned {}'.format(data_item['id']) | |
|
41 | ||
|
35 | 42 | elif data_item['type'] == 'repo': |
|
36 | 43 | repos.append(data_item) |
|
37 | 44 | elif data_item['type'] == 'repo_group': |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -19,7 +19,7 b'' | |||
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | # -*- coding: utf-8 -*- |
|
21 | 21 | |
|
22 |
# Copyright (C) 2016-201 |
|
|
22 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
23 | 23 | # |
|
24 | 24 | # This program is free software: you can redistribute it and/or modify |
|
25 | 25 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -172,7 +172,9 b' class HomeView(BaseAppView):' | |||
|
172 | 172 | 'id': obj.group_name, |
|
173 | 173 | 'value': org_query, |
|
174 | 174 | 'value_display': obj.group_name, |
|
175 | 'text': obj.group_name, | |
|
175 | 176 | 'type': 'repo_group', |
|
177 | 'repo_group_id': obj.group_id, | |
|
176 | 178 | 'url': h.route_path( |
|
177 | 179 | 'repo_group_home', repo_group_name=obj.group_name) |
|
178 | 180 | } |
@@ -246,9 +248,9 b' class HomeView(BaseAppView):' | |||
|
246 | 248 | } |
|
247 | 249 | for obj in acl_iter] |
|
248 | 250 | |
|
249 | def _get_hash_commit_list(self, auth_user, query): | |
|
251 | def _get_hash_commit_list(self, auth_user, searcher, query): | |
|
250 | 252 | org_query = query |
|
251 | if not query or len(query) < 3: | |
|
253 | if not query or len(query) < 3 or not searcher: | |
|
252 | 254 | return [] |
|
253 | 255 | |
|
254 | 256 | commit_hashes = re.compile('(?:commit:)([0-9a-f]{2,40})').findall(query) |
@@ -257,24 +259,34 b' class HomeView(BaseAppView):' | |||
|
257 | 259 | return [] |
|
258 | 260 | commit_hash = commit_hashes[0] |
|
259 | 261 | |
|
260 | searcher = searcher_from_config(self.request.registry.settings) | |
|
261 | 262 | result = searcher.search( |
|
262 |
'commit_id: |
|
|
263 | 'commit_id:{}*'.format(commit_hash), 'commit', auth_user, | |
|
263 | 264 | raise_on_exc=False) |
|
264 | 265 | |
|
265 |
|
|
|
266 | { | |
|
266 | commits = [] | |
|
267 | for entry in result['results']: | |
|
268 | repo_data = { | |
|
269 | 'repository_id': entry.get('repository_id'), | |
|
270 | 'repository_type': entry.get('repo_type'), | |
|
271 | 'repository_name': entry.get('repository'), | |
|
272 | } | |
|
273 | ||
|
274 | commit_entry = { | |
|
267 | 275 | 'id': entry['commit_id'], |
|
268 | 276 | 'value': org_query, |
|
269 |
'value_display': ' |
|
|
277 | 'value_display': '`{}` commit: {}'.format( | |
|
270 | 278 | entry['repository'], entry['commit_id']), |
|
271 | 279 | 'type': 'commit', |
|
272 | 280 | 'repo': entry['repository'], |
|
281 | 'repo_data': repo_data, | |
|
282 | ||
|
273 | 283 | 'url': h.route_path( |
|
274 | 284 | 'repo_commit', |
|
275 | 285 | repo_name=entry['repository'], commit_id=entry['commit_id']) |
|
276 | 286 | } |
|
277 | for entry in result['results']] | |
|
287 | ||
|
288 | commits.append(commit_entry) | |
|
289 | return commits | |
|
278 | 290 | |
|
279 | 291 | @LoginRequired() |
|
280 | 292 | @view_config( |
@@ -305,6 +317,144 b' class HomeView(BaseAppView):' | |||
|
305 | 317 | |
|
306 | 318 | @LoginRequired() |
|
307 | 319 | @view_config( |
|
320 | route_name='repo_group_list_data', request_method='GET', | |
|
321 | renderer='json_ext', xhr=True) | |
|
322 | def repo_group_list_data(self): | |
|
323 | _ = self.request.translate | |
|
324 | self.load_default_context() | |
|
325 | ||
|
326 | query = self.request.GET.get('query') | |
|
327 | ||
|
328 | log.debug('generating repo group list, query:%s', | |
|
329 | query) | |
|
330 | ||
|
331 | res = [] | |
|
332 | repo_groups = self._get_repo_group_list(query) | |
|
333 | if repo_groups: | |
|
334 | res.append({ | |
|
335 | 'text': _('Repository Groups'), | |
|
336 | 'children': repo_groups | |
|
337 | }) | |
|
338 | ||
|
339 | data = { | |
|
340 | 'more': False, | |
|
341 | 'results': res | |
|
342 | } | |
|
343 | return data | |
|
344 | ||
|
345 | def _get_default_search_queries(self, search_context, searcher, query): | |
|
346 | if not searcher: | |
|
347 | return [] | |
|
348 | ||
|
349 | is_es_6 = searcher.is_es_6 | |
|
350 | ||
|
351 | queries = [] | |
|
352 | repo_group_name, repo_name, repo_context = None, None, None | |
|
353 | ||
|
354 | # repo group context | |
|
355 | if search_context.get('search_context[repo_group_name]'): | |
|
356 | repo_group_name = search_context.get('search_context[repo_group_name]') | |
|
357 | if search_context.get('search_context[repo_name]'): | |
|
358 | repo_name = search_context.get('search_context[repo_name]') | |
|
359 | repo_context = search_context.get('search_context[repo_view_type]') | |
|
360 | ||
|
361 | if is_es_6 and repo_name: | |
|
362 | # files | |
|
363 | def query_modifier(): | |
|
364 | qry = query | |
|
365 | return {'q': qry, 'type': 'content'} | |
|
366 | label = u'File search for `{}` in this repository.'.format(query) | |
|
367 | queries.append( | |
|
368 | { | |
|
369 | 'id': -10, | |
|
370 | 'value': query, | |
|
371 | 'value_display': label, | |
|
372 | 'type': 'search', | |
|
373 | 'url': h.route_path('search_repo', | |
|
374 | repo_name=repo_name, | |
|
375 | _query=query_modifier()) | |
|
376 | } | |
|
377 | ) | |
|
378 | ||
|
379 | # commits | |
|
380 | def query_modifier(): | |
|
381 | qry = query | |
|
382 | return {'q': qry, 'type': 'commit'} | |
|
383 | ||
|
384 | label = u'Commit search for `{}` in this repository.'.format(query) | |
|
385 | queries.append( | |
|
386 | { | |
|
387 | 'id': -20, | |
|
388 | 'value': query, | |
|
389 | 'value_display': label, | |
|
390 | 'type': 'search', | |
|
391 | 'url': h.route_path('search_repo', | |
|
392 | repo_name=repo_name, | |
|
393 | _query=query_modifier()) | |
|
394 | } | |
|
395 | ) | |
|
396 | ||
|
397 | elif is_es_6 and repo_group_name: | |
|
398 | # files | |
|
399 | def query_modifier(): | |
|
400 | qry = query | |
|
401 | return {'q': qry, 'type': 'content'} | |
|
402 | ||
|
403 | label = u'File search for `{}` in this repository group'.format(query) | |
|
404 | queries.append( | |
|
405 | { | |
|
406 | 'id': -30, | |
|
407 | 'value': query, | |
|
408 | 'value_display': label, | |
|
409 | 'type': 'search', | |
|
410 | 'url': h.route_path('search_repo_group', | |
|
411 | repo_group_name=repo_group_name, | |
|
412 | _query=query_modifier()) | |
|
413 | } | |
|
414 | ) | |
|
415 | ||
|
416 | # commits | |
|
417 | def query_modifier(): | |
|
418 | qry = query | |
|
419 | return {'q': qry, 'type': 'commit'} | |
|
420 | ||
|
421 | label = u'Commit search for `{}` in this repository group'.format(query) | |
|
422 | queries.append( | |
|
423 | { | |
|
424 | 'id': -40, | |
|
425 | 'value': query, | |
|
426 | 'value_display': label, | |
|
427 | 'type': 'search', | |
|
428 | 'url': h.route_path('search_repo_group', | |
|
429 | repo_group_name=repo_group_name, | |
|
430 | _query=query_modifier()) | |
|
431 | } | |
|
432 | ) | |
|
433 | ||
|
434 | if not queries: | |
|
435 | queries.append( | |
|
436 | { | |
|
437 | 'id': -1, | |
|
438 | 'value': query, | |
|
439 | 'value_display': u'File search for: `{}`'.format(query), | |
|
440 | 'type': 'search', | |
|
441 | 'url': h.route_path('search', | |
|
442 | _query={'q': query, 'type': 'content'}) | |
|
443 | }) | |
|
444 | queries.append( | |
|
445 | { | |
|
446 | 'id': -2, | |
|
447 | 'value': query, | |
|
448 | 'value_display': u'Commit search for: `{}`'.format(query), | |
|
449 | 'type': 'search', | |
|
450 | 'url': h.route_path('search', | |
|
451 | _query={'q': query, 'type': 'commit'}) | |
|
452 | }) | |
|
453 | ||
|
454 | return queries | |
|
455 | ||
|
456 | @LoginRequired() | |
|
457 | @view_config( | |
|
308 | 458 | route_name='goto_switcher_data', request_method='GET', |
|
309 | 459 | renderer='json_ext', xhr=True) |
|
310 | 460 | def goto_switcher_data(self): |
@@ -315,26 +465,21 b' class HomeView(BaseAppView):' | |||
|
315 | 465 | query = self.request.GET.get('query') |
|
316 | 466 | log.debug('generating main filter data, query %s', query) |
|
317 | 467 | |
|
318 | default_search_val = u'Full text search for: `{}`'.format(query) | |
|
319 | 468 | res = [] |
|
320 | 469 | if not query: |
|
321 | 470 | return {'suggestions': res} |
|
322 | 471 | |
|
323 | res.append({ | |
|
324 | 'id': -1, | |
|
325 | 'value': query, | |
|
326 | 'value_display': default_search_val, | |
|
327 | 'type': 'search', | |
|
328 | 'url': h.route_path( | |
|
329 | 'search', _query={'q': query}) | |
|
330 | }) | |
|
331 | repo_group_id = safe_int(self.request.GET.get('repo_group_id')) | |
|
472 | searcher = searcher_from_config(self.request.registry.settings) | |
|
473 | for _q in self._get_default_search_queries(self.request.GET, searcher, query): | |
|
474 | res.append(_q) | |
|
475 | ||
|
476 | repo_group_id = safe_int(self.request.GET.get('search_context[repo_group_id]')) | |
|
332 | 477 | if repo_group_id: |
|
333 | 478 | repo_group = RepoGroup.get(repo_group_id) |
|
334 | 479 | composed_hint = '{}/{}'.format(repo_group.group_name, query) |
|
335 | 480 | show_hint = not query.startswith(repo_group.group_name) |
|
336 | 481 | if repo_group and show_hint: |
|
337 |
hint = u' |
|
|
482 | hint = u'Repository search inside: `{}`'.format(composed_hint) | |
|
338 | 483 | res.append({ |
|
339 | 484 | 'id': -1, |
|
340 | 485 | 'value': composed_hint, |
@@ -351,7 +496,7 b' class HomeView(BaseAppView):' | |||
|
351 | 496 | for serialized_repo in repos: |
|
352 | 497 | res.append(serialized_repo) |
|
353 | 498 | |
|
354 | # TODO(marcink): permissions for that ? | |
|
499 | # TODO(marcink): should all logged in users be allowed to search others? | |
|
355 | 500 | allowed_user_search = self._rhodecode_user.username != User.DEFAULT_USER |
|
356 | 501 | if allowed_user_search: |
|
357 | 502 | users = self._get_user_list(query) |
@@ -362,7 +507,7 b' class HomeView(BaseAppView):' | |||
|
362 | 507 | for serialized_user_group in user_groups: |
|
363 | 508 | res.append(serialized_user_group) |
|
364 | 509 | |
|
365 | commits = self._get_hash_commit_list(c.auth_user, query) | |
|
510 | commits = self._get_hash_commit_list(c.auth_user, searcher, query) | |
|
366 | 511 | if commits: |
|
367 | 512 | unique_repos = collections.OrderedDict() |
|
368 | 513 | for commit in commits: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -107,6 +107,26 b' class TestLoginController(object):' | |||
|
107 | 107 | |
|
108 | 108 | response.mustcontain('/%s' % HG_REPO) |
|
109 | 109 | |
|
110 | def test_login_regular_forbidden_when_super_admin_restriction(self): | |
|
111 | from rhodecode.authentication.plugins.auth_rhodecode import RhodeCodeAuthPlugin | |
|
112 | with fixture.auth_restriction(RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN): | |
|
113 | response = self.app.post(route_path('login'), | |
|
114 | {'username': 'test_regular', | |
|
115 | 'password': 'test12'}) | |
|
116 | ||
|
117 | response.mustcontain('invalid user name') | |
|
118 | response.mustcontain('invalid password') | |
|
119 | ||
|
120 | def test_login_regular_forbidden_when_scope_restriction(self): | |
|
121 | from rhodecode.authentication.plugins.auth_rhodecode import RhodeCodeAuthPlugin | |
|
122 | with fixture.scope_restriction(RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_VCS): | |
|
123 | response = self.app.post(route_path('login'), | |
|
124 | {'username': 'test_regular', | |
|
125 | 'password': 'test12'}) | |
|
126 | ||
|
127 | response.mustcontain('invalid user name') | |
|
128 | response.mustcontain('invalid password') | |
|
129 | ||
|
110 | 130 | def test_login_ok_came_from(self): |
|
111 | 131 | test_came_from = '/_admin/users?branch=stable' |
|
112 | 132 | _url = '{}?came_from={}'.format(route_path('login'), test_came_from) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -74,20 +74,17 b' class TestPasswordReset(TestController):' | |||
|
74 | 74 | 'default_password_reset': pwd_reset_setting, |
|
75 | 75 | 'default_extern_activate': 'hg.extern_activate.auto', |
|
76 | 76 | } |
|
77 | resp = self.app.post(route_path('admin_permissions_application_update'), params=params) | |
|
77 | resp = self.app.post( | |
|
78 | route_path('admin_permissions_application_update'), params=params) | |
|
78 | 79 | self.logout_user() |
|
79 | 80 | |
|
80 | 81 | login_page = self.app.get(route_path('login')) |
|
81 | 82 | asr_login = AssertResponse(login_page) |
|
82 | index_page = self.app.get(h.route_path('home')) | |
|
83 | asr_index = AssertResponse(index_page) | |
|
84 | 83 | |
|
85 | 84 | if show_link: |
|
86 | 85 | asr_login.one_element_exists('a.pwd_reset') |
|
87 | asr_index.one_element_exists('a.pwd_reset') | |
|
88 | 86 | else: |
|
89 | 87 | asr_login.no_element_exists('a.pwd_reset') |
|
90 | asr_index.no_element_exists('a.pwd_reset') | |
|
91 | 88 | |
|
92 | 89 | response = self.app.get(route_path('reset_password')) |
|
93 | 90 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -95,6 +95,18 b' def includeme(config):' | |||
|
95 | 95 | pattern=ADMIN_PREFIX + '/my_account/watched') |
|
96 | 96 | |
|
97 | 97 | config.add_route( |
|
98 | name='my_account_bookmarks', | |
|
99 | pattern=ADMIN_PREFIX + '/my_account/bookmarks') | |
|
100 | ||
|
101 | config.add_route( | |
|
102 | name='my_account_bookmarks_update', | |
|
103 | pattern=ADMIN_PREFIX + '/my_account/bookmarks/update') | |
|
104 | ||
|
105 | config.add_route( | |
|
106 | name='my_account_goto_bookmark', | |
|
107 | pattern=ADMIN_PREFIX + '/my_account/bookmark/{bookmark_id}') | |
|
108 | ||
|
109 | config.add_route( | |
|
98 | 110 | name='my_account_perms', |
|
99 | 111 | pattern=ADMIN_PREFIX + '/my_account/perms') |
|
100 | 112 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -19,7 +19,7 b'' | |||
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | # -*- coding: utf-8 -*- |
|
21 | 21 | |
|
22 |
# Copyright (C) 2016-201 |
|
|
22 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
23 | 23 | # |
|
24 | 24 | # This program is free software: you can redistribute it and/or modify |
|
25 | 25 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -20,29 +20,30 b'' | |||
|
20 | 20 | |
|
21 | 21 | import logging |
|
22 | 22 | import datetime |
|
23 | import string | |
|
23 | 24 | |
|
24 | 25 | import formencode |
|
25 | 26 | import formencode.htmlfill |
|
27 | import peppercorn | |
|
26 | 28 | from pyramid.httpexceptions import HTTPFound |
|
27 | 29 | from pyramid.view import view_config |
|
28 | from pyramid.renderers import render | |
|
29 | from pyramid.response import Response | |
|
30 | 30 | |
|
31 | 31 | from rhodecode.apps._base import BaseAppView, DataGridAppView |
|
32 | 32 | from rhodecode import forms |
|
33 | 33 | from rhodecode.lib import helpers as h |
|
34 | 34 | from rhodecode.lib import audit_logger |
|
35 | 35 | from rhodecode.lib.ext_json import json |
|
36 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired | |
|
36 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired, \ | |
|
37 | HasRepoPermissionAny, HasRepoGroupPermissionAny | |
|
37 | 38 | from rhodecode.lib.channelstream import ( |
|
38 | 39 | channelstream_request, ChannelstreamException) |
|
39 | 40 | from rhodecode.lib.utils2 import safe_int, md5, str2bool |
|
40 | 41 | from rhodecode.model.auth_token import AuthTokenModel |
|
41 | 42 | from rhodecode.model.comment import CommentsModel |
|
42 | 43 | from rhodecode.model.db import ( |
|
43 | Repository, UserEmailMap, UserApiKeys, UserFollowing, joinedload, | |
|
44 | PullRequest) | |
|
45 | from rhodecode.model.forms import UserForm, UserExtraEmailForm | |
|
44 | IntegrityError, joinedload, | |
|
45 | Repository, UserEmailMap, UserApiKeys, UserFollowing, | |
|
46 | PullRequest, UserBookmark, RepoGroup) | |
|
46 | 47 | from rhodecode.model.meta import Session |
|
47 | 48 | from rhodecode.model.pull_request import PullRequestModel |
|
48 | 49 | from rhodecode.model.scm import RepoList |
@@ -392,6 +393,140 b' class MyAccountView(BaseAppView, DataGri' | |||
|
392 | 393 | @LoginRequired() |
|
393 | 394 | @NotAnonymous() |
|
394 | 395 | @view_config( |
|
396 | route_name='my_account_bookmarks', request_method='GET', | |
|
397 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |
|
398 | def my_account_bookmarks(self): | |
|
399 | c = self.load_default_context() | |
|
400 | c.active = 'bookmarks' | |
|
401 | return self._get_template_context(c) | |
|
402 | ||
|
403 | def _process_entry(self, entry, user_id): | |
|
404 | position = safe_int(entry.get('position')) | |
|
405 | if position is None: | |
|
406 | return | |
|
407 | ||
|
408 | # check if this is an existing entry | |
|
409 | is_new = False | |
|
410 | db_entry = UserBookmark().get_by_position_for_user(position, user_id) | |
|
411 | ||
|
412 | if db_entry and str2bool(entry.get('remove')): | |
|
413 | log.debug('Marked bookmark %s for deletion', db_entry) | |
|
414 | Session().delete(db_entry) | |
|
415 | return | |
|
416 | ||
|
417 | if not db_entry: | |
|
418 | # new | |
|
419 | db_entry = UserBookmark() | |
|
420 | is_new = True | |
|
421 | ||
|
422 | should_save = False | |
|
423 | default_redirect_url = '' | |
|
424 | ||
|
425 | # save repo | |
|
426 | if entry.get('bookmark_repo'): | |
|
427 | repo = Repository.get(entry['bookmark_repo']) | |
|
428 | perm_check = HasRepoPermissionAny( | |
|
429 | 'repository.read', 'repository.write', 'repository.admin') | |
|
430 | if repo and perm_check(repo_name=repo.repo_name): | |
|
431 | db_entry.repository = repo | |
|
432 | should_save = True | |
|
433 | default_redirect_url = '${repo_url}' | |
|
434 | # save repo group | |
|
435 | elif entry.get('bookmark_repo_group'): | |
|
436 | repo_group = RepoGroup.get(entry['bookmark_repo_group']) | |
|
437 | perm_check = HasRepoGroupPermissionAny( | |
|
438 | 'group.read', 'group.write', 'group.admin') | |
|
439 | ||
|
440 | if repo_group and perm_check(group_name=repo_group.group_name): | |
|
441 | db_entry.repository_group = repo_group | |
|
442 | should_save = True | |
|
443 | default_redirect_url = '${repo_group_url}' | |
|
444 | # save generic info | |
|
445 | elif entry.get('title') and entry.get('redirect_url'): | |
|
446 | should_save = True | |
|
447 | ||
|
448 | if should_save: | |
|
449 | log.debug('Saving bookmark %s, new:%s', db_entry, is_new) | |
|
450 | # mark user and position | |
|
451 | db_entry.user_id = user_id | |
|
452 | db_entry.position = position | |
|
453 | db_entry.title = entry.get('title') | |
|
454 | db_entry.redirect_url = entry.get('redirect_url') or default_redirect_url | |
|
455 | ||
|
456 | Session().add(db_entry) | |
|
457 | ||
|
458 | @LoginRequired() | |
|
459 | @NotAnonymous() | |
|
460 | @CSRFRequired() | |
|
461 | @view_config( | |
|
462 | route_name='my_account_bookmarks_update', request_method='POST') | |
|
463 | def my_account_bookmarks_update(self): | |
|
464 | _ = self.request.translate | |
|
465 | c = self.load_default_context() | |
|
466 | c.active = 'bookmarks' | |
|
467 | ||
|
468 | controls = peppercorn.parse(self.request.POST.items()) | |
|
469 | user_id = c.user.user_id | |
|
470 | ||
|
471 | try: | |
|
472 | for entry in controls.get('bookmarks', []): | |
|
473 | self._process_entry(entry, user_id) | |
|
474 | ||
|
475 | Session().commit() | |
|
476 | h.flash(_("Update Bookmarks"), category='success') | |
|
477 | except IntegrityError: | |
|
478 | h.flash(_("Failed to update bookmarks. " | |
|
479 | "Make sure an unique position is used"), category='error') | |
|
480 | ||
|
481 | return HTTPFound(h.route_path('my_account_bookmarks')) | |
|
482 | ||
|
483 | @LoginRequired() | |
|
484 | @NotAnonymous() | |
|
485 | @view_config( | |
|
486 | route_name='my_account_goto_bookmark', request_method='GET', | |
|
487 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |
|
488 | def my_account_goto_bookmark(self): | |
|
489 | ||
|
490 | bookmark_id = self.request.matchdict['bookmark_id'] | |
|
491 | user_bookmark = UserBookmark().query()\ | |
|
492 | .filter(UserBookmark.user_id == self.request.user.user_id) \ | |
|
493 | .filter(UserBookmark.position == bookmark_id).scalar() | |
|
494 | ||
|
495 | redirect_url = h.route_path('my_account_bookmarks') | |
|
496 | if not user_bookmark: | |
|
497 | raise HTTPFound(redirect_url) | |
|
498 | ||
|
499 | if user_bookmark.repository: | |
|
500 | repo_name = user_bookmark.repository.repo_name | |
|
501 | base_redirect_url = h.route_path( | |
|
502 | 'repo_summary', repo_name=repo_name) | |
|
503 | if user_bookmark.redirect_url and \ | |
|
504 | '${repo_url}' in user_bookmark.redirect_url: | |
|
505 | redirect_url = string.Template(user_bookmark.redirect_url)\ | |
|
506 | .safe_substitute({'repo_url': base_redirect_url}) | |
|
507 | else: | |
|
508 | redirect_url = base_redirect_url | |
|
509 | ||
|
510 | elif user_bookmark.repository_group: | |
|
511 | repo_group_name = user_bookmark.repository_group.group_name | |
|
512 | base_redirect_url = h.route_path( | |
|
513 | 'repo_group_home', repo_group_name=repo_group_name) | |
|
514 | if user_bookmark.redirect_url and \ | |
|
515 | '${repo_group_url}' in user_bookmark.redirect_url: | |
|
516 | redirect_url = string.Template(user_bookmark.redirect_url)\ | |
|
517 | .safe_substitute({'repo_group_url': base_redirect_url}) | |
|
518 | else: | |
|
519 | redirect_url = base_redirect_url | |
|
520 | ||
|
521 | elif user_bookmark.redirect_url: | |
|
522 | redirect_url = user_bookmark.redirect_url | |
|
523 | ||
|
524 | log.debug('Redirecting bookmark %s to %s', user_bookmark, redirect_url) | |
|
525 | raise HTTPFound(redirect_url) | |
|
526 | ||
|
527 | @LoginRequired() | |
|
528 | @NotAnonymous() | |
|
529 | @view_config( | |
|
395 | 530 | route_name='my_account_perms', request_method='GET', |
|
396 | 531 | renderer='rhodecode:templates/admin/my_account/my_account.mako') |
|
397 | 532 | def my_account_perms(self): |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -71,10 +71,11 b' class MyAccountSshKeysView(BaseAppView, ' | |||
|
71 | 71 | c = self.load_default_context() |
|
72 | 72 | |
|
73 | 73 | c.active = 'ssh_keys_generate' |
|
74 | comment = 'RhodeCode-SSH {}'.format(c.user.email or '') | |
|
75 | c.private, c.public = SshKeyModel().generate_keypair(comment=comment) | |
|
76 | c.target_form_url = h.route_path( | |
|
77 | 'my_account_ssh_keys', _query=dict(default_key=c.public)) | |
|
74 | if c.ssh_key_generator_enabled: | |
|
75 | comment = 'RhodeCode-SSH {}'.format(c.user.email or '') | |
|
76 | c.private, c.public = SshKeyModel().generate_keypair(comment=comment) | |
|
77 | c.target_form_url = h.route_path( | |
|
78 | 'my_account_ssh_keys', _query=dict(default_key=c.public)) | |
|
78 | 79 | return self._get_template_context(c) |
|
79 | 80 | |
|
80 | 81 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -49,9 +49,13 b' class OpsView(BaseAppView):' | |||
|
49 | 49 | 'instance': self.request.registry.settings.get('instance_id'), |
|
50 | 50 | } |
|
51 | 51 | if getattr(self.request, 'user'): |
|
52 | caller_name = 'anonymous' | |
|
53 | if self.request.user.user_id: | |
|
54 | caller_name = self.request.user.username | |
|
55 | ||
|
52 | 56 | data.update({ |
|
53 | 57 | 'caller_ip': self.request.user.ip_addr, |
|
54 |
'caller_name': |
|
|
58 | 'caller_name': caller_name, | |
|
55 | 59 | }) |
|
56 | 60 | return {'ok': data} |
|
57 | 61 | |
@@ -65,11 +69,13 b' class OpsView(BaseAppView):' | |||
|
65 | 69 | """ |
|
66 | 70 | Test exception handling and emails on errors |
|
67 | 71 | """ |
|
72 | ||
|
68 | 73 | class TestException(Exception): |
|
69 | 74 | pass |
|
70 | ||
|
75 | # add timeout so we add some sort of rate limiter | |
|
76 | time.sleep(2) | |
|
71 | 77 | msg = ('RhodeCode Enterprise test exception. ' |
|
72 |
' |
|
|
78 | 'Client:{}. Generation time: {}.'.format(self.request.user, time.time())) | |
|
73 | 79 | raise TestException(msg) |
|
74 | 80 | |
|
75 | 81 | @view_config( |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -271,8 +271,8 b' def includeme(config):' | |||
|
271 | 271 | repo_route=True) |
|
272 | 272 | |
|
273 | 273 | config.add_route( |
|
274 |
name='pullrequest_repo_ |
|
|
275 |
pattern='/{repo_name:.*?[^/]}/pull-request/repo- |
|
|
274 | name='pullrequest_repo_targets', | |
|
275 | pattern='/{repo_name:.*?[^/]}/pull-request/repo-targets', | |
|
276 | 276 | repo_route=True) |
|
277 | 277 | |
|
278 | 278 | config.add_route( |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -32,7 +32,6 b' from rhodecode.model.pull_request import' | |||
|
32 | 32 | from rhodecode.model.user import UserModel |
|
33 | 33 | from rhodecode.tests import ( |
|
34 | 34 | assert_session_flash, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN) |
|
35 | from rhodecode.tests.utils import AssertResponse | |
|
36 | 35 | |
|
37 | 36 | |
|
38 | 37 | def route_path(name, params=None, **kwargs): |
@@ -45,7 +44,7 b' def route_path(name, params=None, **kwar' | |||
|
45 | 44 | 'pullrequest_show_all': '/{repo_name}/pull-request', |
|
46 | 45 | 'pullrequest_show_all_data': '/{repo_name}/pull-request-data', |
|
47 | 46 | 'pullrequest_repo_refs': '/{repo_name}/pull-request/refs/{target_repo_name:.*?[^/]}', |
|
48 |
'pullrequest_repo_ |
|
|
47 | 'pullrequest_repo_targets': '/{repo_name}/pull-request/repo-destinations', | |
|
49 | 48 | 'pullrequest_new': '/{repo_name}/pull-request/new', |
|
50 | 49 | 'pullrequest_create': '/{repo_name}/pull-request/create', |
|
51 | 50 | 'pullrequest_update': '/{repo_name}/pull-request/{pull_request_id}/update', |
@@ -233,8 +232,7 b' class TestPullrequestsView(object):' | |||
|
233 | 232 | route_path('pullrequest_update', |
|
234 | 233 | repo_name=pull_request.target_repo.repo_name, |
|
235 | 234 | pull_request_id=pull_request_id), |
|
236 | params={'update_commits': 'true', | |
|
237 | 'csrf_token': csrf_token}) | |
|
235 | params={'update_commits': 'true', 'csrf_token': csrf_token}) | |
|
238 | 236 | |
|
239 | 237 | expected_msg = str(PullRequestModel.UPDATE_STATUS_MESSAGES[ |
|
240 | 238 | UpdateFailureReason.MISSING_SOURCE_REF]) |
@@ -244,7 +242,8 b' class TestPullrequestsView(object):' | |||
|
244 | 242 | from rhodecode.lib.vcs.backends.base import MergeFailureReason |
|
245 | 243 | pull_request = pr_util.create_pull_request( |
|
246 | 244 | approved=True, mergeable=True) |
|
247 |
|
|
|
245 | unicode_reference = u'branch:invalid-branch:invalid-commit-id' | |
|
246 | pull_request.target_ref = unicode_reference | |
|
248 | 247 | Session().add(pull_request) |
|
249 | 248 | Session().commit() |
|
250 | 249 | |
@@ -255,12 +254,12 b' class TestPullrequestsView(object):' | |||
|
255 | 254 | pull_request_id=pull_request_id) |
|
256 | 255 | |
|
257 | 256 | response = self.app.get(pull_request_url) |
|
258 | ||
|
259 |
|
|
|
260 | expected_msg = PullRequestModel.MERGE_STATUS_MESSAGES[ | |
|
261 | MergeFailureReason.MISSING_TARGET_REF] | |
|
262 | assertr.element_contains( | |
|
263 |
'span[data-role="merge-message"]', |
|
|
257 | target_ref_id = 'invalid-branch' | |
|
258 | merge_resp = MergeResponse( | |
|
259 | True, True, '', MergeFailureReason.MISSING_TARGET_REF, | |
|
260 | metadata={'target_ref': PullRequest.unicode_to_reference(unicode_reference)}) | |
|
261 | response.assert_response().element_contains( | |
|
262 | 'span[data-role="merge-message"]', merge_resp.merge_status_message) | |
|
264 | 263 | |
|
265 | 264 | def test_comment_and_close_pull_request_custom_message_approved( |
|
266 | 265 | self, pr_util, csrf_token, xhr_header): |
@@ -272,8 +271,8 b' class TestPullrequestsView(object):' | |||
|
272 | 271 | |
|
273 | 272 | self.app.post( |
|
274 | 273 | route_path('pullrequest_comment_create', |
|
275 | repo_name=pull_request.target_repo.scm_instance().name, | |
|
276 | pull_request_id=pull_request_id), | |
|
274 | repo_name=pull_request.target_repo.scm_instance().name, | |
|
275 | pull_request_id=pull_request_id), | |
|
277 | 276 | params={ |
|
278 | 277 | 'close_pull_request': '1', |
|
279 | 278 | 'text': 'Closing a PR', |
@@ -608,8 +607,7 b' class TestPullrequestsView(object):' | |||
|
608 | 607 | |
|
609 | 608 | response = self.app.post( |
|
610 | 609 | route_path('pullrequest_merge', |
|
611 | repo_name=repo_name, | |
|
612 | pull_request_id=pull_request_id), | |
|
610 | repo_name=repo_name, pull_request_id=pull_request_id), | |
|
613 | 611 | params={'csrf_token': csrf_token}).follow() |
|
614 | 612 | |
|
615 | 613 | assert response.status_int == 200 |
@@ -624,10 +622,13 b' class TestPullrequestsView(object):' | |||
|
624 | 622 | pull_request_id = pull_request.pull_request_id |
|
625 | 623 | repo_name = pull_request.target_repo.scm_instance().name |
|
626 | 624 | |
|
625 | merge_resp = MergeResponse(True, False, 'STUB_COMMIT_ID', | |
|
626 | MergeFailureReason.PUSH_FAILED, | |
|
627 | metadata={'target': 'shadow repo', | |
|
628 | 'merge_commit': 'xxx'}) | |
|
627 | 629 | model_patcher = mock.patch.multiple( |
|
628 | 630 | PullRequestModel, |
|
629 |
merge_repo=mock.Mock(return_value= |
|
|
630 | True, False, 'STUB_COMMIT_ID', MergeFailureReason.PUSH_FAILED)), | |
|
631 | merge_repo=mock.Mock(return_value=merge_resp), | |
|
631 | 632 | merge_status=mock.Mock(return_value=(True, 'WRONG_MESSAGE'))) |
|
632 | 633 | |
|
633 | 634 | with model_patcher: |
@@ -637,8 +638,10 b' class TestPullrequestsView(object):' | |||
|
637 | 638 | pull_request_id=pull_request_id), |
|
638 | 639 | params={'csrf_token': csrf_token}, status=302) |
|
639 | 640 | |
|
640 | assert_session_flash(response, PullRequestModel.MERGE_STATUS_MESSAGES[ | |
|
641 | MergeFailureReason.PUSH_FAILED]) | |
|
641 | merge_resp = MergeResponse(True, True, '', MergeFailureReason.PUSH_FAILED, | |
|
642 | metadata={'target': 'shadow repo', | |
|
643 | 'merge_commit': 'xxx'}) | |
|
644 | assert_session_flash(response, merge_resp.merge_status_message) | |
|
642 | 645 | |
|
643 | 646 | def test_update_source_revision(self, backend, csrf_token): |
|
644 | 647 | commits = [ |
@@ -652,20 +655,20 b' class TestPullrequestsView(object):' | |||
|
652 | 655 | |
|
653 | 656 | # create pr from a in source to A in target |
|
654 | 657 | pull_request = PullRequest() |
|
658 | ||
|
655 | 659 | pull_request.source_repo = source |
|
656 | # TODO: johbo: Make sure that we write the source ref this way! | |
|
657 | 660 | pull_request.source_ref = 'branch:{branch}:{commit_id}'.format( |
|
658 | 661 | branch=backend.default_branch_name, commit_id=commit_ids['change']) |
|
662 | ||
|
659 | 663 | pull_request.target_repo = target |
|
660 | ||
|
661 | 664 | pull_request.target_ref = 'branch:{branch}:{commit_id}'.format( |
|
662 | branch=backend.default_branch_name, | |
|
663 | commit_id=commit_ids['ancestor']) | |
|
665 | branch=backend.default_branch_name, commit_id=commit_ids['ancestor']) | |
|
666 | ||
|
664 | 667 | pull_request.revisions = [commit_ids['change']] |
|
665 | 668 | pull_request.title = u"Test" |
|
666 | 669 | pull_request.description = u"Description" |
|
667 | pull_request.author = UserModel().get_by_username( | |
|
668 | TEST_USER_ADMIN_LOGIN) | |
|
670 | pull_request.author = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) | |
|
671 | pull_request.pull_request_state = PullRequest.STATE_CREATED | |
|
669 | 672 | Session().add(pull_request) |
|
670 | 673 | Session().commit() |
|
671 | 674 | pull_request_id = pull_request.pull_request_id |
@@ -676,23 +679,21 b' class TestPullrequestsView(object):' | |||
|
676 | 679 | # update PR |
|
677 | 680 | self.app.post( |
|
678 | 681 | route_path('pullrequest_update', |
|
679 | repo_name=target.repo_name, | |
|
680 | pull_request_id=pull_request_id), | |
|
681 | params={'update_commits': 'true', | |
|
682 | 'csrf_token': csrf_token}) | |
|
682 | repo_name=target.repo_name, pull_request_id=pull_request_id), | |
|
683 | params={'update_commits': 'true', 'csrf_token': csrf_token}) | |
|
684 | ||
|
685 | response = self.app.get( | |
|
686 | route_path('pullrequest_show', | |
|
687 | repo_name=target.repo_name, | |
|
688 | pull_request_id=pull_request.pull_request_id)) | |
|
689 | ||
|
690 | assert response.status_int == 200 | |
|
691 | assert 'Pull request updated to' in response.body | |
|
692 | assert 'with 1 added, 0 removed commits.' in response.body | |
|
683 | 693 | |
|
684 | 694 | # check that we have now both revisions |
|
685 | 695 | pull_request = PullRequest.get(pull_request_id) |
|
686 | assert pull_request.revisions == [ | |
|
687 | commit_ids['change-2'], commit_ids['change']] | |
|
688 | ||
|
689 | # TODO: johbo: this should be a test on its own | |
|
690 | response = self.app.get(route_path( | |
|
691 | 'pullrequest_new', | |
|
692 | repo_name=target.repo_name)) | |
|
693 | assert response.status_int == 200 | |
|
694 | assert 'Pull request updated to' in response.body | |
|
695 | assert 'with 1 added, 0 removed commits.' in response.body | |
|
696 | assert pull_request.revisions == [commit_ids['change-2'], commit_ids['change']] | |
|
696 | 697 | |
|
697 | 698 | def test_update_target_revision(self, backend, csrf_token): |
|
698 | 699 | commits = [ |
@@ -707,21 +708,21 b' class TestPullrequestsView(object):' | |||
|
707 | 708 | |
|
708 | 709 | # create pr from a in source to A in target |
|
709 | 710 | pull_request = PullRequest() |
|
711 | ||
|
710 | 712 | pull_request.source_repo = source |
|
711 | # TODO: johbo: Make sure that we write the source ref this way! | |
|
712 | 713 | pull_request.source_ref = 'branch:{branch}:{commit_id}'.format( |
|
713 | 714 | branch=backend.default_branch_name, commit_id=commit_ids['change']) |
|
715 | ||
|
714 | 716 | pull_request.target_repo = target |
|
715 | # TODO: johbo: Target ref should be branch based, since tip can jump | |
|
716 | # from branch to branch | |
|
717 | 717 | pull_request.target_ref = 'branch:{branch}:{commit_id}'.format( |
|
718 | branch=backend.default_branch_name, | |
|
719 | commit_id=commit_ids['ancestor']) | |
|
718 | branch=backend.default_branch_name, commit_id=commit_ids['ancestor']) | |
|
719 | ||
|
720 | 720 | pull_request.revisions = [commit_ids['change']] |
|
721 | 721 | pull_request.title = u"Test" |
|
722 | 722 | pull_request.description = u"Description" |
|
723 | pull_request.author = UserModel().get_by_username( | |
|
724 | TEST_USER_ADMIN_LOGIN) | |
|
723 | pull_request.author = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) | |
|
724 | pull_request.pull_request_state = PullRequest.STATE_CREATED | |
|
725 | ||
|
725 | 726 | Session().add(pull_request) |
|
726 | 727 | Session().commit() |
|
727 | 728 | pull_request_id = pull_request.pull_request_id |
@@ -734,23 +735,21 b' class TestPullrequestsView(object):' | |||
|
734 | 735 | # update PR |
|
735 | 736 | self.app.post( |
|
736 | 737 | route_path('pullrequest_update', |
|
737 | repo_name=target.repo_name, | |
|
738 | pull_request_id=pull_request_id), | |
|
739 | params={'update_commits': 'true', | |
|
740 | 'csrf_token': csrf_token}, | |
|
738 | repo_name=target.repo_name, | |
|
739 | pull_request_id=pull_request_id), | |
|
740 | params={'update_commits': 'true', 'csrf_token': csrf_token}, | |
|
741 | 741 | status=200) |
|
742 | 742 | |
|
743 | 743 | # check that we have now both revisions |
|
744 | 744 | pull_request = PullRequest.get(pull_request_id) |
|
745 | 745 | assert pull_request.revisions == [commit_ids['change-rebased']] |
|
746 | 746 | assert pull_request.target_ref == 'branch:{branch}:{commit_id}'.format( |
|
747 | branch=backend.default_branch_name, | |
|
748 | commit_id=commit_ids['ancestor-new']) | |
|
747 | branch=backend.default_branch_name, commit_id=commit_ids['ancestor-new']) | |
|
749 | 748 | |
|
750 | # TODO: johbo: This should be a test on its own | |
|
751 | response = self.app.get(route_path( | |
|
752 | 'pullrequest_new', | |
|
753 | repo_name=target.repo_name)) | |
|
749 | response = self.app.get( | |
|
750 | route_path('pullrequest_show', | |
|
751 | repo_name=target.repo_name, | |
|
752 | pull_request_id=pull_request.pull_request_id)) | |
|
754 | 753 | assert response.status_int == 200 |
|
755 | 754 | assert 'Pull request updated to' in response.body |
|
756 | 755 | assert 'with 1 added, 1 removed commits.' in response.body |
@@ -772,17 +771,14 b' class TestPullrequestsView(object):' | |||
|
772 | 771 | # create pr from a in source to A in target |
|
773 | 772 | pull_request = PullRequest() |
|
774 | 773 | pull_request.source_repo = source |
|
775 | # TODO: johbo: Make sure that we write the source ref this way! | |
|
774 | ||
|
776 | 775 | pull_request.source_ref = 'branch:{branch}:{commit_id}'.format( |
|
777 | 776 | branch=backend.default_branch_name, |
|
778 | 777 | commit_id=commit_ids['master-commit-3-change-2']) |
|
779 | 778 | |
|
780 | 779 | pull_request.target_repo = target |
|
781 | # TODO: johbo: Target ref should be branch based, since tip can jump | |
|
782 | # from branch to branch | |
|
783 | 780 | pull_request.target_ref = 'branch:{branch}:{commit_id}'.format( |
|
784 | branch=backend.default_branch_name, | |
|
785 | commit_id=commit_ids['feat-commit-2']) | |
|
781 | branch=backend.default_branch_name, commit_id=commit_ids['feat-commit-2']) | |
|
786 | 782 | |
|
787 | 783 | pull_request.revisions = [ |
|
788 | 784 | commit_ids['feat-commit-1'], |
@@ -790,8 +786,8 b' class TestPullrequestsView(object):' | |||
|
790 | 786 | ] |
|
791 | 787 | pull_request.title = u"Test" |
|
792 | 788 | pull_request.description = u"Description" |
|
793 | pull_request.author = UserModel().get_by_username( | |
|
794 | TEST_USER_ADMIN_LOGIN) | |
|
789 | pull_request.author = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) | |
|
790 | pull_request.pull_request_state = PullRequest.STATE_CREATED | |
|
795 | 791 | Session().add(pull_request) |
|
796 | 792 | Session().commit() |
|
797 | 793 | pull_request_id = pull_request.pull_request_id |
@@ -807,13 +803,10 b' class TestPullrequestsView(object):' | |||
|
807 | 803 | route_path('pullrequest_update', |
|
808 | 804 | repo_name=target.repo_name, |
|
809 | 805 | pull_request_id=pull_request_id), |
|
810 | params={'update_commits': 'true', | |
|
811 | 'csrf_token': csrf_token}, | |
|
806 | params={'update_commits': 'true', 'csrf_token': csrf_token}, | |
|
812 | 807 | status=200) |
|
813 | 808 | |
|
814 | response = self.app.get(route_path( | |
|
815 | 'pullrequest_new', | |
|
816 | repo_name=target.repo_name)) | |
|
809 | response = self.app.get(route_path('pullrequest_new', repo_name=target.repo_name)) | |
|
817 | 810 | assert response.status_int == 200 |
|
818 | 811 | response.mustcontain('Pull request updated to') |
|
819 | 812 | response.mustcontain('with 0 added, 0 removed commits.') |
@@ -833,21 +826,17 b' class TestPullrequestsView(object):' | |||
|
833 | 826 | # create pr from a in source to A in target |
|
834 | 827 | pull_request = PullRequest() |
|
835 | 828 | pull_request.source_repo = source |
|
836 | # TODO: johbo: Make sure that we write the source ref this way! | |
|
829 | ||
|
837 | 830 | pull_request.source_ref = 'branch:{branch}:{commit_id}'.format( |
|
838 | branch=backend.default_branch_name, | |
|
839 | commit_id=commit_ids['change']) | |
|
831 | branch=backend.default_branch_name, commit_id=commit_ids['change']) | |
|
840 | 832 | pull_request.target_repo = target |
|
841 | # TODO: johbo: Target ref should be branch based, since tip can jump | |
|
842 | # from branch to branch | |
|
843 | 833 | pull_request.target_ref = 'branch:{branch}:{commit_id}'.format( |
|
844 | branch=backend.default_branch_name, | |
|
845 | commit_id=commit_ids['ancestor']) | |
|
834 | branch=backend.default_branch_name, commit_id=commit_ids['ancestor']) | |
|
846 | 835 | pull_request.revisions = [commit_ids['change']] |
|
847 | 836 | pull_request.title = u"Test" |
|
848 | 837 | pull_request.description = u"Description" |
|
849 | pull_request.author = UserModel().get_by_username( | |
|
850 | TEST_USER_ADMIN_LOGIN) | |
|
838 | pull_request.author = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) | |
|
839 | pull_request.pull_request_state = PullRequest.STATE_CREATED | |
|
851 | 840 | Session().add(pull_request) |
|
852 | 841 | Session().commit() |
|
853 | 842 | pull_request_id = pull_request.pull_request_id |
@@ -860,10 +849,8 b' class TestPullrequestsView(object):' | |||
|
860 | 849 | # update PR |
|
861 | 850 | self.app.post( |
|
862 | 851 | route_path('pullrequest_update', |
|
863 | repo_name=target.repo_name, | |
|
864 | pull_request_id=pull_request_id), | |
|
865 | params={'update_commits': 'true', | |
|
866 | 'csrf_token': csrf_token}, | |
|
852 | repo_name=target.repo_name, pull_request_id=pull_request_id), | |
|
853 | params={'update_commits': 'true', 'csrf_token': csrf_token}, | |
|
867 | 854 | status=200) |
|
868 | 855 | |
|
869 | 856 | # Expect the target reference to be updated correctly |
@@ -890,13 +877,12 b' class TestPullrequestsView(object):' | |||
|
890 | 877 | pull_request.source_ref = 'branch:{branch}:{commit_id}'.format( |
|
891 | 878 | branch=branch_name, commit_id=commit_ids['new-feature']) |
|
892 | 879 | pull_request.target_ref = 'branch:{branch}:{commit_id}'.format( |
|
893 | branch=backend_git.default_branch_name, | |
|
894 | commit_id=commit_ids['old-feature']) | |
|
880 | branch=backend_git.default_branch_name, commit_id=commit_ids['old-feature']) | |
|
895 | 881 | pull_request.revisions = [commit_ids['new-feature']] |
|
896 | 882 | pull_request.title = u"Test" |
|
897 | 883 | pull_request.description = u"Description" |
|
898 | pull_request.author = UserModel().get_by_username( | |
|
899 | TEST_USER_ADMIN_LOGIN) | |
|
884 | pull_request.author = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) | |
|
885 | pull_request.pull_request_state = PullRequest.STATE_CREATED | |
|
900 | 886 | Session().add(pull_request) |
|
901 | 887 | Session().commit() |
|
902 | 888 | |
@@ -909,11 +895,11 b' class TestPullrequestsView(object):' | |||
|
909 | 895 | pull_request_id=pull_request.pull_request_id)) |
|
910 | 896 | |
|
911 | 897 | assert response.status_int == 200 |
|
912 | assert_response = AssertResponse(response) | |
|
913 | assert_response.element_contains( | |
|
898 | ||
|
899 | response.assert_response().element_contains( | |
|
914 | 900 | '#changeset_compare_view_content .alert strong', |
|
915 | 901 | 'Missing commits') |
|
916 | assert_response.element_contains( | |
|
902 | response.assert_response().element_contains( | |
|
917 | 903 | '#changeset_compare_view_content .alert', |
|
918 | 904 | 'This pull request cannot be displayed, because one or more' |
|
919 | 905 | ' commits no longer exist in the source repository.') |
@@ -941,15 +927,15 b' class TestPullrequestsView(object):' | |||
|
941 | 927 | pull_request_id=pull_request.pull_request_id)) |
|
942 | 928 | |
|
943 | 929 | assert response.status_int == 200 |
|
944 | assert_response = AssertResponse(response) | |
|
945 | assert_response.element_contains( | |
|
930 | ||
|
931 | response.assert_response().element_contains( | |
|
946 | 932 | '#changeset_compare_view_content .alert strong', |
|
947 | 933 | 'Missing commits') |
|
948 | assert_response.element_contains( | |
|
934 | response.assert_response().element_contains( | |
|
949 | 935 | '#changeset_compare_view_content .alert', |
|
950 | 936 | 'This pull request cannot be displayed, because one or more' |
|
951 | 937 | ' commits no longer exist in the source repository.') |
|
952 | assert_response.element_contains( | |
|
938 | response.assert_response().element_contains( | |
|
953 | 939 | '#update_commits', |
|
954 | 940 | 'Update commits') |
|
955 | 941 | |
@@ -987,8 +973,7 b' class TestPullrequestsView(object):' | |||
|
987 | 973 | pull_request_id=pull_request.pull_request_id)) |
|
988 | 974 | |
|
989 | 975 | assert response.status_int == 200 |
|
990 | assert_response = AssertResponse(response) | |
|
991 | assert_response.element_contains( | |
|
976 | response.assert_response().element_contains( | |
|
992 | 977 | '#changeset_compare_view_content .alert strong', |
|
993 | 978 | 'Missing commits') |
|
994 | 979 | |
@@ -1004,12 +989,11 b' class TestPullrequestsView(object):' | |||
|
1004 | 989 | repo_name=pull_request.target_repo.scm_instance().name, |
|
1005 | 990 | pull_request_id=pull_request.pull_request_id)) |
|
1006 | 991 | assert response.status_int == 200 |
|
1007 | assert_response = AssertResponse(response) | |
|
1008 | 992 | |
|
1009 | origin = assert_response.get_element('.pr-origininfo .tag') | |
|
993 | origin = response.assert_response().get_element('.pr-origininfo .tag') | |
|
1010 | 994 | origin_children = origin.getchildren() |
|
1011 | 995 | assert len(origin_children) == 1 |
|
1012 | target = assert_response.get_element('.pr-targetinfo .tag') | |
|
996 | target = response.assert_response().get_element('.pr-targetinfo .tag') | |
|
1013 | 997 | target_children = target.getchildren() |
|
1014 | 998 | assert len(target_children) == 1 |
|
1015 | 999 | |
@@ -1038,13 +1022,12 b' class TestPullrequestsView(object):' | |||
|
1038 | 1022 | repo_name=pull_request.target_repo.scm_instance().name, |
|
1039 | 1023 | pull_request_id=pull_request.pull_request_id)) |
|
1040 | 1024 | assert response.status_int == 200 |
|
1041 | assert_response = AssertResponse(response) | |
|
1042 | 1025 | |
|
1043 | origin = assert_response.get_element('.pr-origininfo .tag') | |
|
1026 | origin = response.assert_response().get_element('.pr-origininfo .tag') | |
|
1044 | 1027 | assert origin.text.strip() == 'bookmark: origin' |
|
1045 | 1028 | assert origin.getchildren() == [] |
|
1046 | 1029 | |
|
1047 | target = assert_response.get_element('.pr-targetinfo .tag') | |
|
1030 | target = response.assert_response().get_element('.pr-targetinfo .tag') | |
|
1048 | 1031 | assert target.text.strip() == 'bookmark: target' |
|
1049 | 1032 | assert target.getchildren() == [] |
|
1050 | 1033 | |
@@ -1060,13 +1043,12 b' class TestPullrequestsView(object):' | |||
|
1060 | 1043 | repo_name=pull_request.target_repo.scm_instance().name, |
|
1061 | 1044 | pull_request_id=pull_request.pull_request_id)) |
|
1062 | 1045 | assert response.status_int == 200 |
|
1063 | assert_response = AssertResponse(response) | |
|
1064 | 1046 | |
|
1065 | origin = assert_response.get_element('.pr-origininfo .tag') | |
|
1047 | origin = response.assert_response().get_element('.pr-origininfo .tag') | |
|
1066 | 1048 | assert origin.text.strip() == 'tag: origin' |
|
1067 | 1049 | assert origin.getchildren() == [] |
|
1068 | 1050 | |
|
1069 | target = assert_response.get_element('.pr-targetinfo .tag') | |
|
1051 | target = response.assert_response().get_element('.pr-targetinfo .tag') | |
|
1070 | 1052 | assert target.text.strip() == 'tag: target' |
|
1071 | 1053 | assert target.getchildren() == [] |
|
1072 | 1054 | |
@@ -1090,12 +1072,13 b' class TestPullrequestsView(object):' | |||
|
1090 | 1072 | repo_name=target_repo.name, |
|
1091 | 1073 | pull_request_id=pr_id)) |
|
1092 | 1074 | |
|
1093 | assertr = AssertResponse(response) | |
|
1094 | 1075 | if mergeable: |
|
1095 |
assertr.element_value_contains( |
|
|
1096 | assertr.element_value_contains('input.pr-mergeinfo ', 'pr-merge') | |
|
1076 | response.assert_response().element_value_contains( | |
|
1077 | 'input.pr-mergeinfo', shadow_url) | |
|
1078 | response.assert_response().element_value_contains( | |
|
1079 | 'input.pr-mergeinfo ', 'pr-merge') | |
|
1097 | 1080 | else: |
|
1098 | assertr.no_element_exists('.pr-mergeinfo') | |
|
1081 | response.assert_response().no_element_exists('.pr-mergeinfo') | |
|
1099 | 1082 | |
|
1100 | 1083 | |
|
1101 | 1084 | @pytest.mark.usefixtures('app') |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2017-201 |
|
|
3 | # Copyright (C) 2017-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -203,7 +203,6 b' class RepoChangelogView(RepoAppView):' | |||
|
203 | 203 | pre_load = self._get_preload_attrs() |
|
204 | 204 | |
|
205 | 205 | partial_xhr = self.request.environ.get('HTTP_X_PARTIAL_XHR') |
|
206 | ||
|
207 | 206 | try: |
|
208 | 207 | if f_path: |
|
209 | 208 | log.debug('generating changelog for path %s', f_path) |
@@ -231,7 +230,7 b' class RepoChangelogView(RepoAppView):' | |||
|
231 | 230 | else: |
|
232 | 231 | collection = self.rhodecode_vcs_repo.get_commits( |
|
233 | 232 | branch_name=branch_name, show_hidden=show_hidden, |
|
234 | pre_load=pre_load) | |
|
233 | pre_load=pre_load, translate_tags=False) | |
|
235 | 234 | |
|
236 | 235 | self._load_changelog_data( |
|
237 | 236 | c, collection, p, chunk_size, c.branch_name, |
@@ -320,7 +319,8 b' class RepoChangelogView(RepoAppView):' | |||
|
320 | 319 | collection = list(reversed(collection)) |
|
321 | 320 | else: |
|
322 | 321 | collection = self.rhodecode_vcs_repo.get_commits( |
|
323 |
branch_name=branch_name, show_hidden=show_hidden, pre_load=pre_load |
|
|
322 | branch_name=branch_name, show_hidden=show_hidden, pre_load=pre_load, | |
|
323 | translate_tags=False) | |
|
324 | 324 | |
|
325 | 325 | p = safe_int(self.request.GET.get('page', 1), 1) |
|
326 | 326 | try: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -97,7 +97,7 b' class RepoCommitsView(RepoAppView):' | |||
|
97 | 97 | if len(commit_range) == 2: |
|
98 | 98 | commits = self.rhodecode_vcs_repo.get_commits( |
|
99 | 99 | start_id=commit_range[0], end_id=commit_range[1], |
|
100 | pre_load=pre_load) | |
|
100 | pre_load=pre_load, translate_tags=False) | |
|
101 | 101 | commits = list(commits) |
|
102 | 102 | else: |
|
103 | 103 | commits = [self.rhodecode_vcs_repo.get_commit( |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -27,12 +27,13 b' from pyramid.renderers import render' | |||
|
27 | 27 | from pyramid.response import Response |
|
28 | 28 | |
|
29 | 29 | from rhodecode.apps._base import RepoAppView |
|
30 | from rhodecode.controllers.utils import parse_path_ref, get_commit_from_ref_name | |
|
30 | ||
|
31 | 31 | from rhodecode.lib import helpers as h |
|
32 | 32 | from rhodecode.lib import diffs, codeblocks |
|
33 | 33 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
|
34 | 34 | from rhodecode.lib.utils import safe_str |
|
35 | 35 | from rhodecode.lib.utils2 import safe_unicode, str2bool |
|
36 | from rhodecode.lib.view_utils import parse_path_ref, get_commit_from_ref_name | |
|
36 | 37 | from rhodecode.lib.vcs.exceptions import ( |
|
37 | 38 | EmptyRepositoryError, RepositoryError, RepositoryRequirementError, |
|
38 | 39 | NodeDoesNotExistError) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2017-201 |
|
|
3 | # Copyright (C) 2017-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -34,9 +34,10 b' from pyramid.response import Response' | |||
|
34 | 34 | import rhodecode |
|
35 | 35 | from rhodecode.apps._base import RepoAppView |
|
36 | 36 | |
|
37 | from rhodecode.controllers.utils import parse_path_ref | |
|
37 | ||
|
38 | 38 | from rhodecode.lib import diffs, helpers as h, rc_cache |
|
39 | 39 | from rhodecode.lib import audit_logger |
|
40 | from rhodecode.lib.view_utils import parse_path_ref | |
|
40 | 41 | from rhodecode.lib.exceptions import NonRelativePathError |
|
41 | 42 | from rhodecode.lib.codeblocks import ( |
|
42 | 43 | filenode_as_lines_tokens, filenode_as_annotated_lines_tokens) |
@@ -83,6 +84,7 b' class RepoFilesView(RepoAppView):' | |||
|
83 | 84 | def load_default_context(self): |
|
84 | 85 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
85 | 86 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
87 | c.enable_downloads = self.db_repo.enable_downloads | |
|
86 | 88 | return c |
|
87 | 89 | |
|
88 | 90 | def _ensure_not_locked(self): |
@@ -227,10 +229,11 b' class RepoFilesView(RepoAppView):' | |||
|
227 | 229 | self, c, commit_id, f_path, full_load=False): |
|
228 | 230 | |
|
229 | 231 | repo_id = self.db_repo.repo_id |
|
232 | force_recache = self.get_recache_flag() | |
|
230 | 233 | |
|
231 | 234 | cache_seconds = safe_int( |
|
232 | 235 | rhodecode.CONFIG.get('rc_cache.cache_repo.expiration_time')) |
|
233 | cache_on = cache_seconds > 0 | |
|
236 | cache_on = not force_recache and cache_seconds > 0 | |
|
234 | 237 | log.debug( |
|
235 | 238 | 'Computing FILE TREE for repo_id %s commit_id `%s` and path `%s`' |
|
236 | 239 | 'with caching: %s[TTL: %ss]' % ( |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -50,8 +50,13 b' class RepoSettingsPermissionsView(RepoAp' | |||
|
50 | 50 | route_name='edit_repo_perms', request_method='GET', |
|
51 | 51 | renderer='rhodecode:templates/admin/repos/repo_edit.mako') |
|
52 | 52 | def edit_permissions(self): |
|
53 | _ = self.request.translate | |
|
53 | 54 | c = self.load_default_context() |
|
54 | 55 | c.active = 'permissions' |
|
56 | if self.request.GET.get('branch_permissions'): | |
|
57 | h.flash(_('Explicitly add user or user group with write+ ' | |
|
58 | 'permission to modify their branch permissions.'), | |
|
59 | category='notice') | |
|
55 | 60 | return self._get_template_context(c) |
|
56 | 61 | |
|
57 | 62 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -137,13 +137,6 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
137 | 137 | }) |
|
138 | 138 | return data |
|
139 | 139 | |
|
140 | def get_recache_flag(self): | |
|
141 | for flag_name in ['force_recache', 'force-recache', 'no-cache']: | |
|
142 | flag_val = self.request.GET.get(flag_name) | |
|
143 | if str2bool(flag_val): | |
|
144 | return True | |
|
145 | return False | |
|
146 | ||
|
147 | 140 | @LoginRequired() |
|
148 | 141 | @HasRepoPermissionAnyDecorator( |
|
149 | 142 | 'repository.read', 'repository.write', 'repository.admin') |
@@ -272,9 +265,22 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
272 | 265 | route_name='pullrequest_show', request_method='GET', |
|
273 | 266 | renderer='rhodecode:templates/pullrequests/pullrequest_show.mako') |
|
274 | 267 | def pull_request_show(self): |
|
275 | pull_request_id = self.request.matchdict['pull_request_id'] | |
|
268 | _ = self.request.translate | |
|
269 | c = self.load_default_context() | |
|
270 | ||
|
271 | pull_request = PullRequest.get_or_404( | |
|
272 | self.request.matchdict['pull_request_id']) | |
|
273 | pull_request_id = pull_request.pull_request_id | |
|
276 | 274 | |
|
277 | c = self.load_default_context() | |
|
275 | if pull_request.pull_request_state != PullRequest.STATE_CREATED: | |
|
276 | log.debug('show: forbidden because pull request is in state %s', | |
|
277 | pull_request.pull_request_state) | |
|
278 | msg = _(u'Cannot show pull requests in state other than `{}`. ' | |
|
279 | u'Current state is: `{}`').format(PullRequest.STATE_CREATED, | |
|
280 | pull_request.pull_request_state) | |
|
281 | h.flash(msg, category='error') | |
|
282 | raise HTTPFound(h.route_path('pullrequest_show_all', | |
|
283 | repo_name=self.db_repo_name)) | |
|
278 | 284 | |
|
279 | 285 | version = self.request.GET.get('version') |
|
280 | 286 | from_version = self.request.GET.get('from_version') or version |
@@ -754,7 +760,7 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
754 | 760 | |
|
755 | 761 | default_target_repo = source_repo |
|
756 | 762 | |
|
757 | if source_repo.parent: | |
|
763 | if source_repo.parent and c.has_origin_repo_read_perm: | |
|
758 | 764 | parent_vcs_obj = source_repo.parent.scm_instance() |
|
759 | 765 | if parent_vcs_obj and not parent_vcs_obj.is_empty(): |
|
760 | 766 | # change default if we have a parent repo |
@@ -811,37 +817,51 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
811 | 817 | @HasRepoPermissionAnyDecorator( |
|
812 | 818 | 'repository.read', 'repository.write', 'repository.admin') |
|
813 | 819 | @view_config( |
|
814 |
route_name='pullrequest_repo_ |
|
|
820 | route_name='pullrequest_repo_targets', request_method='GET', | |
|
815 | 821 | renderer='json_ext', xhr=True) |
|
816 |
def pull |
|
|
822 | def pullrequest_repo_targets(self): | |
|
817 | 823 | _ = self.request.translate |
|
818 | 824 | filter_query = self.request.GET.get('query') |
|
819 | 825 | |
|
826 | # get the parents | |
|
827 | parent_target_repos = [] | |
|
828 | if self.db_repo.parent: | |
|
829 | parents_query = Repository.query() \ | |
|
830 | .order_by(func.length(Repository.repo_name)) \ | |
|
831 | .filter(Repository.fork_id == self.db_repo.parent.repo_id) | |
|
832 | ||
|
833 | if filter_query: | |
|
834 | ilike_expression = u'%{}%'.format(safe_unicode(filter_query)) | |
|
835 | parents_query = parents_query.filter( | |
|
836 | Repository.repo_name.ilike(ilike_expression)) | |
|
837 | parents = parents_query.limit(20).all() | |
|
838 | ||
|
839 | for parent in parents: | |
|
840 | parent_vcs_obj = parent.scm_instance() | |
|
841 | if parent_vcs_obj and not parent_vcs_obj.is_empty(): | |
|
842 | parent_target_repos.append(parent) | |
|
843 | ||
|
844 | # get other forks, and repo itself | |
|
820 | 845 | query = Repository.query() \ |
|
821 | 846 | .order_by(func.length(Repository.repo_name)) \ |
|
822 | 847 | .filter( |
|
823 |
or_(Repository.repo_ |
|
|
824 |
Repository.fork_id == self.db_repo.repo_id) |
|
|
848 | or_(Repository.repo_id == self.db_repo.repo_id, # repo itself | |
|
849 | Repository.fork_id == self.db_repo.repo_id) # forks of this repo | |
|
850 | ) \ | |
|
851 | .filter(~Repository.repo_id.in_([x.repo_id for x in parent_target_repos])) | |
|
825 | 852 | |
|
826 | 853 | if filter_query: |
|
827 | 854 | ilike_expression = u'%{}%'.format(safe_unicode(filter_query)) |
|
828 | query = query.filter( | |
|
829 | Repository.repo_name.ilike(ilike_expression)) | |
|
855 | query = query.filter(Repository.repo_name.ilike(ilike_expression)) | |
|
830 | 856 | |
|
831 | add_parent = False | |
|
832 | if self.db_repo.parent: | |
|
833 | if filter_query in self.db_repo.parent.repo_name: | |
|
834 | parent_vcs_obj = self.db_repo.parent.scm_instance() | |
|
835 | if parent_vcs_obj and not parent_vcs_obj.is_empty(): | |
|
836 | add_parent = True | |
|
857 | limit = max(20 - len(parent_target_repos), 5) # not less then 5 | |
|
858 | target_repos = query.limit(limit).all() | |
|
837 | 859 | |
|
838 | limit = 20 - 1 if add_parent else 20 | |
|
839 | all_repos = query.limit(limit).all() | |
|
840 | if add_parent: | |
|
841 | all_repos += [self.db_repo.parent] | |
|
860 | all_target_repos = target_repos + parent_target_repos | |
|
842 | 861 | |
|
843 | 862 | repos = [] |
|
844 | for obj in ScmModel().get_repos(all_repos): | |
|
863 | # This checks permissions to the repositories | |
|
864 | for obj in ScmModel().get_repos(all_target_repos): | |
|
845 | 865 | repos.append({ |
|
846 | 866 | 'id': obj['name'], |
|
847 | 867 | 'text': obj['name'], |
@@ -904,12 +924,17 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
904 | 924 | source_db_repo = Repository.get_by_repo_name(_form['source_repo']) |
|
905 | 925 | target_db_repo = Repository.get_by_repo_name(_form['target_repo']) |
|
906 | 926 | |
|
927 | if not (source_db_repo or target_db_repo): | |
|
928 | h.flash(_('source_repo or target repo not found'), category='error') | |
|
929 | raise HTTPFound( | |
|
930 | h.route_path('pullrequest_new', repo_name=self.db_repo_name)) | |
|
931 | ||
|
907 | 932 | # re-check permissions again here |
|
908 | 933 | # source_repo we must have read permissions |
|
909 | 934 | |
|
910 | 935 | source_perm = HasRepoPermissionAny( |
|
911 | 'repository.read', | |
|
912 |
|
|
|
936 | 'repository.read', 'repository.write', 'repository.admin')( | |
|
937 | source_db_repo.repo_name) | |
|
913 | 938 | if not source_perm: |
|
914 | 939 | msg = _('Not Enough permissions to source repo `{}`.'.format( |
|
915 | 940 | source_db_repo.repo_name)) |
@@ -923,8 +948,8 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
923 | 948 | # target repo we must have read permissions, and also later on |
|
924 | 949 | # we want to check branch permissions here |
|
925 | 950 | target_perm = HasRepoPermissionAny( |
|
926 | 'repository.read', | |
|
927 |
|
|
|
951 | 'repository.read', 'repository.write', 'repository.admin')( | |
|
952 | target_db_repo.repo_name) | |
|
928 | 953 | if not target_perm: |
|
929 | 954 | msg = _('Not Enough permissions to target repo `{}`.'.format( |
|
930 | 955 | target_db_repo.repo_name)) |
@@ -1027,6 +1052,15 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
1027 | 1052 | h.flash(msg, category='error') |
|
1028 | 1053 | return True |
|
1029 | 1054 | |
|
1055 | if pull_request.pull_request_state != PullRequest.STATE_CREATED: | |
|
1056 | log.debug('update: forbidden because pull request is in state %s', | |
|
1057 | pull_request.pull_request_state) | |
|
1058 | msg = _(u'Cannot update pull requests in state other than `{}`. ' | |
|
1059 | u'Current state is: `{}`').format(PullRequest.STATE_CREATED, | |
|
1060 | pull_request.pull_request_state) | |
|
1061 | h.flash(msg, category='error') | |
|
1062 | return True | |
|
1063 | ||
|
1030 | 1064 | # only owner or admin can update it |
|
1031 | 1065 | allowed_to_update = PullRequestModel().check_user_update( |
|
1032 | 1066 | pull_request, self._rhodecode_user) |
@@ -1069,7 +1103,9 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
1069 | 1103 | |
|
1070 | 1104 | def _update_commits(self, pull_request): |
|
1071 | 1105 | _ = self.request.translate |
|
1072 | resp = PullRequestModel().update_commits(pull_request) | |
|
1106 | ||
|
1107 | with pull_request.set_state(PullRequest.STATE_UPDATING): | |
|
1108 | resp = PullRequestModel().update_commits(pull_request) | |
|
1073 | 1109 | |
|
1074 | 1110 | if resp.executed: |
|
1075 | 1111 | |
@@ -1082,10 +1118,9 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
1082 | 1118 | else: |
|
1083 | 1119 | changed = 'nothing' |
|
1084 | 1120 | |
|
1085 | msg = _( | |
|
1086 | u'Pull request updated to "{source_commit_id}" with ' | |
|
1087 | u'{count_added} added, {count_removed} removed commits. ' | |
|
1088 | u'Source of changes: {change_source}') | |
|
1121 | msg = _(u'Pull request updated to "{source_commit_id}" with ' | |
|
1122 | u'{count_added} added, {count_removed} removed commits. ' | |
|
1123 | u'Source of changes: {change_source}') | |
|
1089 | 1124 | msg = msg.format( |
|
1090 | 1125 | source_commit_id=pull_request.source_ref_parts.commit_id, |
|
1091 | 1126 | count_added=len(resp.changes.added), |
@@ -1094,8 +1129,7 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
1094 | 1129 | h.flash(msg, category='success') |
|
1095 | 1130 | |
|
1096 | 1131 | channel = '/repo${}$/pr/{}'.format( |
|
1097 | pull_request.target_repo.repo_name, | |
|
1098 | pull_request.pull_request_id) | |
|
1132 | pull_request.target_repo.repo_name, pull_request.pull_request_id) | |
|
1099 | 1133 | message = msg + ( |
|
1100 | 1134 | ' - <a onclick="window.location.reload()">' |
|
1101 | 1135 | '<strong>{}</strong></a>'.format(_('Reload page'))) |
@@ -1128,11 +1162,26 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
1128 | 1162 | """ |
|
1129 | 1163 | pull_request = PullRequest.get_or_404( |
|
1130 | 1164 | self.request.matchdict['pull_request_id']) |
|
1165 | _ = self.request.translate | |
|
1166 | ||
|
1167 | if pull_request.pull_request_state != PullRequest.STATE_CREATED: | |
|
1168 | log.debug('show: forbidden because pull request is in state %s', | |
|
1169 | pull_request.pull_request_state) | |
|
1170 | msg = _(u'Cannot merge pull requests in state other than `{}`. ' | |
|
1171 | u'Current state is: `{}`').format(PullRequest.STATE_CREATED, | |
|
1172 | pull_request.pull_request_state) | |
|
1173 | h.flash(msg, category='error') | |
|
1174 | raise HTTPFound( | |
|
1175 | h.route_path('pullrequest_show', | |
|
1176 | repo_name=pull_request.target_repo.repo_name, | |
|
1177 | pull_request_id=pull_request.pull_request_id)) | |
|
1131 | 1178 | |
|
1132 | 1179 | self.load_default_context() |
|
1133 | check = MergeCheck.validate( | |
|
1134 | pull_request, auth_user=self._rhodecode_user, | |
|
1135 | translator=self.request.translate) | |
|
1180 | ||
|
1181 | with pull_request.set_state(PullRequest.STATE_UPDATING): | |
|
1182 | check = MergeCheck.validate( | |
|
1183 | pull_request, auth_user=self._rhodecode_user, | |
|
1184 | translator=self.request.translate) | |
|
1136 | 1185 | merge_possible = not check.failed |
|
1137 | 1186 | |
|
1138 | 1187 | for err_type, error_msg in check.errors: |
@@ -1144,8 +1193,9 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
1144 | 1193 | self.request.environ, repo_name=pull_request.target_repo.repo_name, |
|
1145 | 1194 | username=self._rhodecode_db_user.username, action='push', |
|
1146 | 1195 | scm=pull_request.target_repo.repo_type) |
|
1147 | self._merge_pull_request( | |
|
1148 | pull_request, self._rhodecode_db_user, extras) | |
|
1196 | with pull_request.set_state(PullRequest.STATE_UPDATING): | |
|
1197 | self._merge_pull_request( | |
|
1198 | pull_request, self._rhodecode_db_user, extras) | |
|
1149 | 1199 | else: |
|
1150 | 1200 | log.debug("Pre-conditions failed, NOT merging.") |
|
1151 | 1201 | |
@@ -1167,10 +1217,8 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
1167 | 1217 | h.flash(msg, category='success') |
|
1168 | 1218 | else: |
|
1169 | 1219 | log.debug( |
|
1170 | "The merge was not successful. Merge response: %s", | |
|
1171 | merge_resp) | |
|
1172 | msg = PullRequestModel().merge_status_message( | |
|
1173 | merge_resp.failure_reason) | |
|
1220 | "The merge was not successful. Merge response: %s", merge_resp) | |
|
1221 | msg = merge_resp.merge_status_message | |
|
1174 | 1222 | h.flash(msg, category='error') |
|
1175 | 1223 | |
|
1176 | 1224 | def _update_reviewers(self, pull_request, review_members, reviewer_rules): |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -73,6 +73,8 b' class RepoSettingsView(RepoAppView):' | |||
|
73 | 73 | 'repository.write', 'repository.read', 'repository.admin')( |
|
74 | 74 | self.db_repo.fork.repo_name, 'repo set as fork page') |
|
75 | 75 | |
|
76 | c.ver_info_dict = self.rhodecode_vcs_repo.get_hooks_info() | |
|
77 | ||
|
76 | 78 | return self._get_template_context(c) |
|
77 | 79 | |
|
78 | 80 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2017-201 |
|
|
3 | # Copyright (C) 2017-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2017-201 |
|
|
3 | # Copyright (C) 2017-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2017-201 |
|
|
3 | # Copyright (C) 2017-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2017-201 |
|
|
3 | # Copyright (C) 2017-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2017-201 |
|
|
3 | # Copyright (C) 2017-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -24,7 +24,7 b' import rhodecode' | |||
|
24 | 24 | |
|
25 | 25 | from pyramid.view import view_config |
|
26 | 26 | |
|
27 |
from rhodecode. |
|
|
27 | from rhodecode.lib.view_utils import get_format_ref_id | |
|
28 | 28 | from rhodecode.apps._base import RepoAppView |
|
29 | 29 | from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP) |
|
30 | 30 | from rhodecode.lib import helpers as h, rc_cache |
@@ -141,7 +141,8 b' class RepoSummaryView(RepoAppView):' | |||
|
141 | 141 | |
|
142 | 142 | pre_load = ['author', 'branch', 'date', 'message'] |
|
143 | 143 | try: |
|
144 |
collection = self.rhodecode_vcs_repo.get_commits( |
|
|
144 | collection = self.rhodecode_vcs_repo.get_commits( | |
|
145 | pre_load=pre_load, translate_tags=False) | |
|
145 | 146 | except EmptyRepositoryError: |
|
146 | 147 | collection = self.rhodecode_vcs_repo |
|
147 | 148 | |
@@ -351,7 +352,7 b' class RepoSummaryView(RepoAppView):' | |||
|
351 | 352 | return data |
|
352 | 353 | |
|
353 | 354 | def _create_reference_data(self, repo, full_repo_name, refs_to_create): |
|
354 |
format_ref_id = |
|
|
355 | format_ref_id = get_format_ref_id(repo) | |
|
355 | 356 | |
|
356 | 357 | result = [] |
|
357 | 358 | for title, refs, ref_type in refs_to_create: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -28,7 +28,16 b' def includeme(config):' | |||
|
28 | 28 | |
|
29 | 29 | config.add_route( |
|
30 | 30 | name='search_repo', |
|
31 | pattern='/{repo_name:.*?[^/]}/_search', repo_route=True) | |
|
32 | ||
|
33 | config.add_route( | |
|
34 | name='search_repo_alt', | |
|
31 | 35 | pattern='/{repo_name:.*?[^/]}/search', repo_route=True) |
|
32 | 36 | |
|
37 | config.add_route( | |
|
38 | name='search_repo_group', | |
|
39 | pattern='/{repo_group_name:.*?[^/]}/_search', | |
|
40 | repo_group_route=True) | |
|
41 | ||
|
33 | 42 | # Scan module for configuration decorators. |
|
34 | 43 | config.scan('.views', ignore='.tests') |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -23,8 +23,9 b' import urllib' | |||
|
23 | 23 | from pyramid.view import view_config |
|
24 | 24 | from webhelpers.util import update_params |
|
25 | 25 | |
|
26 | from rhodecode.apps._base import BaseAppView, RepoAppView | |
|
27 | from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator) | |
|
26 | from rhodecode.apps._base import BaseAppView, RepoAppView, RepoGroupAppView | |
|
27 | from rhodecode.lib.auth import ( | |
|
28 | LoginRequired, HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator) | |
|
28 | 29 | from rhodecode.lib.helpers import Page |
|
29 | 30 | from rhodecode.lib.utils2 import safe_str |
|
30 | 31 | from rhodecode.lib.index import searcher_from_config |
@@ -34,22 +35,25 b' from rhodecode.model.validation_schema.s' | |||
|
34 | 35 | log = logging.getLogger(__name__) |
|
35 | 36 | |
|
36 | 37 | |
|
37 | def search(request, tmpl_context, repo_name): | |
|
38 | def perform_search(request, tmpl_context, repo_name=None, repo_group_name=None): | |
|
38 | 39 | searcher = searcher_from_config(request.registry.settings) |
|
39 | 40 | formatted_results = [] |
|
40 | 41 | execution_time = '' |
|
41 | 42 | |
|
42 | 43 | schema = search_schema.SearchParamsSchema() |
|
43 | ||
|
44 | search_tags = [] | |
|
44 | 45 | search_params = {} |
|
45 | 46 | errors = [] |
|
46 | 47 | try: |
|
47 | 48 | search_params = schema.deserialize( |
|
48 | dict(search_query=request.GET.get('q'), | |
|
49 |
|
|
|
50 |
|
|
|
51 |
|
|
|
52 |
|
|
|
49 | dict( | |
|
50 | search_query=request.GET.get('q'), | |
|
51 | search_type=request.GET.get('type'), | |
|
52 | search_sort=request.GET.get('sort'), | |
|
53 | search_max_lines=request.GET.get('max_lines'), | |
|
54 | page_limit=request.GET.get('page_limit'), | |
|
55 | requested_page=request.GET.get('page'), | |
|
56 | ) | |
|
53 | 57 | ) |
|
54 | 58 | except validation_schema.Invalid as e: |
|
55 | 59 | errors = e.children |
@@ -57,20 +61,22 b' def search(request, tmpl_context, repo_n' | |||
|
57 | 61 | def url_generator(**kw): |
|
58 | 62 | q = urllib.quote(safe_str(search_query)) |
|
59 | 63 | return update_params( |
|
60 | "?q=%s&type=%s" % (q, safe_str(search_type)), **kw) | |
|
64 | "?q=%s&type=%s&max_lines=%s" % ( | |
|
65 | q, safe_str(search_type), search_max_lines), **kw) | |
|
61 | 66 | |
|
62 | 67 | c = tmpl_context |
|
63 | 68 | search_query = search_params.get('search_query') |
|
64 | 69 | search_type = search_params.get('search_type') |
|
65 | 70 | search_sort = search_params.get('search_sort') |
|
71 | search_max_lines = search_params.get('search_max_lines') | |
|
66 | 72 | if search_params.get('search_query'): |
|
67 | 73 | page_limit = search_params['page_limit'] |
|
68 | 74 | requested_page = search_params['requested_page'] |
|
69 | 75 | |
|
70 | 76 | try: |
|
71 | 77 | search_result = searcher.search( |
|
72 | search_query, search_type, c.auth_user, repo_name, | |
|
73 | requested_page, page_limit, search_sort) | |
|
78 | search_query, search_type, c.auth_user, repo_name, repo_group_name, | |
|
79 | requested_page=requested_page, page_limit=page_limit, sort=search_sort) | |
|
74 | 80 | |
|
75 | 81 | formatted_results = Page( |
|
76 | 82 | search_result['results'], page=requested_page, |
@@ -79,6 +85,8 b' def search(request, tmpl_context, repo_n' | |||
|
79 | 85 | finally: |
|
80 | 86 | searcher.cleanup() |
|
81 | 87 | |
|
88 | search_tags = searcher.extract_search_tags(search_query) | |
|
89 | ||
|
82 | 90 | if not search_result['error']: |
|
83 | 91 | execution_time = '%s results (%.3f seconds)' % ( |
|
84 | 92 | search_result['count'], |
@@ -90,6 +98,7 b' def search(request, tmpl_context, repo_n' | |||
|
90 | 98 | |
|
91 | 99 | c.perm_user = c.auth_user |
|
92 | 100 | c.repo_name = repo_name |
|
101 | c.repo_group_name = repo_group_name | |
|
93 | 102 | c.sort = search_sort |
|
94 | 103 | c.url_generator = url_generator |
|
95 | 104 | c.errors = errors |
@@ -98,12 +107,12 b' def search(request, tmpl_context, repo_n' | |||
|
98 | 107 | c.cur_query = search_query |
|
99 | 108 | c.search_type = search_type |
|
100 | 109 | c.searcher = searcher |
|
110 | c.search_tags = search_tags | |
|
101 | 111 | |
|
102 | 112 | |
|
103 | 113 | class SearchView(BaseAppView): |
|
104 | 114 | def load_default_context(self): |
|
105 | 115 | c = self._get_local_tmpl_context() |
|
106 | ||
|
107 | 116 | return c |
|
108 | 117 | |
|
109 | 118 | @LoginRequired() |
@@ -112,14 +121,14 b' class SearchView(BaseAppView):' | |||
|
112 | 121 | renderer='rhodecode:templates/search/search.mako') |
|
113 | 122 | def search(self): |
|
114 | 123 | c = self.load_default_context() |
|
115 |
search(self.request, c |
|
|
124 | perform_search(self.request, c) | |
|
116 | 125 | return self._get_template_context(c) |
|
117 | 126 | |
|
118 | 127 | |
|
119 | 128 | class SearchRepoView(RepoAppView): |
|
120 | 129 | def load_default_context(self): |
|
121 | 130 | c = self._get_local_tmpl_context() |
|
122 | ||
|
131 | c.active = 'search' | |
|
123 | 132 | return c |
|
124 | 133 | |
|
125 | 134 | @LoginRequired() |
@@ -128,7 +137,28 b' class SearchRepoView(RepoAppView):' | |||
|
128 | 137 | @view_config( |
|
129 | 138 | route_name='search_repo', request_method='GET', |
|
130 | 139 | renderer='rhodecode:templates/search/search.mako') |
|
140 | @view_config( | |
|
141 | route_name='search_repo_alt', request_method='GET', | |
|
142 | renderer='rhodecode:templates/search/search.mako') | |
|
131 | 143 | def search_repo(self): |
|
132 | 144 | c = self.load_default_context() |
|
133 | search(self.request, c, repo_name=self.db_repo_name) | |
|
145 | perform_search(self.request, c, repo_name=self.db_repo_name) | |
|
134 | 146 | return self._get_template_context(c) |
|
147 | ||
|
148 | ||
|
149 | class SearchRepoGroupView(RepoGroupAppView): | |
|
150 | def load_default_context(self): | |
|
151 | c = self._get_local_tmpl_context() | |
|
152 | c.active = 'search' | |
|
153 | return c | |
|
154 | ||
|
155 | @LoginRequired() | |
|
156 | @HasRepoGroupPermissionAnyDecorator( | |
|
157 | 'group.read', 'group.write', 'group.admin') | |
|
158 | @view_config( | |
|
159 | route_name='search_repo_group', request_method='GET', | |
|
160 | renderer='rhodecode:templates/search/search.mako') | |
|
161 | def search_repo_group(self): | |
|
162 | c = self.load_default_context() | |
|
163 | perform_search(self.request, c, repo_group_name=self.db_repo_group_name) | |
|
164 | return self._get_template_context(c) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -36,6 +36,7 b' def _sanitize_settings_and_apply_default' | |||
|
36 | 36 | _bool_setting(settings, config_keys.generate_authorized_keyfile, 'false') |
|
37 | 37 | _bool_setting(settings, config_keys.wrapper_allow_shell, 'false') |
|
38 | 38 | _bool_setting(settings, config_keys.enable_debug_logging, 'false') |
|
39 | _bool_setting(settings, config_keys.ssh_key_generator_enabled, 'true') | |
|
39 | 40 | |
|
40 | 41 | _string_setting(settings, config_keys.authorized_keys_file_path, |
|
41 | 42 | '~/.ssh/authorized_keys_rhodecode', |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -24,6 +24,7 b'' | |||
|
24 | 24 | generate_authorized_keyfile = 'ssh.generate_authorized_keyfile' |
|
25 | 25 | authorized_keys_file_path = 'ssh.authorized_keys_file_path' |
|
26 | 26 | authorized_keys_line_ssh_opts = 'ssh.authorized_keys_ssh_opts' |
|
27 | ssh_key_generator_enabled = 'ssh.enable_ui_key_generator' | |
|
27 | 28 | wrapper_cmd = 'ssh.wrapper_cmd' |
|
28 | 29 | wrapper_allow_shell = 'ssh.wrapper_cmd_allow_shell' |
|
29 | 30 | enable_debug_logging = 'ssh.enable_debug_logging' |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -17,10 +17,10 b'' | |||
|
17 | 17 | # This program is dual-licensed. If you wish to learn more about the |
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | ||
|
20 | import os | |
|
21 | 21 | import logging |
|
22 | import os | |
|
23 | 22 | import shlex |
|
23 | from pyramid import compat | |
|
24 | 24 | |
|
25 | 25 | # Do not use `from rhodecode import events` here, it will be overridden by the |
|
26 | 26 | # events module in this package due to pythons import mechanism. |
@@ -85,6 +85,6 b' def _append_path_sep(path):' | |||
|
85 | 85 | """ |
|
86 | 86 | Append the path separator if missing. |
|
87 | 87 | """ |
|
88 |
if isinstance(path, |
|
|
88 | if isinstance(path, compat.string_types) and not path.endswith(os.path.sep): | |
|
89 | 89 | path += os.path.sep |
|
90 | 90 | return path |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -24,12 +24,15 b' RhodeCode authentication plugin for buil' | |||
|
24 | 24 | |
|
25 | 25 | import logging |
|
26 | 26 | |
|
27 | from rhodecode.translation import _ | |
|
27 | import colander | |
|
28 | 28 | |
|
29 | from rhodecode.authentication.base import RhodeCodeAuthPluginBase, hybrid_property | |
|
30 | from rhodecode.authentication.routes import AuthnPluginResourceBase | |
|
29 | from rhodecode.translation import _ | |
|
31 | 30 | from rhodecode.lib.utils2 import safe_str |
|
32 | 31 | from rhodecode.model.db import User |
|
32 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
|
33 | from rhodecode.authentication.base import ( | |
|
34 | RhodeCodeAuthPluginBase, hybrid_property, HTTP_TYPE, VCS_TYPE) | |
|
35 | from rhodecode.authentication.routes import AuthnPluginResourceBase | |
|
33 | 36 | |
|
34 | 37 | log = logging.getLogger(__name__) |
|
35 | 38 | |
@@ -45,6 +48,11 b' class RhodecodeAuthnResource(AuthnPlugin' | |||
|
45 | 48 | |
|
46 | 49 | class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): |
|
47 | 50 | uid = 'rhodecode' |
|
51 | AUTH_RESTRICTION_NONE = 'user_all' | |
|
52 | AUTH_RESTRICTION_SUPER_ADMIN = 'user_super_admin' | |
|
53 | AUTH_RESTRICTION_SCOPE_ALL = 'scope_all' | |
|
54 | AUTH_RESTRICTION_SCOPE_HTTP = 'scope_http' | |
|
55 | AUTH_RESTRICTION_SCOPE_VCS = 'scope_vcs' | |
|
48 | 56 | |
|
49 | 57 | def includeme(self, config): |
|
50 | 58 | config.add_authn_plugin(self) |
@@ -64,6 +72,9 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
64 | 72 | route_name='auth_home', |
|
65 | 73 | context=RhodecodeAuthnResource) |
|
66 | 74 | |
|
75 | def get_settings_schema(self): | |
|
76 | return RhodeCodeSettingsSchema() | |
|
77 | ||
|
67 | 78 | def get_display_name(self): |
|
68 | 79 | return _('RhodeCode Internal') |
|
69 | 80 | |
@@ -94,10 +105,34 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
94 | 105 | if not userobj: |
|
95 | 106 | log.debug('userobj was:%s skipping', userobj) |
|
96 | 107 | return None |
|
108 | ||
|
97 | 109 | if userobj.extern_type != self.name: |
|
98 | log.warning( | |
|
99 | "userobj:%s extern_type mismatch got:`%s` expected:`%s`", | |
|
100 | userobj, userobj.extern_type, self.name) | |
|
110 | log.warning("userobj:%s extern_type mismatch got:`%s` expected:`%s`", | |
|
111 | userobj, userobj.extern_type, self.name) | |
|
112 | return None | |
|
113 | ||
|
114 | # check scope of auth | |
|
115 | scope_restriction = settings.get('scope_restriction', '') | |
|
116 | ||
|
117 | if scope_restriction == self.AUTH_RESTRICTION_SCOPE_HTTP \ | |
|
118 | and self.auth_type != HTTP_TYPE: | |
|
119 | log.warning("userobj:%s tried scope type %s and scope restriction is set to %s", | |
|
120 | userobj, self.auth_type, scope_restriction) | |
|
121 | return None | |
|
122 | ||
|
123 | if scope_restriction == self.AUTH_RESTRICTION_SCOPE_VCS \ | |
|
124 | and self.auth_type != VCS_TYPE: | |
|
125 | log.warning("userobj:%s tried scope type %s and scope restriction is set to %s", | |
|
126 | userobj, self.auth_type, scope_restriction) | |
|
127 | return None | |
|
128 | ||
|
129 | # check super-admin restriction | |
|
130 | auth_restriction = settings.get('auth_restriction', '') | |
|
131 | ||
|
132 | if auth_restriction == self.AUTH_RESTRICTION_SUPER_ADMIN \ | |
|
133 | and userobj.admin is False: | |
|
134 | log.warning("userobj:%s is not super-admin and auth restriction is set to %s", | |
|
135 | userobj, auth_restriction) | |
|
101 | 136 | return None |
|
102 | 137 | |
|
103 | 138 | user_attrs = { |
@@ -131,23 +166,55 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
131 | 166 | user_attrs['_hash_migrate'] = new_hash |
|
132 | 167 | |
|
133 | 168 | if userobj.username == User.DEFAULT_USER and userobj.active: |
|
134 | log.info( | |
|
135 |
|
|
|
169 | log.info('user `%s` authenticated correctly as anonymous user', | |
|
170 | userobj.username) | |
|
136 | 171 | return user_attrs |
|
137 | 172 | |
|
138 | 173 | elif userobj.username == username and password_match: |
|
139 | 174 | log.info('user `%s` authenticated correctly', userobj.username) |
|
140 | 175 | return user_attrs |
|
141 | log.warn("user `%s` used a wrong password when " | |
|
142 | "authenticating on this plugin", userobj.username) | |
|
176 | log.warning("user `%s` used a wrong password when " | |
|
177 | "authenticating on this plugin", userobj.username) | |
|
143 | 178 | return None |
|
144 | 179 | else: |
|
145 | log.warning( | |
|
146 | 'user `%s` failed to authenticate via %s, reason: account not ' | |
|
147 | 'active.', username, self.name) | |
|
180 | log.warning('user `%s` failed to authenticate via %s, reason: account not ' | |
|
181 | 'active.', username, self.name) | |
|
148 | 182 | return None |
|
149 | 183 | |
|
150 | 184 | |
|
185 | class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase): | |
|
186 | ||
|
187 | auth_restriction_choices = [ | |
|
188 | (RhodeCodeAuthPlugin.AUTH_RESTRICTION_NONE, 'All users'), | |
|
189 | (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN, 'Super admins only'), | |
|
190 | ] | |
|
191 | ||
|
192 | auth_scope_choices = [ | |
|
193 | (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_ALL, 'HTTP and VCS'), | |
|
194 | (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_HTTP, 'HTTP only'), | |
|
195 | ] | |
|
196 | ||
|
197 | auth_restriction = colander.SchemaNode( | |
|
198 | colander.String(), | |
|
199 | default=auth_restriction_choices[0], | |
|
200 | description=_('Allowed user types for authentication using this plugin.'), | |
|
201 | title=_('User restriction'), | |
|
202 | validator=colander.OneOf([x[0] for x in auth_restriction_choices]), | |
|
203 | widget='select_with_labels', | |
|
204 | choices=auth_restriction_choices | |
|
205 | ) | |
|
206 | scope_restriction = colander.SchemaNode( | |
|
207 | colander.String(), | |
|
208 | default=auth_scope_choices[0], | |
|
209 | description=_('Allowed protocols for authentication using this plugin. ' | |
|
210 | 'VCS means GIT/HG/SVN. HTTP is web based login.'), | |
|
211 | title=_('Scope restriction'), | |
|
212 | validator=colander.OneOf([x[0] for x in auth_scope_choices]), | |
|
213 | widget='select_with_labels', | |
|
214 | choices=auth_scope_choices | |
|
215 | ) | |
|
216 | ||
|
217 | ||
|
151 | 218 | def includeme(config): |
|
152 | 219 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) |
|
153 | 220 | plugin_factory(plugin_id).includeme(config) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -23,7 +23,9 b' RhodeCode authentication token plugin fo' | |||
|
23 | 23 | """ |
|
24 | 24 | |
|
25 | 25 | import logging |
|
26 | import colander | |
|
26 | 27 | |
|
28 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
|
27 | 29 | from rhodecode.translation import _ |
|
28 | 30 | from rhodecode.authentication.base import ( |
|
29 | 31 | RhodeCodeAuthPluginBase, VCS_TYPE, hybrid_property) |
@@ -48,6 +50,7 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
48 | 50 | Enables usage of authentication tokens for vcs operations. |
|
49 | 51 | """ |
|
50 | 52 | uid = 'token' |
|
53 | AUTH_RESTRICTION_SCOPE_VCS = 'scope_vcs' | |
|
51 | 54 | |
|
52 | 55 | def includeme(self, config): |
|
53 | 56 | config.add_authn_plugin(self) |
@@ -67,6 +70,9 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
67 | 70 | route_name='auth_home', |
|
68 | 71 | context=RhodecodeAuthnResource) |
|
69 | 72 | |
|
73 | def get_settings_schema(self): | |
|
74 | return RhodeCodeSettingsSchema() | |
|
75 | ||
|
70 | 76 | def get_display_name(self): |
|
71 | 77 | return _('Rhodecode Token') |
|
72 | 78 | |
@@ -142,16 +148,30 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
142 | 148 | 'user `%s` successfully authenticated via %s', |
|
143 | 149 | user_attrs['username'], self.name) |
|
144 | 150 | return user_attrs |
|
145 | log.warn( | |
|
146 | 'user `%s` failed to authenticate via %s, reason: bad or ' | |
|
147 | 'inactive token.', username, self.name) | |
|
151 | log.warning('user `%s` failed to authenticate via %s, reason: bad or ' | |
|
152 | 'inactive token.', username, self.name) | |
|
148 | 153 | else: |
|
149 | log.warning( | |
|
150 | 'user `%s` failed to authenticate via %s, reason: account not ' | |
|
151 | 'active.', username, self.name) | |
|
154 | log.warning('user `%s` failed to authenticate via %s, reason: account not ' | |
|
155 | 'active.', username, self.name) | |
|
152 | 156 | return None |
|
153 | 157 | |
|
154 | 158 | |
|
155 | 159 | def includeme(config): |
|
156 | 160 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) |
|
157 | 161 | plugin_factory(plugin_id).includeme(config) |
|
162 | ||
|
163 | ||
|
164 | class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase): | |
|
165 | auth_scope_choices = [ | |
|
166 | (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_VCS, 'VCS only'), | |
|
167 | ] | |
|
168 | ||
|
169 | scope_restriction = colander.SchemaNode( | |
|
170 | colander.String(), | |
|
171 | default=auth_scope_choices[0], | |
|
172 | description=_('Choose operation scope restriction when authenticating.'), | |
|
173 | title=_('Scope restriction'), | |
|
174 | validator=colander.OneOf([x[0] for x in auth_scope_choices]), | |
|
175 | widget='select_with_labels', | |
|
176 | choices=auth_scope_choices | |
|
177 | ) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2013-201 |
|
|
3 | # Copyright (C) 2013-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -98,7 +98,7 b' def make_pyramid_app(global_config, **se' | |||
|
98 | 98 | global_config = _substitute_values(global_config, environ) |
|
99 | 99 | settings = _substitute_values(settings, environ) |
|
100 | 100 | |
|
101 | sanitize_settings_and_apply_defaults(settings) | |
|
101 | sanitize_settings_and_apply_defaults(global_config, settings) | |
|
102 | 102 | |
|
103 | 103 | config = Configurator(settings=settings) |
|
104 | 104 | |
@@ -165,7 +165,7 b' def error_handler(exception, request):' | |||
|
165 | 165 | |
|
166 | 166 | error_explanation = base_response.explanation or str(base_response) |
|
167 | 167 | if base_response.status_code == 404: |
|
168 |
error_explanation += " O |
|
|
168 | error_explanation += " Optionally you don't have permission to access this page." | |
|
169 | 169 | c = AttributeDict() |
|
170 | 170 | c.error_message = base_response.status |
|
171 | 171 | c.error_explanation = error_explanation |
@@ -281,6 +281,7 b' def includeme(config):' | |||
|
281 | 281 | config.include('rhodecode.apps.ops') |
|
282 | 282 | config.include('rhodecode.apps.admin') |
|
283 | 283 | config.include('rhodecode.apps.channelstream') |
|
284 | config.include('rhodecode.apps.file_store') | |
|
284 | 285 | config.include('rhodecode.apps.login') |
|
285 | 286 | config.include('rhodecode.apps.home') |
|
286 | 287 | config.include('rhodecode.apps.journal') |
@@ -381,7 +382,7 b' def wrap_app_in_wsgi_middlewares(pyramid' | |||
|
381 | 382 | return pyramid_app_with_cleanup |
|
382 | 383 | |
|
383 | 384 | |
|
384 | def sanitize_settings_and_apply_defaults(settings): | |
|
385 | def sanitize_settings_and_apply_defaults(global_config, settings): | |
|
385 | 386 | """ |
|
386 | 387 | Applies settings defaults and does all type conversion. |
|
387 | 388 | |
@@ -420,6 +421,7 b' def sanitize_settings_and_apply_defaults' | |||
|
420 | 421 | # TODO: johbo: Re-think this, usually the call to config.include |
|
421 | 422 | # should allow to pass in a prefix. |
|
422 | 423 | settings.setdefault('rhodecode.api.url', '/_admin/api') |
|
424 | settings.setdefault('__file__', global_config.get('__file__')) | |
|
423 | 425 | |
|
424 | 426 | # Sanitize generic settings. |
|
425 | 427 | _list_setting(settings, 'default_encoding', 'UTF-8') |
@@ -708,18 +710,29 b' def _string_setting(settings, name, defa' | |||
|
708 | 710 | |
|
709 | 711 | |
|
710 | 712 | def _substitute_values(mapping, substitutions): |
|
713 | result = {} | |
|
711 | 714 | |
|
712 | 715 | try: |
|
713 | result = { | |
|
716 | for key, value in mapping.items(): | |
|
717 | # initialize without substitution first | |
|
718 | result[key] = value | |
|
719 | ||
|
714 | 720 | # Note: Cannot use regular replacements, since they would clash |
|
715 | 721 | # with the implementation of ConfigParser. Using "format" instead. |
|
716 | key: value.format(**substitutions) | |
|
717 | for key, value in mapping.items() | |
|
718 | } | |
|
719 | except KeyError as e: | |
|
720 | raise ValueError( | |
|
721 | 'Failed to substitute env variable: {}. ' | |
|
722 | 'Make sure you have specified this env variable without ENV_ prefix'.format(e)) | |
|
722 | try: | |
|
723 | result[key] = value.format(**substitutions) | |
|
724 | except KeyError as e: | |
|
725 | env_var = '{}'.format(e.args[0]) | |
|
726 | ||
|
727 | msg = 'Failed to substitute: `{key}={{{var}}}` with environment entry. ' \ | |
|
728 | 'Make sure your environment has {var} set, or remove this ' \ | |
|
729 | 'variable from config file'.format(key=key, var=env_var) | |
|
730 | ||
|
731 | if env_var.startswith('ENV_'): | |
|
732 | raise ValueError(msg) | |
|
733 | else: | |
|
734 | log.warning(msg) | |
|
735 | ||
|
723 | 736 | except ValueError as e: |
|
724 | 737 | log.warning('Failed to substitute ENV variable: %s', e) |
|
725 | 738 | result = mapping |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -14,19 +14,6 b'' | |||
|
14 | 14 | 'hook_type': '', |
|
15 | 15 | 'user_agent': 'Client user agent, e.g git or mercurial CLI version', |
|
16 | 16 | }) |
|
17 | @has_kwargs({ | |
|
18 | 'server_url': 'url of instance that triggered this hook', | |
|
19 | 'config': 'path to .ini config used', | |
|
20 | 'scm': 'type of version control "git", "hg", "svn"', | |
|
21 | 'username': 'username of actor who triggered this event', | |
|
22 | 'ip': 'ip address of actor who triggered this hook', | |
|
23 | 'action': '', | |
|
24 | 'repository': 'repository name', | |
|
25 | 'repo_store_path': 'full path to where repositories are stored', | |
|
26 | 'commit_ids': 'pre transaction metadata for commit ids', | |
|
27 | 'hook_type': '', | |
|
28 | 'user_agent': 'Client user agent, e.g git or mercurial CLI version', | |
|
29 | }) | |
|
30 | 17 | def _pre_push_hook(*args, **kwargs): |
|
31 | 18 | """ |
|
32 | 19 | Post push hook |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 |
# Copyright (C) 2016-201 |
|
|
2 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software: you can redistribute it and/or modify |
|
5 | 5 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 |
# Copyright (C) 2016-201 |
|
|
2 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software: you can redistribute it and/or modify |
|
5 | 5 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 |
# Copyright (C) 2016-201 |
|
|
2 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software: you can redistribute it and/or modify |
|
5 | 5 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 |
# Copyright (C) 2016-201 |
|
|
2 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software: you can redistribute it and/or modify |
|
5 | 5 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -7457,7 +7457,7 b' msgid ""' | |||
|
7457 | 7457 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7458 | 7458 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7459 | 7459 | " {user} current user username,\n" |
|
7460 |
" {sys_user} current system user running this process, |
|
|
7460 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7461 | 7461 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7462 | 7462 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7463 | 7463 | " {repo} full repository name,\n" |
@@ -7455,7 +7455,7 b' msgid ""' | |||
|
7455 | 7455 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7456 | 7456 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7457 | 7457 | " {user} current user username,\n" |
|
7458 |
" {sys_user} current system user running this process, |
|
|
7458 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7459 | 7459 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7460 | 7460 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7461 | 7461 | " {repo} full repository name,\n" |
@@ -7456,7 +7456,7 b' msgid ""' | |||
|
7456 | 7456 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7457 | 7457 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7458 | 7458 | " {user} current user username,\n" |
|
7459 |
" {sys_user} current system user running this process, |
|
|
7459 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7460 | 7460 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7461 | 7461 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7462 | 7462 | " {repo} full repository name,\n" |
@@ -7456,7 +7456,7 b' msgid ""' | |||
|
7456 | 7456 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7457 | 7457 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7458 | 7458 | " {user} current user username,\n" |
|
7459 |
" {sys_user} current system user running this process, |
|
|
7459 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7460 | 7460 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7461 | 7461 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7462 | 7462 | " {repo} full repository name,\n" |
@@ -7463,7 +7463,7 b' msgid ""' | |||
|
7463 | 7463 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7464 | 7464 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7465 | 7465 | " {user} current user username,\n" |
|
7466 |
" {sys_user} current system user running this process, |
|
|
7466 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7467 | 7467 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7468 | 7468 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7469 | 7469 | " {repo} full repository name,\n" |
@@ -7461,7 +7461,7 b' msgid ""' | |||
|
7461 | 7461 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7462 | 7462 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7463 | 7463 | " {user} current user username,\n" |
|
7464 |
" {sys_user} current system user running this process, |
|
|
7464 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7465 | 7465 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7466 | 7466 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7467 | 7467 | " {repo} full repository name,\n" |
@@ -7457,7 +7457,7 b' msgid ""' | |||
|
7457 | 7457 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7458 | 7458 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7459 | 7459 | " {user} current user username,\n" |
|
7460 |
" {sys_user} current system user running this process, |
|
|
7460 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7461 | 7461 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7462 | 7462 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7463 | 7463 | " {repo} full repository name,\n" |
@@ -7497,7 +7497,7 b' msgid ""' | |||
|
7497 | 7497 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7498 | 7498 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7499 | 7499 | " {user} current user username,\n" |
|
7500 |
" {sys_user} current system user running this process, |
|
|
7500 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7501 | 7501 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7502 | 7502 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7503 | 7503 | " {repo} full repository name,\n" |
@@ -7474,7 +7474,7 b' msgid ""' | |||
|
7474 | 7474 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7475 | 7475 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7476 | 7476 | " {user} current user username,\n" |
|
7477 |
" {sys_user} current system user running this process, |
|
|
7477 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7478 | 7478 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7479 | 7479 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7480 | 7480 | " {repo} full repository name,\n" |
@@ -7458,7 +7458,7 b' msgid ""' | |||
|
7458 | 7458 | "Schema of clone url construction eg. '{scheme}://{user}@{netloc}/{repo}', available vars:\n" |
|
7459 | 7459 | " {scheme} 'http' or 'https' sent from running RhodeCode server,\n" |
|
7460 | 7460 | " {user} current user username,\n" |
|
7461 |
" {sys_user} current system user running this process, |
|
|
7461 | " {sys_user} current system user running this process, Useful for ssh,\n" | |
|
7462 | 7462 | " {hostname} hostname of this server running RhodeCode,\n" |
|
7463 | 7463 | " {netloc} network location/server host of running RhodeCode server,\n" |
|
7464 | 7464 | " {repo} full repository name,\n" |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 |
# Copyright (C) 2012-201 |
|
|
2 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
3 | 3 | # |
|
4 | 4 | # This program is free software: you can redistribute it and/or modify |
|
5 | 5 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -23,17 +23,27 b' import string' | |||
|
23 | 23 | import collections |
|
24 | 24 | import logging |
|
25 | 25 | import requests |
|
26 | import urllib | |
|
26 | 27 | from requests.adapters import HTTPAdapter |
|
27 | 28 | from requests.packages.urllib3.util.retry import Retry |
|
28 | 29 | |
|
29 | 30 | from mako import exceptions |
|
30 | 31 | |
|
32 | from rhodecode.lib.utils2 import safe_str | |
|
31 | 33 | from rhodecode.translation import _ |
|
32 | 34 | |
|
33 | 35 | |
|
34 | 36 | log = logging.getLogger(__name__) |
|
35 | 37 | |
|
36 | 38 | |
|
39 | class UrlTmpl(string.Template): | |
|
40 | ||
|
41 | def safe_substitute(self, **kws): | |
|
42 | # url encode the kw for usage in url | |
|
43 | kws = {k: urllib.quote(safe_str(v)) for k, v in kws.items()} | |
|
44 | return super(UrlTmpl, self).safe_substitute(**kws) | |
|
45 | ||
|
46 | ||
|
37 | 47 | class IntegrationTypeBase(object): |
|
38 | 48 | """ Base class for IntegrationType plugins """ |
|
39 | 49 | is_dummy = False |
@@ -217,7 +227,9 b' class WebhookDataHandler(CommitParsingDa' | |||
|
217 | 227 | common_vars.update(extra_vars) |
|
218 | 228 | |
|
219 | 229 | template_url = self.template_url.replace('${extra:', '${extra__') |
|
220 | return string.Template(template_url).safe_substitute(**common_vars) | |
|
230 | for k, v in common_vars.items(): | |
|
231 | template_url = UrlTmpl(template_url).safe_substitute(**{k: v}) | |
|
232 | return template_url | |
|
221 | 233 | |
|
222 | 234 | def repo_push_event_handler(self, event, data): |
|
223 | 235 | url = self.get_base_parsed_template(data) |
@@ -228,20 +240,18 b' class WebhookDataHandler(CommitParsingDa' | |||
|
228 | 240 | if '${branch}' in url or '${branch_head}' in url or '${commit_id}' in url: |
|
229 | 241 | # call it multiple times, for each branch if used in variables |
|
230 | 242 | for branch, commit_ids in branches_commits.items(): |
|
231 |
branch_url = |
|
|
243 | branch_url = UrlTmpl(url).safe_substitute(branch=branch) | |
|
232 | 244 | |
|
233 | 245 | if '${branch_head}' in branch_url: |
|
234 | 246 | # last commit in the aggregate is the head of the branch |
|
235 | 247 | branch_head = commit_ids['branch_head'] |
|
236 |
branch_url = |
|
|
237 | branch_head=branch_head) | |
|
248 | branch_url = UrlTmpl(branch_url).safe_substitute(branch_head=branch_head) | |
|
238 | 249 | |
|
239 | 250 | # call further down for each commit if used |
|
240 | 251 | if '${commit_id}' in branch_url: |
|
241 | 252 | for commit_data in commit_ids['commits']: |
|
242 | 253 | commit_id = commit_data['raw_id'] |
|
243 |
commit_url = |
|
|
244 | commit_id=commit_id) | |
|
254 | commit_url = UrlTmpl(branch_url).safe_substitute(commit_id=commit_id) | |
|
245 | 255 | # register per-commit call |
|
246 | 256 | log.debug( |
|
247 | 257 | 'register %s call(%s) to url %s', |
@@ -251,36 +261,34 b' class WebhookDataHandler(CommitParsingDa' | |||
|
251 | 261 | |
|
252 | 262 | else: |
|
253 | 263 | # register per-branch call |
|
254 | log.debug( | |
|
255 | 'register %s call(%s) to url %s', | |
|
256 | self.name, event, branch_url) | |
|
257 | url_calls.append( | |
|
258 | (branch_url, self.headers, data)) | |
|
264 | log.debug('register %s call(%s) to url %s', | |
|
265 | self.name, event, branch_url) | |
|
266 | url_calls.append((branch_url, self.headers, data)) | |
|
259 | 267 | |
|
260 | 268 | else: |
|
261 | log.debug( | |
|
262 | 'register %s call(%s) to url %s', self.name, event, url) | |
|
269 | log.debug('register %s call(%s) to url %s', self.name, event, url) | |
|
263 | 270 | url_calls.append((url, self.headers, data)) |
|
264 | 271 | |
|
265 | 272 | return url_calls |
|
266 | 273 | |
|
267 | 274 | def repo_create_event_handler(self, event, data): |
|
268 | 275 | url = self.get_base_parsed_template(data) |
|
269 | log.debug( | |
|
270 | 'register %s call(%s) to url %s', self.name, event, url) | |
|
276 | log.debug('register %s call(%s) to url %s', self.name, event, url) | |
|
271 | 277 | return [(url, self.headers, data)] |
|
272 | 278 | |
|
273 | 279 | def pull_request_event_handler(self, event, data): |
|
274 | 280 | url = self.get_base_parsed_template(data) |
|
275 | log.debug( | |
|
276 | 'register %s call(%s) to url %s', self.name, event, url) | |
|
277 | url = string.Template(url).safe_substitute( | |
|
278 |
pull_request_ |
|
|
279 |
pull_request_ |
|
|
280 |
pull_request_ |
|
|
281 |
pull_request_ |
|
|
282 | pull_request_commits_uid=data['pullrequest']['commits_uid'], | |
|
283 | ) | |
|
281 | log.debug('register %s call(%s) to url %s', self.name, event, url) | |
|
282 | pr_vars = [ | |
|
283 | ('pull_request_id', data['pullrequest']['pull_request_id']), | |
|
284 | ('pull_request_title', data['pullrequest']['title']), | |
|
285 | ('pull_request_url', data['pullrequest']['url']), | |
|
286 | ('pull_request_shadow_url', data['pullrequest']['shadow_url']), | |
|
287 | ('pull_request_commits_uid', data['pullrequest']['commits_uid']), | |
|
288 | ] | |
|
289 | for k, v in pr_vars: | |
|
290 | url = UrlTmpl(url).safe_substitute(**{k: v}) | |
|
291 | ||
|
284 | 292 | return [(url, self.headers, data)] |
|
285 | 293 | |
|
286 | 294 | def __call__(self, event, data): |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -122,8 +122,10 b' class HipchatIntegrationType(Integration' | |||
|
122 | 122 | log.debug('event not valid: %r', event) |
|
123 | 123 | return |
|
124 | 124 | |
|
125 |
|
|
|
126 | log.debug('event ignored: %r', event) | |
|
125 | allowed_events = self.settings['events'] | |
|
126 | if event.name not in allowed_events: | |
|
127 | log.debug('event ignored: %r event %s not in allowed events %s', | |
|
128 | event, event.name, allowed_events) | |
|
127 | 129 | return |
|
128 | 130 | |
|
129 | 131 | data = event.as_dict() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2019 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -138,8 +138,10 b' class SlackIntegrationType(IntegrationTy' | |||
|
138 | 138 | log.debug('event not valid: %r', event) |
|
139 | 139 | return |
|
140 | 140 | |
|
141 |
|
|
|
142 | log.debug('event ignored: %r', event) | |
|
141 | allowed_events = self.settings['events'] | |
|
142 | if event.name not in allowed_events: | |
|
143 | log.debug('event ignored: %r event %s not in allowed events %s', | |
|
144 | event, event.name, allowed_events) | |
|
143 | 145 | return |
|
144 | 146 | |
|
145 | 147 | data = event.as_dict() |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file renamed from rhodecode/controllers/utils.py to rhodecode/lib/view_utils.py | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: file was removed | |
The requested commit or file is too big and content was truncated. Show full diff |
General Comments 0
You need to be logged in to leave comments.
Login now