mirror of
https://github.com/go-gitea/gitea
synced 2024-12-22 12:47:53 +01:00
Merge branch 'master' into refactor_issues-subscription
This commit is contained in:
commit
cd6f2bef54
@ -24,7 +24,7 @@ indent_size = 2
|
|||||||
|
|
||||||
[*.js]
|
[*.js]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 2
|
||||||
|
|
||||||
[Makefile]
|
[Makefile]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
40
.eslintrc
40
.eslintrc
@ -1,27 +1,51 @@
|
|||||||
root: true
|
root: true
|
||||||
|
|
||||||
extends:
|
extends:
|
||||||
|
- eslint-config-airbnb-base
|
||||||
- eslint:recommended
|
- eslint:recommended
|
||||||
|
|
||||||
parserOptions:
|
parserOptions:
|
||||||
ecmaVersion: 2015
|
ecmaVersion: 2020
|
||||||
|
|
||||||
env:
|
env:
|
||||||
browser: true
|
browser: true
|
||||||
jquery: true
|
|
||||||
es6: true
|
es6: true
|
||||||
|
jquery: true
|
||||||
|
node: true
|
||||||
|
|
||||||
globals:
|
globals:
|
||||||
Clipboard: false
|
Clipboard: false
|
||||||
CodeMirror: false
|
CodeMirror: false
|
||||||
emojify: false
|
|
||||||
SimpleMDE: false
|
|
||||||
Vue: false
|
|
||||||
Dropzone: false
|
Dropzone: false
|
||||||
u2fApi: false
|
emojify: false
|
||||||
hljs: false
|
hljs: false
|
||||||
|
SimpleMDE: false
|
||||||
|
u2fApi: false
|
||||||
|
Vue: false
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
no-unused-vars: [error, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}]
|
camelcase: [0]
|
||||||
prefer-const: [2, {destructuring: all}]
|
comma-dangle: [2, only-multiline]
|
||||||
|
consistent-return: [0]
|
||||||
|
default-case: [0]
|
||||||
|
func-names: [0]
|
||||||
|
max-len: [0]
|
||||||
|
newline-per-chained-call: [0]
|
||||||
|
arrow-body-style: [0]
|
||||||
|
no-alert: [0]
|
||||||
|
no-continue: [0]
|
||||||
|
no-mixed-operators: [0]
|
||||||
|
no-multi-assign: [0]
|
||||||
|
no-new: [0]
|
||||||
|
no-param-reassign: [0]
|
||||||
|
no-plusplus: [0]
|
||||||
|
no-restricted-syntax: [0]
|
||||||
|
no-shadow: [0]
|
||||||
|
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}]
|
||||||
|
no-use-before-define: [0]
|
||||||
no-var: [2]
|
no-var: [2]
|
||||||
|
one-var-declaration-per-line: [0]
|
||||||
|
one-var: [0]
|
||||||
|
prefer-const: [2, {destructuring: all}]
|
||||||
|
prefer-destructuring: [0]
|
||||||
|
radix: [2, as-needed]
|
||||||
|
64
CHANGELOG.md
64
CHANGELOG.md
@ -4,11 +4,44 @@ This changelog goes through all the changes that have been made in each release
|
|||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
## [1.10.0-RC2](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc2) - 2019-10-30
|
## [1.10.0](https://github.com/go-gitea/gitea/releases/tag/v1.10.0) - 2019-11-13
|
||||||
* BREAKING
|
* BREAKING
|
||||||
* Fix deadline on update issue or PR via API (#8698)
|
* Fix deadline on update issue or PR via API (#8698)
|
||||||
* Hide some user information via API if user doesn't have enough permission (#8655) (#8657)
|
* Hide some user information via API if user doesn't have enough permission (#8655) (#8657)
|
||||||
|
* Remove legacy handling of drone token (#8191)
|
||||||
|
* Change repo search to use exact match for topic search. (#7941)
|
||||||
|
* Add pagination for admin api get orgs and fix only list public orgs bug (#7742)
|
||||||
|
* Implement the ability to change the ssh port to match what is in the gitea config (#7286)
|
||||||
|
* SECURITY
|
||||||
|
* Fix issue with user.fullname (#8903)
|
||||||
|
* Ignore mentions for users with no access (#8395)
|
||||||
|
* Be more strict with git arguments (#7715)
|
||||||
|
* Extract the username and password from the mirror url (#7651)
|
||||||
|
* reserve .well-known username (#7637)
|
||||||
|
* FEATURE
|
||||||
|
* Org/Members: display 2FA members states + optimize sql requests (#7621)
|
||||||
|
* SetDefaultBranch on pushing to empty repository (#7610)
|
||||||
|
* Adds side-by-side diff for images (#6784)
|
||||||
|
* API method to list all commits of a repository (#6408)
|
||||||
|
* Password Complexity Checks (#6230)
|
||||||
|
* Add option to initialize repository with labels (#6061)
|
||||||
|
* Add additional password hash algorithms (#6023)
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
* Allow to merge if file path contains " or \ (#8629) (#8771)
|
||||||
|
* On windows set core.longpaths true (#8776) (#8786)
|
||||||
|
* Fix 500 when edit hook (#8782) (#8789)
|
||||||
|
* Fix Checkbox at RepoSettings Protected Branch (#8799) (#8801)
|
||||||
|
* Fix SSH2 conditional in key parsing code (#8806) (#8810)
|
||||||
|
* Fix commit expand button to not go to commit link (#8745) (#8825)
|
||||||
|
* Fix new user form for non-local users (#8826) (#8828)
|
||||||
|
* Fix to close opened io resources as soon as not needed (#8839) (#8846)
|
||||||
|
* Fix edit content button on migrated issue content (#8877) (#8884)
|
||||||
|
* Fix require external registration password (#8885) (#8890)
|
||||||
|
* Fix password complexity check on registration (#8887) (#8888)
|
||||||
|
* Update Github Migration Tests (#8896) (#8938) (#8945)
|
||||||
|
* Enable punctuations ending mentions (#8889) (#8894)
|
||||||
|
* Add Close() method to gogitRepository (#8901) (#8956)
|
||||||
|
* Hotfix for review actions and notifications (#8965)
|
||||||
* Expose db.SetMaxOpenConns and allow non MySQL dbs to set conn pool params (#8528) (#8618)
|
* Expose db.SetMaxOpenConns and allow non MySQL dbs to set conn pool params (#8528) (#8618)
|
||||||
* Fix milestone close timestamp (#8728) (#8730)
|
* Fix milestone close timestamp (#8728) (#8730)
|
||||||
* Fix 500 when getting user as unauthenticated user (#8653) (#8663)
|
* Fix 500 when getting user as unauthenticated user (#8653) (#8663)
|
||||||
@ -29,22 +62,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* Fix password complexity regex for special characters (#8524)
|
* Fix password complexity regex for special characters (#8524)
|
||||||
* Prevent .code-view from overriding font on icon fonts (#8614) (#8627)
|
* Prevent .code-view from overriding font on icon fonts (#8614) (#8627)
|
||||||
* Allow more than 255 characters for tokens in external_login_user table (#8554)
|
* Allow more than 255 characters for tokens in external_login_user table (#8554)
|
||||||
|
|
||||||
## [1.10.0-RC1](https://github.com/go-gitea/gitea/releases/tag/v1.10.0-rc1) - 2019-10-14
|
|
||||||
* BREAKING
|
|
||||||
* Remove legacy handling of drone token (#8191)
|
|
||||||
* Change repo search to use exact match for topic search. (#7941)
|
|
||||||
* Add pagination for admin api get orgs and fix only list public orgs bug (#7742)
|
|
||||||
* Implement the ability to change the ssh port to match what is in the gitea config (#7286)
|
|
||||||
* FEATURE
|
|
||||||
* Org/Members: display 2FA members states + optimize sql requests (#7621)
|
|
||||||
* SetDefaultBranch on pushing to empty repository (#7610)
|
|
||||||
* Adds side-by-side diff for images (#6784)
|
|
||||||
* API method to list all commits of a repository (#6408)
|
|
||||||
* Password Complexity Checks (#6230)
|
|
||||||
* Add option to initialize repository with labels (#6061)
|
|
||||||
* Add additional password hash algorithms (#6023)
|
|
||||||
* BUGFIXES
|
|
||||||
* Fix errors in create org UI regarding team access permission (#8506)
|
* Fix errors in create org UI regarding team access permission (#8506)
|
||||||
* Fix bug on FindExternalUsersByProvider (#8504)
|
* Fix bug on FindExternalUsersByProvider (#8504)
|
||||||
* Create .ssh dir as necessary (#8486)
|
* Create .ssh dir as necessary (#8486)
|
||||||
@ -244,10 +261,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* Support setting cookie domain (#6288)
|
* Support setting cookie domain (#6288)
|
||||||
* Move migrating repository from frontend to backend (#6200)
|
* Move migrating repository from frontend to backend (#6200)
|
||||||
* Delete releases attachments if release is deleted (#6068)
|
* Delete releases attachments if release is deleted (#6068)
|
||||||
* SECURITY
|
|
||||||
* Ignore mentions for users with no access (#8395)
|
|
||||||
* Be more strict with git arguments (#7715)
|
|
||||||
* reserve .well-known username (#7637)
|
|
||||||
* TRANSLATION
|
* TRANSLATION
|
||||||
* Latvian translation for home page (#8468)
|
* Latvian translation for home page (#8468)
|
||||||
* Add home template italian translation (#8352)
|
* Add home template italian translation (#8352)
|
||||||
@ -276,7 +289,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* Fix global search result CSS, misc CSS tweaks (#7789)
|
* Fix global search result CSS, misc CSS tweaks (#7789)
|
||||||
* Tweak label border CSS (#7739)
|
* Tweak label border CSS (#7739)
|
||||||
* Fix create menu item widths (#7708)
|
* Fix create menu item widths (#7708)
|
||||||
* Extract the username and password from the mirror url (#7651)
|
|
||||||
* [Branch View] Delete duplicate protection symbol (#7624)
|
* [Branch View] Delete duplicate protection symbol (#7624)
|
||||||
* [Branch View] Delete Table Header (#7622)
|
* [Branch View] Delete Table Header (#7622)
|
||||||
* [Branch View] icons to buttons (#7602)
|
* [Branch View] icons to buttons (#7602)
|
||||||
@ -289,6 +301,14 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
|||||||
* wiki - editor - add buttons 'inline code', 'empty checkbox', 'checked checkbox' (#7243)
|
* wiki - editor - add buttons 'inline code', 'empty checkbox', 'checked checkbox' (#7243)
|
||||||
* Fix Statuses API only shows first 10 statuses: Add paging and extend API GetCommitStatuses (#7141)
|
* Fix Statuses API only shows first 10 statuses: Add paging and extend API GetCommitStatuses (#7141)
|
||||||
|
|
||||||
|
## [1.9.6](https://github.com/go-gitea/gitea/releases/tag/v1.9.6) - 2019-11-13
|
||||||
|
* BUGFIXES
|
||||||
|
* Allow to merge if file path contains " or \ (#8629) (#8772)
|
||||||
|
* Fix 500 when edit hook (#8782) (#8790)
|
||||||
|
* Fix issue with user.fullname (#8904)
|
||||||
|
* Update Github Migration Test (#8897) (#8946)
|
||||||
|
* Add Close() method to gogitRepository (#8901) (#8958)
|
||||||
|
|
||||||
## [1.9.5](https://github.com/go-gitea/gitea/releases/tag/v1.9.5) - 2019-10-30
|
## [1.9.5](https://github.com/go-gitea/gitea/releases/tag/v1.9.5) - 2019-10-30
|
||||||
* BREAKING
|
* BREAKING
|
||||||
* Hide some user information via API if user doesn't have enough permission (#8655) (#8658)
|
* Hide some user information via API if user doesn't have enough permission (#8655) (#8658)
|
||||||
|
3
Makefile
3
Makefile
@ -434,7 +434,8 @@ npm-update: npm-check
|
|||||||
|
|
||||||
.PHONY: js
|
.PHONY: js
|
||||||
js: npm
|
js: npm
|
||||||
npx eslint public/js
|
npx eslint web_src/js webpack.config.js
|
||||||
|
npx webpack
|
||||||
|
|
||||||
.PHONY: css
|
.PHONY: css
|
||||||
css: npm
|
css: npm
|
||||||
|
25
cmd/hook.go
25
cmd/hook.go
@ -16,6 +16,7 @@ import (
|
|||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/private"
|
"code.gitea.io/gitea/modules/private"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -55,7 +56,13 @@ var (
|
|||||||
|
|
||||||
func runHookPreReceive(c *cli.Context) error {
|
func runHookPreReceive(c *cli.Context) error {
|
||||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||||
return nil
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||||
|
fail(`Rejecting changes as Gitea environment not set.
|
||||||
|
If you are pushing over SSH you must push with a key managed by
|
||||||
|
Gitea or set your environment appropriately.`, "")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setup("hooks/pre-receive.log")
|
setup("hooks/pre-receive.log")
|
||||||
@ -115,7 +122,13 @@ func runHookPreReceive(c *cli.Context) error {
|
|||||||
|
|
||||||
func runHookUpdate(c *cli.Context) error {
|
func runHookUpdate(c *cli.Context) error {
|
||||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||||
return nil
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||||
|
fail(`Rejecting changes as Gitea environment not set.
|
||||||
|
If you are pushing over SSH you must push with a key managed by
|
||||||
|
Gitea or set your environment appropriately.`, "")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setup("hooks/update.log")
|
setup("hooks/update.log")
|
||||||
@ -125,7 +138,13 @@ func runHookUpdate(c *cli.Context) error {
|
|||||||
|
|
||||||
func runHookPostReceive(c *cli.Context) error {
|
func runHookPostReceive(c *cli.Context) error {
|
||||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||||
return nil
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||||
|
fail(`Rejecting changes as Gitea environment not set.
|
||||||
|
If you are pushing over SSH you must push with a key managed by
|
||||||
|
Gitea or set your environment appropriately.`, "")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setup("hooks/post-receive.log")
|
setup("hooks/post-receive.log")
|
||||||
|
@ -190,7 +190,7 @@ PROTOCOL = http
|
|||||||
DOMAIN = localhost
|
DOMAIN = localhost
|
||||||
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
||||||
; when STATIC_URL_PREFIX is empty it will follow APP_URL
|
; when STATIC_URL_PREFIX is empty it will follow APP_URL
|
||||||
STATIC_URL_PREFIX =
|
STATIC_URL_PREFIX =
|
||||||
; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket.
|
; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket.
|
||||||
HTTP_ADDR = 0.0.0.0
|
HTTP_ADDR = 0.0.0.0
|
||||||
HTTP_PORT = 3000
|
HTTP_PORT = 3000
|
||||||
@ -383,6 +383,8 @@ MIN_PASSWORD_LENGTH = 6
|
|||||||
IMPORT_LOCAL_PATHS = false
|
IMPORT_LOCAL_PATHS = false
|
||||||
; Set to true to prevent all users (including admin) from creating custom git hooks
|
; Set to true to prevent all users (including admin) from creating custom git hooks
|
||||||
DISABLE_GIT_HOOKS = false
|
DISABLE_GIT_HOOKS = false
|
||||||
|
; Set to false to allow pushes to gitea repositories despite having an incomplete environment - NOT RECOMMENDED
|
||||||
|
ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET = true
|
||||||
;Comma separated list of character classes required to pass minimum complexity.
|
;Comma separated list of character classes required to pass minimum complexity.
|
||||||
;If left empty or no valid values are specified, the default values ("lower,upper,digit,spec") will be used.
|
;If left empty or no valid values are specified, the default values ("lower,upper,digit,spec") will be used.
|
||||||
;Use "off" to disable checking.
|
;Use "off" to disable checking.
|
||||||
@ -515,9 +517,9 @@ SKIP_TLS_VERIFY = false
|
|||||||
; Number of history information in each page
|
; Number of history information in each page
|
||||||
PAGING_NUM = 10
|
PAGING_NUM = 10
|
||||||
; Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
; Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
||||||
PROXY_URL =
|
PROXY_URL =
|
||||||
; Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
; Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
||||||
PROXY_HOSTS =
|
PROXY_HOSTS =
|
||||||
|
|
||||||
[mailer]
|
[mailer]
|
||||||
ENABLED = false
|
ENABLED = false
|
||||||
|
1
docs/.gitignore
vendored
1
docs/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
public/
|
public/
|
||||||
templates/swagger/v1_json.tmpl
|
templates/swagger/v1_json.tmpl
|
||||||
themes/
|
themes/
|
||||||
|
resources/
|
||||||
|
176
docs/assets/js/search.js
Normal file
176
docs/assets/js/search.js
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
function ready(fn) {
|
||||||
|
if (document.readyState != 'loading') {
|
||||||
|
fn();
|
||||||
|
} else {
|
||||||
|
document.addEventListener('DOMContentLoaded', fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ready(doSearch);
|
||||||
|
|
||||||
|
const summaryInclude = 60;
|
||||||
|
const fuseOptions = {
|
||||||
|
shouldSort: true,
|
||||||
|
includeMatches: true,
|
||||||
|
matchAllTokens: true,
|
||||||
|
threshold: 0.0, // for parsing diacritics
|
||||||
|
tokenize: true,
|
||||||
|
location: 0,
|
||||||
|
distance: 100,
|
||||||
|
maxPatternLength: 32,
|
||||||
|
minMatchCharLength: 1,
|
||||||
|
keys: [{
|
||||||
|
name: "title",
|
||||||
|
weight: 0.8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "contents",
|
||||||
|
weight: 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "tags",
|
||||||
|
weight: 0.3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "categories",
|
||||||
|
weight: 0.3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
function param(name) {
|
||||||
|
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
let searchQuery = param("s");
|
||||||
|
|
||||||
|
function doSearch() {
|
||||||
|
if (searchQuery) {
|
||||||
|
document.getElementById("search-query").value = searchQuery;
|
||||||
|
executeSearch(searchQuery);
|
||||||
|
} else {
|
||||||
|
const para = document.createElement("P");
|
||||||
|
para.innerText = "Please enter a word or phrase above";
|
||||||
|
document.getElementById("search-results").appendChild(para);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getJSON(url, fn) {
|
||||||
|
const request = new XMLHttpRequest();
|
||||||
|
request.open('GET', url, true);
|
||||||
|
request.onload = function () {
|
||||||
|
if (request.status >= 200 && request.status < 400) {
|
||||||
|
const data = JSON.parse(request.responseText);
|
||||||
|
fn(data);
|
||||||
|
} else {
|
||||||
|
console.log("Target reached on " + url + " with error " + request.status);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
request.onerror = function () {
|
||||||
|
console.log("Connection error " + request.status);
|
||||||
|
};
|
||||||
|
request.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeSearch(searchQuery) {
|
||||||
|
getJSON("/" + document.LANG + "/index.json", function (data) {
|
||||||
|
const pages = data;
|
||||||
|
const fuse = new Fuse(pages, fuseOptions);
|
||||||
|
const result = fuse.search(searchQuery);
|
||||||
|
console.log({
|
||||||
|
"matches": result
|
||||||
|
});
|
||||||
|
document.getElementById("search-results").innerHTML = "";
|
||||||
|
if (result.length > 0) {
|
||||||
|
populateResults(result);
|
||||||
|
} else {
|
||||||
|
const para = document.createElement("P");
|
||||||
|
para.innerText = "No matches found";
|
||||||
|
document.getElementById("search-results").appendChild(para);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateResults(result) {
|
||||||
|
result.forEach(function (value, key) {
|
||||||
|
const content = value.item.contents;
|
||||||
|
let snippet = "";
|
||||||
|
const snippetHighlights = [];
|
||||||
|
if (fuseOptions.tokenize) {
|
||||||
|
snippetHighlights.push(searchQuery);
|
||||||
|
value.matches.forEach(function (mvalue) {
|
||||||
|
if (mvalue.key === "tags" || mvalue.key === "categories") {
|
||||||
|
snippetHighlights.push(mvalue.value);
|
||||||
|
} else if (mvalue.key === "contents") {
|
||||||
|
const ind = content.toLowerCase().indexOf(searchQuery.toLowerCase());
|
||||||
|
const start = ind - summaryInclude > 0 ? ind - summaryInclude : 0;
|
||||||
|
const end = ind + searchQuery.length + summaryInclude < content.length ? ind + searchQuery.length + summaryInclude : content.length;
|
||||||
|
snippet += content.substring(start, end);
|
||||||
|
if (ind > -1) {
|
||||||
|
snippetHighlights.push(content.substring(ind, ind + searchQuery.length))
|
||||||
|
} else {
|
||||||
|
snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snippet.length < 1) {
|
||||||
|
snippet += content.substring(0, summaryInclude * 2);
|
||||||
|
}
|
||||||
|
//pull template from hugo templarte definition
|
||||||
|
const templateDefinition = document.getElementById("search-result-template").innerHTML;
|
||||||
|
//replace values
|
||||||
|
const output = render(templateDefinition, {
|
||||||
|
key: key,
|
||||||
|
title: value.item.title,
|
||||||
|
link: value.item.permalink,
|
||||||
|
tags: value.item.tags,
|
||||||
|
categories: value.item.categories,
|
||||||
|
snippet: snippet
|
||||||
|
});
|
||||||
|
document.getElementById("search-results").appendChild(htmlToElement(output));
|
||||||
|
|
||||||
|
snippetHighlights.forEach(function (snipvalue) {
|
||||||
|
new Mark(document.getElementById("summary-" + key)).mark(snipvalue);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function render(templateString, data) {
|
||||||
|
let conditionalMatches, copy;
|
||||||
|
const conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g;
|
||||||
|
//since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
|
||||||
|
copy = templateString;
|
||||||
|
while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) {
|
||||||
|
if (data[conditionalMatches[1]]) {
|
||||||
|
//valid key, remove conditionals, leave content.
|
||||||
|
copy = copy.replace(conditionalMatches[0], conditionalMatches[2]);
|
||||||
|
} else {
|
||||||
|
//not valid, remove entire section
|
||||||
|
copy = copy.replace(conditionalMatches[0], '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
templateString = copy;
|
||||||
|
//now any conditionals removed we can do simple substitution
|
||||||
|
let key, find, re;
|
||||||
|
for (key in data) {
|
||||||
|
find = '\\$\\{\\s*' + key + '\\s*\\}';
|
||||||
|
re = new RegExp(find, 'g');
|
||||||
|
templateString = templateString.replace(re, data[key]);
|
||||||
|
}
|
||||||
|
return templateString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By Mark Amery: https://stackoverflow.com/a/35385518
|
||||||
|
* @param {String} HTML representing a single element
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
function htmlToElement(html) {
|
||||||
|
const template = document.createElement('template');
|
||||||
|
html = html.trim(); // Never return a text node of whitespace as the result
|
||||||
|
template.innerHTML = html;
|
||||||
|
return template.content.firstChild;
|
||||||
|
}
|
@ -18,7 +18,13 @@ params:
|
|||||||
description: Git with a cup of tea
|
description: Git with a cup of tea
|
||||||
author: The Gitea Authors
|
author: The Gitea Authors
|
||||||
website: https://docs.gitea.io
|
website: https://docs.gitea.io
|
||||||
version: 1.9.5
|
version: 1.10.0
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
home:
|
||||||
|
- HTML
|
||||||
|
- RSS
|
||||||
|
- JSON
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
page:
|
page:
|
||||||
|
@ -244,6 +244,7 @@ relation to port exhaustion.
|
|||||||
authentication provided email.
|
authentication provided email.
|
||||||
- `DISABLE_GIT_HOOKS`: **false**: Set to `true` to prevent all users (including admin) from creating custom
|
- `DISABLE_GIT_HOOKS`: **false**: Set to `true` to prevent all users (including admin) from creating custom
|
||||||
git hooks.
|
git hooks.
|
||||||
|
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to gitea repositories you should set the environment appropriately.
|
||||||
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
|
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
|
||||||
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
|
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
|
||||||
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
||||||
@ -306,6 +307,7 @@ relation to port exhaustion.
|
|||||||
- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch a repository after their first commit to it
|
- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch a repository after their first commit to it
|
||||||
- `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private".
|
- `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private".
|
||||||
- `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation.
|
- `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation.
|
||||||
|
- `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services.
|
||||||
|
|
||||||
## Webhook (`webhook`)
|
## Webhook (`webhook`)
|
||||||
|
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
date: "2017-01-20T15:00:00+08:00"
|
date: "2017-01-20T15:00:00+08:00"
|
||||||
title: "Help"
|
title: "Help"
|
||||||
slug: "help"
|
slug: "help"
|
||||||
weight: 50
|
weight: 5
|
||||||
toc: false
|
toc: false
|
||||||
draft: false
|
draft: false
|
||||||
menu:
|
menu:
|
||||||
sidebar:
|
sidebar:
|
||||||
name: "Help"
|
name: "Help"
|
||||||
weight: 50
|
weight: 5
|
||||||
identifier: "help"
|
identifier: "help"
|
||||||
---
|
---
|
||||||
|
13
docs/content/doc/help.fr-fr.md
Normal file
13
docs/content/doc/help.fr-fr.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
date: "2017-01-20T15:00:00+08:00"
|
||||||
|
title: "Aide"
|
||||||
|
slug: "help"
|
||||||
|
weight: 5
|
||||||
|
toc: false
|
||||||
|
draft: false
|
||||||
|
menu:
|
||||||
|
sidebar:
|
||||||
|
name: "Aide"
|
||||||
|
weight: 5
|
||||||
|
identifier: "help"
|
||||||
|
---
|
@ -2,12 +2,12 @@
|
|||||||
date: "2017-01-20T15:00:00+08:00"
|
date: "2017-01-20T15:00:00+08:00"
|
||||||
title: "帮助"
|
title: "帮助"
|
||||||
slug: "help"
|
slug: "help"
|
||||||
weight: 50
|
weight: 5
|
||||||
toc: false
|
toc: false
|
||||||
draft: false
|
draft: false
|
||||||
menu:
|
menu:
|
||||||
sidebar:
|
sidebar:
|
||||||
name: "帮助"
|
name: "帮助"
|
||||||
weight: 50
|
weight: 5
|
||||||
identifier: "help"
|
identifier: "help"
|
||||||
---
|
---
|
||||||
|
13
docs/content/doc/help.zh-tw.md
Normal file
13
docs/content/doc/help.zh-tw.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
date: "2017-01-20T15:00:00+08:00"
|
||||||
|
title: "救命"
|
||||||
|
slug: "help"
|
||||||
|
weight: 5
|
||||||
|
toc: false
|
||||||
|
draft: false
|
||||||
|
menu:
|
||||||
|
sidebar:
|
||||||
|
name: "救命"
|
||||||
|
weight: 5
|
||||||
|
identifier: "help"
|
||||||
|
---
|
25
docs/content/doc/help/search.en-us.md
Normal file
25
docs/content/doc/help/search.en-us.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
date: "2019-11-12T16:00:00+02:00"
|
||||||
|
title: "Search"
|
||||||
|
slug: "search"
|
||||||
|
weight: 4
|
||||||
|
toc: true
|
||||||
|
draft: false
|
||||||
|
menu:
|
||||||
|
sidebar:
|
||||||
|
parent: "help"
|
||||||
|
name: "Search"
|
||||||
|
weight: 4
|
||||||
|
identifier: "search"
|
||||||
|
sitemap:
|
||||||
|
priority : 0.1
|
||||||
|
layout: "search"
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||||
|
|
||||||
|
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||||
|
|
||||||
|
Setting a very low sitemap priority will tell search engines this is not important content.
|
||||||
|
|
25
docs/content/doc/help/search.fr-fr.md
Normal file
25
docs/content/doc/help/search.fr-fr.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
date: "2019-11-12T16:00:00+02:00"
|
||||||
|
title: "Chercher"
|
||||||
|
slug: "search"
|
||||||
|
weight: 4
|
||||||
|
toc: true
|
||||||
|
draft: false
|
||||||
|
menu:
|
||||||
|
sidebar:
|
||||||
|
parent: "help"
|
||||||
|
name: "Chercher"
|
||||||
|
weight: 4
|
||||||
|
identifier: "search"
|
||||||
|
sitemap:
|
||||||
|
priority : 0.1
|
||||||
|
layout: "search"
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||||
|
|
||||||
|
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||||
|
|
||||||
|
Setting a very low sitemap priority will tell search engines this is not important content.
|
||||||
|
|
25
docs/content/doc/help/search.zh-cn.md
Normal file
25
docs/content/doc/help/search.zh-cn.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
date: "2019-11-12T16:00:00+02:00"
|
||||||
|
title: "搜索"
|
||||||
|
slug: "search"
|
||||||
|
weight: 4
|
||||||
|
toc: true
|
||||||
|
draft: false
|
||||||
|
menu:
|
||||||
|
sidebar:
|
||||||
|
parent: "help"
|
||||||
|
name: "搜索"
|
||||||
|
weight: 4
|
||||||
|
identifier: "search"
|
||||||
|
sitemap:
|
||||||
|
priority : 0.1
|
||||||
|
layout: "search"
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||||
|
|
||||||
|
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||||
|
|
||||||
|
Setting a very low sitemap priority will tell search engines this is not important content.
|
||||||
|
|
25
docs/content/doc/help/search.zh-tw.md
Normal file
25
docs/content/doc/help/search.zh-tw.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
date: "2019-11-12T16:00:00+02:00"
|
||||||
|
title: "搜索"
|
||||||
|
slug: "search"
|
||||||
|
weight: 4
|
||||||
|
toc: true
|
||||||
|
draft: false
|
||||||
|
menu:
|
||||||
|
sidebar:
|
||||||
|
parent: "help"
|
||||||
|
name: "搜索"
|
||||||
|
weight: 4
|
||||||
|
identifier: "search"
|
||||||
|
sitemap:
|
||||||
|
priority : 0.1
|
||||||
|
layout: "search"
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||||
|
|
||||||
|
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||||
|
|
||||||
|
Setting a very low sitemap priority will tell search engines this is not important content.
|
||||||
|
|
@ -40,7 +40,7 @@ To register Gitea as a Windows service, open a command prompt (cmd) as an Admini
|
|||||||
then run the following command:
|
then run the following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini""
|
sc create gitea start= auto binPath= "\"C:\gitea\gitea.exe\" web --config \"C:\gitea\custom\conf\app.ini\""
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not forget to replace `C:\gitea` with the correct Gitea directory.
|
Do not forget to replace `C:\gitea` with the correct Gitea directory.
|
||||||
|
@ -18,7 +18,7 @@ menu:
|
|||||||
Pour activer le service Windows Gitea, ouvrez une `cmd` en tant qu'Administrateur puis utilisez la commande suivante :
|
Pour activer le service Windows Gitea, ouvrez une `cmd` en tant qu'Administrateur puis utilisez la commande suivante :
|
||||||
|
|
||||||
```
|
```
|
||||||
sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini""
|
sc create gitea start= auto binPath= "\"C:\gitea\gitea.exe\" web --config \"C:\gitea\custom\conf\app.ini\""
|
||||||
```
|
```
|
||||||
|
|
||||||
N'oubliez pas de remplacer `C:\gitea` par le chemin que vous avez utilisez pour votre installation.
|
N'oubliez pas de remplacer `C:\gitea` par le chemin que vous avez utilisez pour votre installation.
|
||||||
|
@ -18,7 +18,7 @@ menu:
|
|||||||
要注册为Windows服务,首先以Administrator身份运行 `cmd`,然后执行以下命令:
|
要注册为Windows服务,首先以Administrator身份运行 `cmd`,然后执行以下命令:
|
||||||
|
|
||||||
```
|
```
|
||||||
sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini""
|
sc create gitea start= auto binPath= "\"C:\gitea\gitea.exe\" web --config \"C:\gitea\custom\conf\app.ini\""
|
||||||
```
|
```
|
||||||
|
|
||||||
别忘了将 `C:\gitea` 替换成你的 Gitea 安装目录。
|
别忘了将 `C:\gitea` 替换成你的 Gitea 安装目录。
|
||||||
|
@ -18,7 +18,7 @@ menu:
|
|||||||
要註冊為 Windows 服務,首先要以管理者身份執行 `cmd`,跳出命令列視窗後執行底下指令:
|
要註冊為 Windows 服務,首先要以管理者身份執行 `cmd`,跳出命令列視窗後執行底下指令:
|
||||||
|
|
||||||
```
|
```
|
||||||
sc create gitea start= auto binPath= ""C:\gitea\gitea.exe" web --config "C:\gitea\custom\conf\app.ini""
|
sc create gitea start= auto binPath= "\"C:\gitea\gitea.exe\" web --config \"C:\gitea\custom\conf\app.ini\""
|
||||||
```
|
```
|
||||||
|
|
||||||
別忘記將 `C:\gitea` 取代為您的 Gitea 安裝路徑。
|
別忘記將 `C:\gitea` 取代為您的 Gitea 安裝路徑。
|
||||||
|
@ -51,6 +51,8 @@ services:
|
|||||||
- gitea
|
- gitea
|
||||||
volumes:
|
volumes:
|
||||||
- ./gitea:/data
|
- ./gitea:/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
- "222:22"
|
- "222:22"
|
||||||
@ -80,6 +82,8 @@ services:
|
|||||||
- gitea
|
- gitea
|
||||||
volumes:
|
volumes:
|
||||||
- ./gitea:/data
|
- ./gitea:/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- - "3000:3000"
|
- - "3000:3000"
|
||||||
- - "222:22"
|
- - "222:22"
|
||||||
@ -115,6 +119,8 @@ services:
|
|||||||
- gitea
|
- gitea
|
||||||
volumes:
|
volumes:
|
||||||
- ./gitea:/data
|
- ./gitea:/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
- "222:22"
|
- "222:22"
|
||||||
@ -163,6 +169,8 @@ services:
|
|||||||
- gitea
|
- gitea
|
||||||
volumes:
|
volumes:
|
||||||
- ./gitea:/data
|
- ./gitea:/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
- "222:22"
|
- "222:22"
|
||||||
@ -209,6 +217,8 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- - ./gitea:/data
|
- - ./gitea:/data
|
||||||
+ - gitea:/data
|
+ - gitea:/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
- "222:22"
|
- "222:22"
|
||||||
@ -306,6 +316,8 @@ UID/GID as the container values `USER_UID`/`USER_GID`. You should also create th
|
|||||||
- gitea
|
- gitea
|
||||||
volumes:
|
volumes:
|
||||||
- /var/lib/gitea:/data
|
- /var/lib/gitea:/data
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
- "127.0.0.1:2222:22"
|
- "127.0.0.1:2222:22"
|
||||||
|
5
docs/layouts/_default/index.json
Normal file
5
docs/layouts/_default/index.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{{- $.Scratch.Add "index" slice -}}
|
||||||
|
{{- range .Site.RegularPages -}}
|
||||||
|
{{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- $.Scratch.Get "index" | jsonify -}}
|
44
docs/layouts/doc/search.html
Normal file
44
docs/layouts/doc/search.html
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{{ partial "header.html" . }}
|
||||||
|
{{ partial "navbar.html" . }}
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<div class="container is-centered page">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-one-quarter">
|
||||||
|
{{ partial "menu" . }}
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class=" content">
|
||||||
|
<section class="resume-section p-3 p-lg-5 d-flex flex-column">
|
||||||
|
<div class="my-auto" >
|
||||||
|
<form action="{{ "search" | absLangURL }}">
|
||||||
|
<label>Search:
|
||||||
|
<input id="search-query" name="s"/>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
<br/>
|
||||||
|
<div id="search-results"></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!-- this template is sucked in by search.js and appended to the search-results div above. So editing here will adjust style -->
|
||||||
|
<script id="search-result-template" type="text/x-js-template">
|
||||||
|
<div id="summary-${key}">
|
||||||
|
<h4><a href="${link}">${title}</a></h4>
|
||||||
|
<p>${snippet}</p>
|
||||||
|
${ isset tags }<p>Tags: ${tags}</p>${ end }
|
||||||
|
${ isset categories }<p>Categories: ${categories}</p>${ end }
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.4.5/fuse.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js"></script>
|
||||||
|
<script>document.LANG = "{{ .Language.Lang }}";</script>
|
||||||
|
{{ $script := resources.Get "js/search.js" | minify | fingerprint -}}
|
||||||
|
<script src="{{ $script.Permalink }}" {{ printf "integrity=%q" $script.Data.Integrity | safeHTMLAttr }}></script>
|
||||||
|
{{ partial "footer.html" . }}
|
2
docs/static/_headers
vendored
2
docs/static/_headers
vendored
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com
|
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; style-src 'self' https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com
|
||||||
X-Frame-Options: DENY
|
X-Frame-Options: DENY
|
||||||
X-Xss-Protection: 1; mode=block
|
X-Xss-Protection: 1; mode=block
|
||||||
X-Content-Type-Options: nosniff
|
X-Content-Type-Options: nosniff
|
||||||
|
1
go.mod
1
go.mod
@ -80,7 +80,6 @@ require (
|
|||||||
github.com/prometheus/client_golang v1.1.0
|
github.com/prometheus/client_golang v1.1.0
|
||||||
github.com/prometheus/procfs v0.0.4 // indirect
|
github.com/prometheus/procfs v0.0.4 // indirect
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
|
||||||
github.com/russross/blackfriday v2.0.0+incompatible // indirect
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1
|
github.com/russross/blackfriday/v2 v2.0.1
|
||||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
|
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/satori/go.uuid v1.2.0
|
||||||
|
45
go.sum
45
go.sum
@ -1,12 +1,10 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
|
|
||||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||||
cloud.google.com/go v0.44.3 h1:0sMegbmn/8uTwpNkB0q9cLEpZ2W5a6kl+wtBQgPWBJQ=
|
|
||||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||||
cloud.google.com/go v0.45.0 h1:bALuGBSgE+BD4rxsopAYlqjcwqcQtye6pWG4bC3N/k0=
|
cloud.google.com/go v0.45.0 h1:bALuGBSgE+BD4rxsopAYlqjcwqcQtye6pWG4bC3N/k0=
|
||||||
cloud.google.com/go v0.45.0/go.mod h1:452BcPOeI9AZfbvDw0Tbo7D32wA+WX9WME8AZwMEDZU=
|
cloud.google.com/go v0.45.0/go.mod h1:452BcPOeI9AZfbvDw0Tbo7D32wA+WX9WME8AZwMEDZU=
|
||||||
@ -67,7 +65,6 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l
|
|||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
@ -167,7 +164,6 @@ github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70t
|
|||||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||||
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||||
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
||||||
github.com/go-openapi/analysis v0.19.4 h1:1TjOzrWkj+9BrjnM1yPAICbaoC0FyfD49oVkTBrSSa0=
|
|
||||||
github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
|
||||||
github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOXdfYzI=
|
github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOXdfYzI=
|
||||||
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
|
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
|
||||||
@ -179,39 +175,33 @@ github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNP
|
|||||||
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
||||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||||
github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0=
|
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||||
github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
|
|
||||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||||
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
||||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||||
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||||
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||||
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
|
||||||
github.com/go-openapi/loads v0.19.2 h1:rf5ArTHmIJxyV5Oiks+Su0mUens1+AjpkPoWr5xFRcI=
|
|
||||||
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
|
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
|
||||||
github.com/go-openapi/loads v0.19.3 h1:jwIoahqCmaA5OBoc/B+1+Mu2L0Gr8xYQnbeyQEo/7b0=
|
github.com/go-openapi/loads v0.19.3 h1:jwIoahqCmaA5OBoc/B+1+Mu2L0Gr8xYQnbeyQEo/7b0=
|
||||||
github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI=
|
github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI=
|
||||||
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
|
||||||
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
|
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
|
||||||
github.com/go-openapi/runtime v0.19.4 h1:csnOgcgAiuGoM/Po7PEpKDoNulCcF3FGbSnbHfxgjMI=
|
|
||||||
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
|
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
|
||||||
github.com/go-openapi/runtime v0.19.5 h1:h4Zk7oTfB3ZYM2oMNliQvL+3BrDstTIX8lqP7yaYCuI=
|
github.com/go-openapi/runtime v0.19.5 h1:h4Zk7oTfB3ZYM2oMNliQvL+3BrDstTIX8lqP7yaYCuI=
|
||||||
github.com/go-openapi/runtime v0.19.5/go.mod h1:WIH6IYPXOrtgTClTV8xzdrD20jBlrK25D0aQbdSlqp8=
|
github.com/go-openapi/runtime v0.19.5/go.mod h1:WIH6IYPXOrtgTClTV8xzdrD20jBlrK25D0aQbdSlqp8=
|
||||||
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||||
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||||
github.com/go-openapi/spec v0.19.2 h1:SStNd1jRcYtfKCN7R0laGNs80WYYvn5CbBjM2sOmCrE=
|
|
||||||
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
|
||||||
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
|
github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
|
||||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||||
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||||
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
|
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
|
||||||
github.com/go-openapi/strfmt v0.19.2 h1:clPGfBnJohokno0e+d7hs6Yocrzjlgz6EsQSDncCRnE=
|
|
||||||
github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
||||||
github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA=
|
github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA=
|
||||||
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
|
||||||
@ -221,7 +211,6 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
|||||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||||
github.com/go-openapi/validate v0.19.2 h1:ky5l57HjyVRrsJfd2+Ro5Z9PjGuKbsmftwyMtk8H7js=
|
|
||||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||||
github.com/go-openapi/validate v0.19.3 h1:PAH/2DylwWcIU1s0Y7k3yNmeAgWOcKrNE2Q7Ww/kCg4=
|
github.com/go-openapi/validate v0.19.3 h1:PAH/2DylwWcIU1s0Y7k3yNmeAgWOcKrNE2Q7Ww/kCg4=
|
||||||
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
|
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
|
||||||
@ -255,18 +244,15 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
|||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
@ -288,7 +274,6 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
|
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
|
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
@ -302,7 +287,6 @@ github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5
|
|||||||
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
|
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
|
||||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
github.com/gorilla/sessions v1.1.1 h1:YMDmfaK68mUixINzY/XjscuJ47uXFWSSHzFbBQM0PrE=
|
|
||||||
github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||||
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
|
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
|
||||||
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||||
@ -385,7 +369,6 @@ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
|
|||||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
@ -423,21 +406,15 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
|
|||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY=
|
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5 h1:BvoENQQU+fZ9uukda/RzCAL/191HHwJA5b13R6diVlY=
|
||||||
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20160724205520-891127d8d1b5/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/niklasfasching/go-org v0.1.6 h1:F521WcqRNl8OJumlgAnekZgERaTA2HpfOYYfVEKOeI8=
|
|
||||||
github.com/niklasfasching/go-org v0.1.6/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
|
||||||
github.com/niklasfasching/go-org v0.1.7 h1:t3V+3XnS/7BhKv/7SlMUa8FvAiq577/a1T3D7mLIRXE=
|
|
||||||
github.com/niklasfasching/go-org v0.1.7/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
|
||||||
github.com/niklasfasching/go-org v0.1.8 h1:Kjvs6lP+LIILHhc9zIJ4Gu90a/pVY483if2Qmu8v4Fg=
|
github.com/niklasfasching/go-org v0.1.8 h1:Kjvs6lP+LIILHhc9zIJ4Gu90a/pVY483if2Qmu8v4Fg=
|
||||||
github.com/niklasfasching/go-org v0.1.8/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
github.com/niklasfasching/go-org v0.1.8/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
|
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
|
||||||
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
|
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
||||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
@ -466,7 +443,6 @@ github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb
|
|||||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
@ -491,8 +467,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qq
|
|||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/russross/blackfriday v2.0.0+incompatible h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk=
|
|
||||||
github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||||
@ -503,8 +477,6 @@ github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
|||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc h1:3wIrJvFb3Pf6B/2mDBnN1G5IfUVev4X5apadQlWOczE=
|
|
||||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
|
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
|
||||||
@ -517,7 +489,6 @@ github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z
|
|||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
|
|
||||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
|
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
|
||||||
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||||
@ -548,11 +519,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66 h1:AwmkkZT+TucFotNCL+aNJ/0KCMsRtlXN9fs8uoOMSRk=
|
|
||||||
github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
@ -594,7 +563,6 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
|||||||
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
go.mongodb.org/mongo-driver v1.1.0 h1:aeOqSrhl9eDRAap/3T5pCfMBEBxZ0vuXBP+RMtp2KX8=
|
|
||||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
go.mongodb.org/mongo-driver v1.1.1 h1:Sq1fR+0c58RME5EoqKdjkiQAmPjmfHlZOoRI6fTUOcs=
|
go.mongodb.org/mongo-driver v1.1.1 h1:Sq1fR+0c58RME5EoqKdjkiQAmPjmfHlZOoRI6fTUOcs=
|
||||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
@ -614,7 +582,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ=
|
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ=
|
||||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
@ -651,20 +618,13 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
|
||||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc=
|
|
||||||
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss=
|
|
||||||
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 h1:DPz9iiH3YoKiKhX/ijjoZvT0VFwK2c6CWYWQ7Zyr8TU=
|
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 h1:DPz9iiH3YoKiKhX/ijjoZvT0VFwK2c6CWYWQ7Zyr8TU=
|
||||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -694,7 +654,6 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
|
|
||||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b h1:3S2h5FadpNr0zUUCVZjlKIEYF+KaX/OBplTGo89CYHI=
|
golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b h1:3S2h5FadpNr0zUUCVZjlKIEYF+KaX/OBplTGo89CYHI=
|
||||||
@ -738,9 +697,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
|||||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw=
|
|
||||||
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
google.golang.org/appengine v1.6.4 h1:WiKh4+/eMB2HaY7QhCfW/R7MuRAoA8QMCSJA6jP5/fo=
|
google.golang.org/appengine v1.6.4 h1:WiKh4+/eMB2HaY7QhCfW/R7MuRAoA8QMCSJA6jP5/fo=
|
||||||
google.golang.org/appengine v1.6.4/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
google.golang.org/appengine v1.6.4/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
@ -764,7 +721,6 @@ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod
|
|||||||
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ=
|
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ=
|
||||||
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@ -776,7 +732,6 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkp
|
|||||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg=
|
gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg=
|
||||||
gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag=
|
|
||||||
gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.48.0 h1:URjZc+8ugRY5mL5uUeQH/a63JcHwdX9xZaWvmNWD7z8=
|
gopkg.in/ini.v1 v1.48.0 h1:URjZc+8ugRY5mL5uUeQH/a63JcHwdX9xZaWvmNWD7z8=
|
||||||
gopkg.in/ini.v1 v1.48.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.48.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
@ -79,8 +79,10 @@ func allowLFSFilters() []string {
|
|||||||
return globalArgs
|
return globalArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL)) {
|
func onGiteaRun(t *testing.T, callback func(*testing.T, *url.URL), prepare ...bool) {
|
||||||
prepareTestEnv(t, 1)
|
if len(prepare) == 0 || prepare[0] {
|
||||||
|
prepareTestEnv(t, 1)
|
||||||
|
}
|
||||||
s := http.Server{
|
s := http.Server{
|
||||||
Handler: mac,
|
Handler: mac,
|
||||||
}
|
}
|
||||||
|
@ -23,14 +23,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestGPGGit(t *testing.T) {
|
func TestGPGGit(t *testing.T) {
|
||||||
onGiteaRun(t, testGPGGit)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testGPGGit(t *testing.T, u *url.URL) {
|
|
||||||
username := "user2"
|
username := "user2"
|
||||||
baseAPITestContext := NewAPITestContext(t, username, "repo1")
|
|
||||||
|
|
||||||
u.Path = baseAPITestContext.GitPath()
|
|
||||||
|
|
||||||
// OK Set a new GPG home
|
// OK Set a new GPG home
|
||||||
tmpDir, err := ioutil.TempDir("", "temp-gpg")
|
tmpDir, err := ioutil.TempDir("", "temp-gpg")
|
||||||
@ -65,130 +58,218 @@ func testGPGGit(t *testing.T, u *url.URL) {
|
|||||||
setting.Repository.Signing.SigningEmail = "gitea@fake.local"
|
setting.Repository.Signing.SigningEmail = "gitea@fake.local"
|
||||||
user := models.AssertExistsAndLoadBean(t, &models.User{Name: username}).(*models.User)
|
user := models.AssertExistsAndLoadBean(t, &models.User{Name: username}).(*models.User)
|
||||||
|
|
||||||
t.Run("Unsigned-Initial", func(t *testing.T) {
|
setting.Repository.Signing.InitialCommit = []string{"never"}
|
||||||
PrintCurrentTest(t)
|
setting.Repository.Signing.CRUDActions = []string{"never"}
|
||||||
setting.Repository.Signing.InitialCommit = []string{"never"}
|
|
||||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
baseAPITestContext := NewAPITestContext(t, username, "repo1")
|
||||||
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
u.Path = baseAPITestContext.GitPath()
|
||||||
assert.NotNil(t, branch.Commit)
|
|
||||||
assert.NotNil(t, branch.Commit.Verification)
|
t.Run("Unsigned-Initial", func(t *testing.T) {
|
||||||
assert.False(t, branch.Commit.Verification.Verified)
|
PrintCurrentTest(t)
|
||||||
assert.Empty(t, branch.Commit.Verification.Signature)
|
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||||
}))
|
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
|
||||||
setting.Repository.Signing.CRUDActions = []string{"never"}
|
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||||
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
assert.NotNil(t, branch.Commit)
|
||||||
t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) {
|
assert.NotNil(t, branch.Commit.Verification)
|
||||||
assert.False(t, response.Verification.Verified)
|
assert.False(t, branch.Commit.Verification.Verified)
|
||||||
|
assert.Empty(t, branch.Commit.Verification.Signature)
|
||||||
}))
|
}))
|
||||||
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
||||||
t, testCtx, user, "never", "never2", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) {
|
t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
assert.False(t, response.Verification.Verified)
|
assert.False(t, response.Verification.Verified)
|
||||||
|
}))
|
||||||
|
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "never", "never2", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.False(t, response.Verification.Verified)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}, false)
|
||||||
|
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("Unsigned-Initial-CRUD-ParentSigned", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||||
|
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.False(t, response.Verification.Verified)
|
||||||
|
}))
|
||||||
|
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "parentsigned", "parentsigned2", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.False(t, response.Verification.Verified)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}, false)
|
||||||
|
setting.Repository.Signing.CRUDActions = []string{"never"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("Unsigned-Initial-CRUD-Never", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||||
|
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "parentsigned", "parentsigned-never", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.False(t, response.Verification.Verified)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}, false)
|
||||||
|
setting.Repository.Signing.CRUDActions = []string{"always"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("Unsigned-Initial-CRUD-Always", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||||
|
t.Run("CreateCRUDFile-Always", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.True(t, response.Verification.Verified)
|
||||||
|
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||||
|
}))
|
||||||
|
t.Run("CreateCRUDFile-ParentSigned-always", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "parentsigned", "parentsigned-always", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.True(t, response.Verification.Verified)
|
||||||
|
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}, false)
|
||||||
|
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("Unsigned-Initial-CRUD-ParentSigned", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||||
|
t.Run("CreateCRUDFile-Always-ParentSigned", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "always", "always-parentsigned", "signed-always-parentsigned.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.True(t, response.Verification.Verified)
|
||||||
|
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}, false)
|
||||||
|
setting.Repository.Signing.InitialCommit = []string{"always"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("AlwaysSign-Initial", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-always")
|
||||||
|
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
|
||||||
|
t.Run("CheckMasterBranchSigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||||
|
assert.NotNil(t, branch.Commit)
|
||||||
|
assert.NotNil(t, branch.Commit.Verification)
|
||||||
|
assert.True(t, branch.Commit.Verification.Verified)
|
||||||
|
assert.Equal(t, "gitea@fake.local", branch.Commit.Verification.Signer.Email)
|
||||||
}))
|
}))
|
||||||
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
})
|
||||||
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
}, false)
|
||||||
t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) {
|
setting.Repository.Signing.CRUDActions = []string{"never"}
|
||||||
assert.False(t, response.Verification.Verified)
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("AlwaysSign-Initial-CRUD-Never", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-always")
|
||||||
|
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.False(t, response.Verification.Verified)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}, false)
|
||||||
|
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("AlwaysSign-Initial-CRUD-ParentSigned-On-Always", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-always")
|
||||||
|
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.True(t, response.Verification.Verified)
|
||||||
|
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}, false)
|
||||||
|
setting.Repository.Signing.CRUDActions = []string{"always"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("AlwaysSign-Initial-CRUD-Always", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-always")
|
||||||
|
t.Run("CreateCRUDFile-Always", crudActionCreateFile(
|
||||||
|
t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) {
|
||||||
|
assert.True(t, response.Verification.Verified)
|
||||||
|
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
||||||
|
}))
|
||||||
|
|
||||||
|
})
|
||||||
|
}, false)
|
||||||
|
var pr api.PullRequest
|
||||||
|
setting.Repository.Signing.Merges = []string{"commitssigned"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("UnsignedMerging", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||||
|
var err error
|
||||||
|
t.Run("CreatePullRequest", func(t *testing.T) {
|
||||||
|
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "never2")(t)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
||||||
|
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||||
|
assert.NotNil(t, branch.Commit)
|
||||||
|
assert.NotNil(t, branch.Commit.Verification)
|
||||||
|
assert.False(t, branch.Commit.Verification.Verified)
|
||||||
|
assert.Empty(t, branch.Commit.Verification.Signature)
|
||||||
}))
|
}))
|
||||||
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
})
|
||||||
t, testCtx, user, "parentsigned", "parentsigned2", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) {
|
}, false)
|
||||||
assert.False(t, response.Verification.Verified)
|
setting.Repository.Signing.Merges = []string{"basesigned"}
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
u.Path = baseAPITestContext.GitPath()
|
||||||
|
|
||||||
|
t.Run("BaseSignedMerging", func(t *testing.T) {
|
||||||
|
PrintCurrentTest(t)
|
||||||
|
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||||
|
var err error
|
||||||
|
t.Run("CreatePullRequest", func(t *testing.T) {
|
||||||
|
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "parentsigned2")(t)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
||||||
|
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||||
|
assert.NotNil(t, branch.Commit)
|
||||||
|
assert.NotNil(t, branch.Commit.Verification)
|
||||||
|
assert.False(t, branch.Commit.Verification.Verified)
|
||||||
|
assert.Empty(t, branch.Commit.Verification.Signature)
|
||||||
}))
|
}))
|
||||||
setting.Repository.Signing.CRUDActions = []string{"never"}
|
})
|
||||||
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
}, false)
|
||||||
t, testCtx, user, "parentsigned", "parentsigned-never", "unsigned-never2.txt", func(t *testing.T, response api.FileResponse) {
|
setting.Repository.Signing.Merges = []string{"commitssigned"}
|
||||||
assert.False(t, response.Verification.Verified)
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
}))
|
u.Path = baseAPITestContext.GitPath()
|
||||||
setting.Repository.Signing.CRUDActions = []string{"always"}
|
|
||||||
t.Run("CreateCRUDFile-Always", crudActionCreateFile(
|
t.Run("CommitsSignedMerging", func(t *testing.T) {
|
||||||
t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) {
|
PrintCurrentTest(t)
|
||||||
assert.True(t, response.Verification.Verified)
|
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
||||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
var err error
|
||||||
}))
|
t.Run("CreatePullRequest", func(t *testing.T) {
|
||||||
t.Run("CreateCRUDFile-ParentSigned-always", crudActionCreateFile(
|
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "always-parentsigned")(t)
|
||||||
t, testCtx, user, "parentsigned", "parentsigned-always", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) {
|
assert.NoError(t, err)
|
||||||
assert.True(t, response.Verification.Verified)
|
})
|
||||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
||||||
}))
|
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
||||||
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
assert.NotNil(t, branch.Commit)
|
||||||
t.Run("CreateCRUDFile-Always-ParentSigned", crudActionCreateFile(
|
assert.NotNil(t, branch.Commit.Verification)
|
||||||
t, testCtx, user, "always", "always-parentsigned", "signed-always-parentsigned.txt", func(t *testing.T, response api.FileResponse) {
|
assert.True(t, branch.Commit.Verification.Verified)
|
||||||
assert.True(t, response.Verification.Verified)
|
|
||||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
t.Run("AlwaysSign-Initial", func(t *testing.T) {
|
|
||||||
PrintCurrentTest(t)
|
|
||||||
setting.Repository.Signing.InitialCommit = []string{"always"}
|
|
||||||
testCtx := NewAPITestContext(t, username, "initial-always")
|
|
||||||
t.Run("CreateRepository", doAPICreateRepository(testCtx, false))
|
|
||||||
t.Run("CheckMasterBranchSigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
|
||||||
assert.NotNil(t, branch.Commit)
|
|
||||||
assert.NotNil(t, branch.Commit.Verification)
|
|
||||||
assert.True(t, branch.Commit.Verification.Verified)
|
|
||||||
assert.Equal(t, "gitea@fake.local", branch.Commit.Verification.Signer.Email)
|
|
||||||
}))
|
|
||||||
setting.Repository.Signing.CRUDActions = []string{"never"}
|
|
||||||
t.Run("CreateCRUDFile-Never", crudActionCreateFile(
|
|
||||||
t, testCtx, user, "master", "never", "unsigned-never.txt", func(t *testing.T, response api.FileResponse) {
|
|
||||||
assert.False(t, response.Verification.Verified)
|
|
||||||
}))
|
|
||||||
setting.Repository.Signing.CRUDActions = []string{"parentsigned"}
|
|
||||||
t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile(
|
|
||||||
t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) {
|
|
||||||
assert.True(t, response.Verification.Verified)
|
|
||||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
|
||||||
}))
|
|
||||||
setting.Repository.Signing.CRUDActions = []string{"always"}
|
|
||||||
t.Run("CreateCRUDFile-Always", crudActionCreateFile(
|
|
||||||
t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) {
|
|
||||||
assert.True(t, response.Verification.Verified)
|
|
||||||
assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email)
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
})
|
|
||||||
t.Run("UnsignedMerging", func(t *testing.T) {
|
|
||||||
PrintCurrentTest(t)
|
|
||||||
testCtx := NewAPITestContext(t, username, "initial-unsigned")
|
|
||||||
var pr api.PullRequest
|
|
||||||
var err error
|
|
||||||
t.Run("CreatePullRequest", func(t *testing.T) {
|
|
||||||
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "never2")(t)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
})
|
})
|
||||||
setting.Repository.Signing.Merges = []string{"commitssigned"}
|
}, false)
|
||||||
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
|
||||||
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
|
||||||
assert.NotNil(t, branch.Commit)
|
|
||||||
assert.NotNil(t, branch.Commit.Verification)
|
|
||||||
assert.False(t, branch.Commit.Verification.Verified)
|
|
||||||
assert.Empty(t, branch.Commit.Verification.Signature)
|
|
||||||
}))
|
|
||||||
setting.Repository.Signing.Merges = []string{"basesigned"}
|
|
||||||
t.Run("CreatePullRequest", func(t *testing.T) {
|
|
||||||
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "parentsigned2")(t)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
})
|
|
||||||
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
|
||||||
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
|
||||||
assert.NotNil(t, branch.Commit)
|
|
||||||
assert.NotNil(t, branch.Commit.Verification)
|
|
||||||
assert.False(t, branch.Commit.Verification.Verified)
|
|
||||||
assert.Empty(t, branch.Commit.Verification.Signature)
|
|
||||||
}))
|
|
||||||
setting.Repository.Signing.Merges = []string{"commitssigned"}
|
|
||||||
t.Run("CreatePullRequest", func(t *testing.T) {
|
|
||||||
pr, err = doAPICreatePullRequest(testCtx, testCtx.Username, testCtx.Reponame, "master", "always-parentsigned")(t)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
})
|
|
||||||
t.Run("MergePR", doAPIMergePullRequest(testCtx, testCtx.Username, testCtx.Reponame, pr.Index))
|
|
||||||
t.Run("CheckMasterBranchUnsigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) {
|
|
||||||
assert.NotNil(t, branch.Commit)
|
|
||||||
assert.NotNil(t, branch.Commit.Verification)
|
|
||||||
assert.True(t, branch.Commit.Verification.Verified)
|
|
||||||
}))
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func crudActionCreateFile(t *testing.T, ctx APITestContext, user *models.User, from, to, path string, callback ...func(*testing.T, api.FileResponse)) func(*testing.T) {
|
func crudActionCreateFile(t *testing.T, ctx APITestContext, user *models.User, from, to, path string, callback ...func(*testing.T, api.FileResponse)) func(*testing.T) {
|
||||||
|
@ -30,26 +30,28 @@ type ActionType int
|
|||||||
|
|
||||||
// Possible action types.
|
// Possible action types.
|
||||||
const (
|
const (
|
||||||
ActionCreateRepo ActionType = iota + 1 // 1
|
ActionCreateRepo ActionType = iota + 1 // 1
|
||||||
ActionRenameRepo // 2
|
ActionRenameRepo // 2
|
||||||
ActionStarRepo // 3
|
ActionStarRepo // 3
|
||||||
ActionWatchRepo // 4
|
ActionWatchRepo // 4
|
||||||
ActionCommitRepo // 5
|
ActionCommitRepo // 5
|
||||||
ActionCreateIssue // 6
|
ActionCreateIssue // 6
|
||||||
ActionCreatePullRequest // 7
|
ActionCreatePullRequest // 7
|
||||||
ActionTransferRepo // 8
|
ActionTransferRepo // 8
|
||||||
ActionPushTag // 9
|
ActionPushTag // 9
|
||||||
ActionCommentIssue // 10
|
ActionCommentIssue // 10
|
||||||
ActionMergePullRequest // 11
|
ActionMergePullRequest // 11
|
||||||
ActionCloseIssue // 12
|
ActionCloseIssue // 12
|
||||||
ActionReopenIssue // 13
|
ActionReopenIssue // 13
|
||||||
ActionClosePullRequest // 14
|
ActionClosePullRequest // 14
|
||||||
ActionReopenPullRequest // 15
|
ActionReopenPullRequest // 15
|
||||||
ActionDeleteTag // 16
|
ActionDeleteTag // 16
|
||||||
ActionDeleteBranch // 17
|
ActionDeleteBranch // 17
|
||||||
ActionMirrorSyncPush // 18
|
ActionMirrorSyncPush // 18
|
||||||
ActionMirrorSyncCreate // 19
|
ActionMirrorSyncCreate // 19
|
||||||
ActionMirrorSyncDelete // 20
|
ActionMirrorSyncDelete // 20
|
||||||
|
ActionApprovePullRequest // 21
|
||||||
|
ActionRejectPullRequest // 22
|
||||||
)
|
)
|
||||||
|
|
||||||
// Action represents user operation type and other information to
|
// Action represents user operation type and other information to
|
||||||
@ -520,52 +522,6 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit, bra
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func transferRepoAction(e Engine, doer, oldOwner *User, repo *Repository) (err error) {
|
|
||||||
if err = notifyWatchers(e, &Action{
|
|
||||||
ActUserID: doer.ID,
|
|
||||||
ActUser: doer,
|
|
||||||
OpType: ActionTransferRepo,
|
|
||||||
RepoID: repo.ID,
|
|
||||||
Repo: repo,
|
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
Content: path.Join(oldOwner.Name, repo.Name),
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("notifyWatchers: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove watch for organization.
|
|
||||||
if oldOwner.IsOrganization() {
|
|
||||||
if err = watchRepo(e, oldOwner.ID, repo.ID, false); err != nil {
|
|
||||||
return fmt.Errorf("watchRepo [false]: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TransferRepoAction adds new action for transferring repository,
|
|
||||||
// the Owner field of repository is assumed to be new owner.
|
|
||||||
func TransferRepoAction(doer, oldOwner *User, repo *Repository) error {
|
|
||||||
return transferRepoAction(x, doer, oldOwner, repo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func mergePullRequestAction(e Engine, doer *User, repo *Repository, issue *Issue) error {
|
|
||||||
return notifyWatchers(e, &Action{
|
|
||||||
ActUserID: doer.ID,
|
|
||||||
ActUser: doer,
|
|
||||||
OpType: ActionMergePullRequest,
|
|
||||||
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
|
|
||||||
RepoID: repo.ID,
|
|
||||||
Repo: repo,
|
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergePullRequestAction adds new action for merging pull request.
|
|
||||||
func MergePullRequestAction(actUser *User, repo *Repository, pull *Issue) error {
|
|
||||||
return mergePullRequestAction(x, actUser, repo, pull)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFeedsOptions options for retrieving feeds
|
// GetFeedsOptions options for retrieving feeds
|
||||||
type GetFeedsOptions struct {
|
type GetFeedsOptions struct {
|
||||||
RequestedUser *User
|
RequestedUser *User
|
||||||
|
@ -332,54 +332,6 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
|
|||||||
CheckConsistencyFor(t, &Action{})
|
CheckConsistencyFor(t, &Action{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTransferRepoAction(t *testing.T) {
|
|
||||||
assert.NoError(t, PrepareTestDatabase())
|
|
||||||
|
|
||||||
user2 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
|
||||||
user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User)
|
|
||||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1, OwnerID: user2.ID}).(*Repository)
|
|
||||||
|
|
||||||
repo.OwnerID = user4.ID
|
|
||||||
repo.Owner = user4
|
|
||||||
|
|
||||||
actionBean := &Action{
|
|
||||||
OpType: ActionTransferRepo,
|
|
||||||
ActUserID: user2.ID,
|
|
||||||
ActUser: user2,
|
|
||||||
RepoID: repo.ID,
|
|
||||||
Repo: repo,
|
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}
|
|
||||||
AssertNotExistsBean(t, actionBean)
|
|
||||||
assert.NoError(t, TransferRepoAction(user2, user2, repo))
|
|
||||||
AssertExistsAndLoadBean(t, actionBean)
|
|
||||||
|
|
||||||
_, err := x.ID(repo.ID).Cols("owner_id").Update(repo)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
CheckConsistencyFor(t, &Action{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMergePullRequestAction(t *testing.T) {
|
|
||||||
assert.NoError(t, PrepareTestDatabase())
|
|
||||||
user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
|
||||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1, OwnerID: user.ID}).(*Repository)
|
|
||||||
repo.Owner = user
|
|
||||||
issue := AssertExistsAndLoadBean(t, &Issue{ID: 3, RepoID: repo.ID}).(*Issue)
|
|
||||||
|
|
||||||
actionBean := &Action{
|
|
||||||
OpType: ActionMergePullRequest,
|
|
||||||
ActUserID: user.ID,
|
|
||||||
ActUser: user,
|
|
||||||
RepoID: repo.ID,
|
|
||||||
Repo: repo,
|
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}
|
|
||||||
AssertNotExistsBean(t, actionBean)
|
|
||||||
assert.NoError(t, MergePullRequestAction(user, repo, issue))
|
|
||||||
AssertExistsAndLoadBean(t, actionBean)
|
|
||||||
CheckConsistencyFor(t, &Action{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetFeeds(t *testing.T) {
|
func TestGetFeeds(t *testing.T) {
|
||||||
// test with an individual user
|
// test with an individual user
|
||||||
assert.NoError(t, PrepareTestDatabase())
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
@ -539,8 +539,10 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = sendCreateCommentAction(e, opts, comment); err != nil {
|
if !opts.NoAction {
|
||||||
return nil, err
|
if err = sendCreateCommentAction(e, opts, comment); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = comment.addCrossReferences(e, opts.Doer); err != nil {
|
if err = comment.addCrossReferences(e, opts.Doer); err != nil {
|
||||||
@ -816,6 +818,7 @@ type CreateCommentOptions struct {
|
|||||||
RefCommentID int64
|
RefCommentID int64
|
||||||
RefAction references.XRefAction
|
RefAction references.XRefAction
|
||||||
RefIsPull bool
|
RefIsPull bool
|
||||||
|
NoAction bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateComment creates comment of issue or commit.
|
// CreateComment creates comment of issue or commit.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -403,6 +404,19 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR
|
|||||||
|
|
||||||
var isAttributeSSHPublicKeySet = len(strings.TrimSpace(source.LDAP().AttributeSSHPublicKey)) > 0
|
var isAttributeSSHPublicKeySet = len(strings.TrimSpace(source.LDAP().AttributeSSHPublicKey)) > 0
|
||||||
|
|
||||||
|
// Update User admin flag if exist
|
||||||
|
if isExist, err := IsUserExist(0, sr.Username); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if isExist &&
|
||||||
|
!user.ProhibitLogin && len(source.LDAP().AdminFilter) > 0 && user.IsAdmin != sr.IsAdmin {
|
||||||
|
// Change existing admin flag only if AdminFilter option is set
|
||||||
|
user.IsAdmin = sr.IsAdmin
|
||||||
|
err = UpdateUserCols(user, "is_admin")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !autoRegister {
|
if !autoRegister {
|
||||||
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(user, source, sr.SSHPublicKey) {
|
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(user, source, sr.SSHPublicKey) {
|
||||||
return user, RewriteAllPublicKeys()
|
return user, RewriteAllPublicKeys()
|
||||||
|
@ -1792,8 +1792,13 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
|
|||||||
|
|
||||||
if err = watchRepo(sess, doer.ID, repo.ID, true); err != nil {
|
if err = watchRepo(sess, doer.ID, repo.ID, true); err != nil {
|
||||||
return fmt.Errorf("watchRepo: %v", err)
|
return fmt.Errorf("watchRepo: %v", err)
|
||||||
} else if err = transferRepoAction(sess, doer, owner, repo); err != nil {
|
}
|
||||||
return fmt.Errorf("transferRepoAction: %v", err)
|
|
||||||
|
// Remove watch for organization.
|
||||||
|
if owner.IsOrganization() {
|
||||||
|
if err = watchRepo(sess, owner.ID, repo.ID, false); err != nil {
|
||||||
|
return fmt.Errorf("watchRepo [false]: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename remote repository to new path and delete local copy.
|
// Rename remote repository to new path and delete local copy.
|
||||||
@ -1824,23 +1829,21 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
|
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
|
||||||
func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error) {
|
func ChangeRepositoryName(doer *User, repo *Repository, newRepoName string) (err error) {
|
||||||
oldRepoName = strings.ToLower(oldRepoName)
|
|
||||||
newRepoName = strings.ToLower(newRepoName)
|
newRepoName = strings.ToLower(newRepoName)
|
||||||
if err = IsUsableRepoName(newRepoName); err != nil {
|
if err = IsUsableRepoName(newRepoName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err := IsRepositoryExist(u, newRepoName)
|
if err := repo.GetOwner(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
has, err := IsRepositoryExist(repo.Owner, newRepoName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("IsRepositoryExist: %v", err)
|
return fmt.Errorf("IsRepositoryExist: %v", err)
|
||||||
} else if has {
|
} else if has {
|
||||||
return ErrRepoAlreadyExist{u.Name, newRepoName}
|
return ErrRepoAlreadyExist{repo.Owner.Name, newRepoName}
|
||||||
}
|
|
||||||
|
|
||||||
repo, err := GetRepositoryByName(u.ID, oldRepoName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("GetRepositoryByName: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change repository directory name. We must lock the local copy of the
|
// Change repository directory name. We must lock the local copy of the
|
||||||
@ -1849,14 +1852,14 @@ func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error)
|
|||||||
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
|
repoWorkingPool.CheckIn(com.ToStr(repo.ID))
|
||||||
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
|
defer repoWorkingPool.CheckOut(com.ToStr(repo.ID))
|
||||||
|
|
||||||
newRepoPath := RepoPath(u.Name, newRepoName)
|
newRepoPath := RepoPath(repo.Owner.Name, newRepoName)
|
||||||
if err = os.Rename(repo.RepoPath(), newRepoPath); err != nil {
|
if err = os.Rename(repo.RepoPath(), newRepoPath); err != nil {
|
||||||
return fmt.Errorf("rename repository directory: %v", err)
|
return fmt.Errorf("rename repository directory: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wikiPath := repo.WikiPath()
|
wikiPath := repo.WikiPath()
|
||||||
if com.IsExist(wikiPath) {
|
if com.IsExist(wikiPath) {
|
||||||
if err = os.Rename(wikiPath, WikiPath(u.Name, newRepoName)); err != nil {
|
if err = os.Rename(wikiPath, WikiPath(repo.Owner.Name, newRepoName)); err != nil {
|
||||||
return fmt.Errorf("rename repository wiki: %v", err)
|
return fmt.Errorf("rename repository wiki: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1868,7 +1871,7 @@ func ChangeRepositoryName(u *User, oldRepoName, newRepoName string) (err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If there was previously a redirect at this location, remove it.
|
// If there was previously a redirect at this location, remove it.
|
||||||
if err = deleteRepoRedirect(sess, u.ID, newRepoName); err != nil {
|
if err = deleteRepoRedirect(sess, repo.OwnerID, newRepoName); err != nil {
|
||||||
return fmt.Errorf("delete repo redirect: %v", err)
|
return fmt.Errorf("delete repo redirect: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/unknwon/com"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRepo(t *testing.T) {
|
func TestRepo(t *testing.T) {
|
||||||
@ -142,29 +141,6 @@ func TestRepoAPIURL(t *testing.T) {
|
|||||||
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL())
|
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTransferOwnership(t *testing.T) {
|
|
||||||
assert.NoError(t, PrepareTestDatabase())
|
|
||||||
|
|
||||||
doer := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
|
||||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
|
|
||||||
repo.Owner = AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User)
|
|
||||||
assert.NoError(t, TransferOwnership(doer, "user2", repo))
|
|
||||||
|
|
||||||
transferredRepo := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
|
|
||||||
assert.EqualValues(t, 2, transferredRepo.OwnerID)
|
|
||||||
|
|
||||||
assert.False(t, com.IsExist(RepoPath("user3", "repo3")))
|
|
||||||
assert.True(t, com.IsExist(RepoPath("user2", "repo3")))
|
|
||||||
AssertExistsAndLoadBean(t, &Action{
|
|
||||||
OpType: ActionTransferRepo,
|
|
||||||
ActUserID: 2,
|
|
||||||
RepoID: 3,
|
|
||||||
Content: "user3/repo3",
|
|
||||||
})
|
|
||||||
|
|
||||||
CheckConsistencyFor(t, &Repository{}, &User{}, &Team{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUploadAvatar(t *testing.T) {
|
func TestUploadAvatar(t *testing.T) {
|
||||||
|
|
||||||
// Generate image
|
// Generate image
|
||||||
|
@ -216,6 +216,21 @@ func NotifyWatchers(act *Action) error {
|
|||||||
return notifyWatchers(x, act)
|
return notifyWatchers(x, act)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotifyWatchersActions creates batch of actions for every watcher.
|
||||||
|
func NotifyWatchersActions(acts []*Action) error {
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, act := range acts {
|
||||||
|
if err := notifyWatchers(sess, act); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sess.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
func watchIfAuto(e Engine, userID, repoID int64, isWrite bool) error {
|
func watchIfAuto(e Engine, userID, repoID int64, isWrite bool) error {
|
||||||
if !isWrite || !setting.Service.AutoWatchOnChanges {
|
if !isWrite || !setting.Service.AutoWatchOnChanges {
|
||||||
return nil
|
return nil
|
||||||
|
134
models/review.go
134
models/review.go
@ -5,14 +5,12 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
"xorm.io/xorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReviewType defines the sort of feedback a review gives
|
// ReviewType defines the sort of feedback a review gives
|
||||||
@ -86,6 +84,11 @@ func (r *Review) loadReviewer(e Engine) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadReviewer loads reviewer
|
||||||
|
func (r *Review) LoadReviewer() error {
|
||||||
|
return r.loadReviewer(x)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Review) loadAttributes(e Engine) (err error) {
|
func (r *Review) loadAttributes(e Engine) (err error) {
|
||||||
if err = r.loadReviewer(e); err != nil {
|
if err = r.loadReviewer(e); err != nil {
|
||||||
return
|
return
|
||||||
@ -101,54 +104,6 @@ func (r *Review) LoadAttributes() error {
|
|||||||
return r.loadAttributes(x)
|
return r.loadAttributes(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish will send notifications / actions to participants for all code comments; parts are concurrent
|
|
||||||
func (r *Review) Publish() error {
|
|
||||||
return r.publish(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Review) publish(e *xorm.Engine) error {
|
|
||||||
if r.Type == ReviewTypePending || r.Type == ReviewTypeUnknown {
|
|
||||||
return fmt.Errorf("review cannot be published if type is pending or unknown")
|
|
||||||
}
|
|
||||||
if r.Issue == nil {
|
|
||||||
if err := r.loadIssue(e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := r.Issue.loadRepo(e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(r.CodeComments) == 0 {
|
|
||||||
if err := r.loadCodeComments(e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, lines := range r.CodeComments {
|
|
||||||
for _, comments := range lines {
|
|
||||||
for _, comment := range comments {
|
|
||||||
go func(en *xorm.Engine, review *Review, comm *Comment) {
|
|
||||||
sess := en.NewSession()
|
|
||||||
defer sess.Close()
|
|
||||||
opts := &CreateCommentOptions{
|
|
||||||
Doer: comm.Poster,
|
|
||||||
Issue: review.Issue,
|
|
||||||
Repo: review.Issue.Repo,
|
|
||||||
Type: comm.Type,
|
|
||||||
Content: comm.Content,
|
|
||||||
}
|
|
||||||
if err := updateCommentInfos(sess, opts, comm); err != nil {
|
|
||||||
log.Warn("updateCommentInfos: %v", err)
|
|
||||||
}
|
|
||||||
if err := sendCreateCommentAction(sess, opts, comm); err != nil {
|
|
||||||
log.Warn("sendCreateCommentAction: %v", err)
|
|
||||||
}
|
|
||||||
}(e, r, comment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getReviewByID(e Engine, id int64) (*Review, error) {
|
func getReviewByID(e Engine, id int64) (*Review, error) {
|
||||||
review := new(Review)
|
review := new(Review)
|
||||||
if has, err := e.ID(id).Get(review); err != nil {
|
if has, err := e.ID(id).Get(review); err != nil {
|
||||||
@ -271,12 +226,79 @@ func GetCurrentReview(reviewer *User, issue *Issue) (*Review, error) {
|
|||||||
return getCurrentReview(x, reviewer, issue)
|
return getCurrentReview(x, reviewer, issue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateReview will update all cols of the given review in db
|
// ContentEmptyErr represents an content empty error
|
||||||
func UpdateReview(r *Review) error {
|
type ContentEmptyErr struct {
|
||||||
if _, err := x.ID(r.ID).AllCols().Update(r); err != nil {
|
}
|
||||||
return err
|
|
||||||
|
func (ContentEmptyErr) Error() string {
|
||||||
|
return "Review content is empty"
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsContentEmptyErr returns true if err is a ContentEmptyErr
|
||||||
|
func IsContentEmptyErr(err error) bool {
|
||||||
|
_, ok := err.(ContentEmptyErr)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist
|
||||||
|
func SubmitReview(doer *User, issue *Issue, reviewType ReviewType, content string) (*Review, *Comment, error) {
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
review, err := getCurrentReview(sess, doer, issue)
|
||||||
|
if err != nil {
|
||||||
|
if !IsErrReviewNotExist(err) {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if reviewType != ReviewTypeApprove && len(strings.TrimSpace(content)) == 0 {
|
||||||
|
return nil, nil, ContentEmptyErr{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No current review. Create a new one!
|
||||||
|
review, err = createReview(sess, CreateReviewOptions{
|
||||||
|
Type: reviewType,
|
||||||
|
Issue: issue,
|
||||||
|
Reviewer: doer,
|
||||||
|
Content: content,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := review.loadCodeComments(sess); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if reviewType != ReviewTypeApprove && len(review.CodeComments) == 0 && len(strings.TrimSpace(content)) == 0 {
|
||||||
|
return nil, nil, ContentEmptyErr{}
|
||||||
|
}
|
||||||
|
|
||||||
|
review.Issue = issue
|
||||||
|
review.Content = content
|
||||||
|
review.Type = reviewType
|
||||||
|
if _, err := sess.ID(review.ID).Cols("content, type").Update(review); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comm, err := createComment(sess, &CreateCommentOptions{
|
||||||
|
Type: CommentTypeReview,
|
||||||
|
Doer: doer,
|
||||||
|
Content: review.Content,
|
||||||
|
Issue: issue,
|
||||||
|
Repo: issue.Repo,
|
||||||
|
ReviewID: review.ID,
|
||||||
|
NoAction: true,
|
||||||
|
})
|
||||||
|
if err != nil || comm == nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
comm.Review = review
|
||||||
|
return review, comm, sess.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PullReviewersWithType represents the type used to display a review overview
|
// PullReviewersWithType represents the type used to display a review overview
|
||||||
|
@ -98,14 +98,6 @@ func TestCreateReview(t *testing.T) {
|
|||||||
AssertExistsAndLoadBean(t, &Review{Content: "New Review"})
|
AssertExistsAndLoadBean(t, &Review{Content: "New Review"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateReview(t *testing.T) {
|
|
||||||
assert.NoError(t, PrepareTestDatabase())
|
|
||||||
review := AssertExistsAndLoadBean(t, &Review{ID: 1}).(*Review)
|
|
||||||
review.Content = "Updated Review"
|
|
||||||
assert.NoError(t, UpdateReview(review))
|
|
||||||
AssertExistsAndLoadBean(t, &Review{ID: 1, Content: "Updated Review"})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetReviewersByPullID(t *testing.T) {
|
func TestGetReviewersByPullID(t *testing.T) {
|
||||||
assert.NoError(t, PrepareTestDatabase())
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -50,6 +51,28 @@ func (b *Blob) GetBlobContent() (string, error) {
|
|||||||
return string(buf), nil
|
return string(buf), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlobLineCount gets line count of lob as raw text
|
||||||
|
func (b *Blob) GetBlobLineCount() (int, error) {
|
||||||
|
reader, err := b.DataAsync()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
buf := make([]byte, 32*1024)
|
||||||
|
count := 0
|
||||||
|
lineSep := []byte{'\n'}
|
||||||
|
for {
|
||||||
|
c, err := reader.Read(buf)
|
||||||
|
count += bytes.Count(buf[:c], lineSep)
|
||||||
|
switch {
|
||||||
|
case err == io.EOF:
|
||||||
|
return count, nil
|
||||||
|
case err != nil:
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlobContentBase64 Reads the content of the blob with a base64 encode and returns the encoded string
|
// GetBlobContentBase64 Reads the content of the blob with a base64 encode and returns the encoded string
|
||||||
func (b *Blob) GetBlobContentBase64() (string, error) {
|
func (b *Blob) GetBlobContentBase64() (string, error) {
|
||||||
dataRc, err := b.DataAsync()
|
dataRc, err := b.DataAsync()
|
||||||
|
@ -6,6 +6,8 @@ package action
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
@ -76,7 +78,9 @@ func (a *actionNotifier) NotifyNewPullRequest(pull *models.PullRequest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *actionNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) {
|
func (a *actionNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldRepoName string) {
|
||||||
|
log.Trace("action.ChangeRepositoryName: %s/%s", doer.Name, repo.Name)
|
||||||
|
|
||||||
if err := models.NotifyWatchers(&models.Action{
|
if err := models.NotifyWatchers(&models.Action{
|
||||||
ActUserID: doer.ID,
|
ActUserID: doer.ID,
|
||||||
ActUser: doer,
|
ActUser: doer,
|
||||||
@ -84,11 +88,23 @@ func (a *actionNotifier) NotifyRenameRepository(doer *models.User, repo *models.
|
|||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
IsPrivate: repo.IsPrivate,
|
IsPrivate: repo.IsPrivate,
|
||||||
Content: oldName,
|
Content: oldRepoName,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error("notify watchers: %v", err)
|
log.Error("NotifyWatchers: %v", err)
|
||||||
} else {
|
}
|
||||||
log.Trace("action.renameRepoAction: %s/%s", doer.Name, repo.Name)
|
}
|
||||||
|
|
||||||
|
func (a *actionNotifier) NotifyTransferRepository(doer *models.User, repo *models.Repository, oldOwnerName string) {
|
||||||
|
if err := models.NotifyWatchers(&models.Action{
|
||||||
|
ActUserID: doer.ID,
|
||||||
|
ActUser: doer,
|
||||||
|
OpType: models.ActionTransferRepo,
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Repo: repo,
|
||||||
|
IsPrivate: repo.IsPrivate,
|
||||||
|
Content: path.Join(oldOwnerName, repo.Name),
|
||||||
|
}); err != nil {
|
||||||
|
log.Error("NotifyWatchers: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,3 +133,61 @@ func (a *actionNotifier) NotifyForkRepository(doer *models.User, oldRepo, repo *
|
|||||||
log.Error("notify watchers '%d/%d': %v", doer.ID, repo.ID, err)
|
log.Error("notify watchers '%d/%d': %v", doer.ID, repo.ID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment) {
|
||||||
|
if err := review.LoadReviewer(); err != nil {
|
||||||
|
log.Error("LoadReviewer '%d/%d': %v", review.ID, review.ReviewerID, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := review.LoadCodeComments(); err != nil {
|
||||||
|
log.Error("LoadCodeComments '%d/%d': %v", review.Reviewer.ID, review.ID, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var actions = make([]*models.Action, 0, 10)
|
||||||
|
for _, lines := range review.CodeComments {
|
||||||
|
for _, comments := range lines {
|
||||||
|
for _, comm := range comments {
|
||||||
|
actions = append(actions, &models.Action{
|
||||||
|
ActUserID: review.Reviewer.ID,
|
||||||
|
ActUser: review.Reviewer,
|
||||||
|
Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comm.Content, "\n")[0]),
|
||||||
|
OpType: models.ActionCommentIssue,
|
||||||
|
RepoID: review.Issue.RepoID,
|
||||||
|
Repo: review.Issue.Repo,
|
||||||
|
IsPrivate: review.Issue.Repo.IsPrivate,
|
||||||
|
Comment: comm,
|
||||||
|
CommentID: comm.ID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if review.Type != models.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" {
|
||||||
|
action := &models.Action{
|
||||||
|
ActUserID: review.Reviewer.ID,
|
||||||
|
ActUser: review.Reviewer,
|
||||||
|
Content: fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comment.Content, "\n")[0]),
|
||||||
|
RepoID: review.Issue.RepoID,
|
||||||
|
Repo: review.Issue.Repo,
|
||||||
|
IsPrivate: review.Issue.Repo.IsPrivate,
|
||||||
|
Comment: comment,
|
||||||
|
CommentID: comment.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
switch review.Type {
|
||||||
|
case models.ReviewTypeApprove:
|
||||||
|
action.OpType = models.ActionApprovePullRequest
|
||||||
|
case models.ReviewTypeReject:
|
||||||
|
action.OpType = models.ActionRejectPullRequest
|
||||||
|
default:
|
||||||
|
action.OpType = models.ActionCommentIssue
|
||||||
|
}
|
||||||
|
|
||||||
|
actions = append(actions, action)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.NotifyWatchersActions(actions); err != nil {
|
||||||
|
log.Error("notify watchers '%d/%d': %v", review.Reviewer.ID, review.Issue.RepoID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -17,7 +17,8 @@ type Notifier interface {
|
|||||||
NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Repository)
|
NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Repository)
|
||||||
NotifyDeleteRepository(doer *models.User, repo *models.Repository)
|
NotifyDeleteRepository(doer *models.User, repo *models.Repository)
|
||||||
NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository)
|
NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository)
|
||||||
NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string)
|
NotifyRenameRepository(doer *models.User, repo *models.Repository, oldRepoName string)
|
||||||
|
NotifyTransferRepository(doer *models.User, repo *models.Repository, oldOwnerName string)
|
||||||
|
|
||||||
NotifyNewIssue(*models.Issue)
|
NotifyNewIssue(*models.Issue)
|
||||||
NotifyIssueChangeStatus(*models.User, *models.Issue, bool)
|
NotifyIssueChangeStatus(*models.User, *models.Issue, bool)
|
||||||
|
@ -58,18 +58,6 @@ func (*NullNotifier) NotifyUpdateComment(doer *models.User, c *models.Comment, o
|
|||||||
func (*NullNotifier) NotifyDeleteComment(doer *models.User, c *models.Comment) {
|
func (*NullNotifier) NotifyDeleteComment(doer *models.User, c *models.Comment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyDeleteRepository places a place holder function
|
|
||||||
func (*NullNotifier) NotifyDeleteRepository(doer *models.User, repo *models.Repository) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyForkRepository places a place holder function
|
|
||||||
func (*NullNotifier) NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyRenameRepository places a place holder function
|
|
||||||
func (*NullNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyNewRelease places a place holder function
|
// NotifyNewRelease places a place holder function
|
||||||
func (*NullNotifier) NotifyNewRelease(rel *models.Release) {
|
func (*NullNotifier) NotifyNewRelease(rel *models.Release) {
|
||||||
}
|
}
|
||||||
@ -111,6 +99,14 @@ func (*NullNotifier) NotifyIssueChangeLabels(doer *models.User, issue *models.Is
|
|||||||
func (*NullNotifier) NotifyCreateRepository(doer *models.User, u *models.User, repo *models.Repository) {
|
func (*NullNotifier) NotifyCreateRepository(doer *models.User, u *models.User, repo *models.Repository) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotifyDeleteRepository places a place holder function
|
||||||
|
func (*NullNotifier) NotifyDeleteRepository(doer *models.User, repo *models.Repository) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyForkRepository places a place holder function
|
||||||
|
func (*NullNotifier) NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) {
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyMigrateRepository places a place holder function
|
// NotifyMigrateRepository places a place holder function
|
||||||
func (*NullNotifier) NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Repository) {
|
func (*NullNotifier) NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Repository) {
|
||||||
}
|
}
|
||||||
@ -126,3 +122,11 @@ func (*NullNotifier) NotifyCreateRef(doer *models.User, repo *models.Repository,
|
|||||||
// NotifyDeleteRef notifies branch or tag deleteion to notifiers
|
// NotifyDeleteRef notifies branch or tag deleteion to notifiers
|
||||||
func (*NullNotifier) NotifyDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) {
|
func (*NullNotifier) NotifyDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotifyRenameRepository places a place holder function
|
||||||
|
func (*NullNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repository, oldRepoName string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyTransferRepository places a place holder function
|
||||||
|
func (*NullNotifier) NotifyTransferRepository(doer *models.User, repo *models.Repository, oldOwnerName string) {
|
||||||
|
}
|
||||||
|
@ -101,27 +101,6 @@ func NotifyDeleteComment(doer *models.User, c *models.Comment) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyDeleteRepository notifies delete repository to notifiers
|
|
||||||
func NotifyDeleteRepository(doer *models.User, repo *models.Repository) {
|
|
||||||
for _, notifier := range notifiers {
|
|
||||||
notifier.NotifyDeleteRepository(doer, repo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyForkRepository notifies fork repository to notifiers
|
|
||||||
func NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) {
|
|
||||||
for _, notifier := range notifiers {
|
|
||||||
notifier.NotifyForkRepository(doer, oldRepo, repo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyRenameRepository notifies repository renamed
|
|
||||||
func NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) {
|
|
||||||
for _, notifier := range notifiers {
|
|
||||||
notifier.NotifyRenameRepository(doer, repo, oldName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotifyNewRelease notifies new release to notifiers
|
// NotifyNewRelease notifies new release to notifiers
|
||||||
func NotifyNewRelease(rel *models.Release) {
|
func NotifyNewRelease(rel *models.Release) {
|
||||||
for _, notifier := range notifiers {
|
for _, notifier := range notifiers {
|
||||||
@ -200,6 +179,34 @@ func NotifyMigrateRepository(doer *models.User, u *models.User, repo *models.Rep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotifyTransferRepository notifies create repository to notifiers
|
||||||
|
func NotifyTransferRepository(doer *models.User, repo *models.Repository, newOwnerName string) {
|
||||||
|
for _, notifier := range notifiers {
|
||||||
|
notifier.NotifyTransferRepository(doer, repo, newOwnerName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyDeleteRepository notifies delete repository to notifiers
|
||||||
|
func NotifyDeleteRepository(doer *models.User, repo *models.Repository) {
|
||||||
|
for _, notifier := range notifiers {
|
||||||
|
notifier.NotifyDeleteRepository(doer, repo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyForkRepository notifies fork repository to notifiers
|
||||||
|
func NotifyForkRepository(doer *models.User, oldRepo, repo *models.Repository) {
|
||||||
|
for _, notifier := range notifiers {
|
||||||
|
notifier.NotifyForkRepository(doer, oldRepo, repo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyRenameRepository notifies repository renamed
|
||||||
|
func NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName string) {
|
||||||
|
for _, notifier := range notifiers {
|
||||||
|
notifier.NotifyRenameRepository(doer, repo, oldName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyPushCommits notifies commits pushed to notifiers
|
// NotifyPushCommits notifies commits pushed to notifiers
|
||||||
func NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) {
|
func NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) {
|
||||||
for _, notifier := range notifiers {
|
for _, notifier := range notifiers {
|
||||||
|
@ -55,6 +55,15 @@ func TestGetDiffPreview(t *testing.T) {
|
|||||||
Type: 4,
|
Type: 4,
|
||||||
Content: "@@ -1,3 +1,4 @@",
|
Content: "@@ -1,3 +1,4 @@",
|
||||||
Comments: nil,
|
Comments: nil,
|
||||||
|
SectionInfo: &gitdiff.DiffLineSectionInfo{
|
||||||
|
Path: "README.md",
|
||||||
|
LastLeftIdx: 0,
|
||||||
|
LastRightIdx: 0,
|
||||||
|
LeftIdx: 1,
|
||||||
|
RightIdx: 1,
|
||||||
|
LeftHunkSize: 3,
|
||||||
|
RightHunkSize: 4,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
LeftIdx: 1,
|
LeftIdx: 1,
|
||||||
|
@ -140,18 +140,19 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Security settings
|
// Security settings
|
||||||
InstallLock bool
|
InstallLock bool
|
||||||
SecretKey string
|
SecretKey string
|
||||||
LogInRememberDays int
|
LogInRememberDays int
|
||||||
CookieUserName string
|
CookieUserName string
|
||||||
CookieRememberName string
|
CookieRememberName string
|
||||||
ReverseProxyAuthUser string
|
ReverseProxyAuthUser string
|
||||||
ReverseProxyAuthEmail string
|
ReverseProxyAuthEmail string
|
||||||
MinPasswordLength int
|
MinPasswordLength int
|
||||||
ImportLocalPaths bool
|
ImportLocalPaths bool
|
||||||
DisableGitHooks bool
|
DisableGitHooks bool
|
||||||
PasswordComplexity []string
|
OnlyAllowPushIfGiteaEnvironmentSet bool
|
||||||
PasswordHashAlgo string
|
PasswordComplexity []string
|
||||||
|
PasswordHashAlgo string
|
||||||
|
|
||||||
// UI settings
|
// UI settings
|
||||||
UI = struct {
|
UI = struct {
|
||||||
@ -778,6 +779,7 @@ func NewContext() {
|
|||||||
MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6)
|
MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6)
|
||||||
ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false)
|
ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false)
|
||||||
DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(false)
|
DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(false)
|
||||||
|
OnlyAllowPushIfGiteaEnvironmentSet = sec.Key("ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET").MustBool(true)
|
||||||
PasswordHashAlgo = sec.Key("PASSWORD_HASH_ALGO").MustString("pbkdf2")
|
PasswordHashAlgo = sec.Key("PASSWORD_HASH_ALGO").MustString("pbkdf2")
|
||||||
CSRFCookieHTTPOnly = sec.Key("CSRF_COOKIE_HTTP_ONLY").MustBool(true)
|
CSRFCookieHTTPOnly = sec.Key("CSRF_COOKIE_HTTP_ONLY").MustBool(true)
|
||||||
|
|
||||||
|
@ -555,6 +555,10 @@ func ActionIcon(opType models.ActionType) string {
|
|||||||
return "issue-reopened"
|
return "issue-reopened"
|
||||||
case models.ActionMirrorSyncPush, models.ActionMirrorSyncCreate, models.ActionMirrorSyncDelete:
|
case models.ActionMirrorSyncPush, models.ActionMirrorSyncCreate, models.ActionMirrorSyncDelete:
|
||||||
return "repo-clone"
|
return "repo-clone"
|
||||||
|
case models.ActionApprovePullRequest:
|
||||||
|
return "eye"
|
||||||
|
case models.ActionRejectPullRequest:
|
||||||
|
return "x"
|
||||||
default:
|
default:
|
||||||
return "invalid type"
|
return "invalid type"
|
||||||
}
|
}
|
||||||
|
@ -582,7 +582,7 @@ email_notifications.submit = Set Email Preference
|
|||||||
owner = Owner
|
owner = Owner
|
||||||
repo_name = Repository Name
|
repo_name = Repository Name
|
||||||
repo_name_helper = Good repository names use short, memorable and unique keywords.
|
repo_name_helper = Good repository names use short, memorable and unique keywords.
|
||||||
repo_size = Repository Size
|
repo_size = Repository Size
|
||||||
template = Template
|
template = Template
|
||||||
template_select = Select a template.
|
template_select = Select a template.
|
||||||
template_helper = Make repository a template
|
template_helper = Make repository a template
|
||||||
@ -2000,6 +2000,8 @@ compare_commits_general = Compare commits
|
|||||||
mirror_sync_push = synced commits to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a> from mirror
|
mirror_sync_push = synced commits to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a> from mirror
|
||||||
mirror_sync_create = synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
|
mirror_sync_create = synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
|
||||||
mirror_sync_delete = synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
|
mirror_sync_delete = synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
|
||||||
|
approve_pull_request = `approved <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||||
|
reject_pull_request = `suggested changes for <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||||
|
|
||||||
[tool]
|
[tool]
|
||||||
ago = %s ago
|
ago = %s ago
|
||||||
|
@ -581,6 +581,7 @@ email_notifications.submit=Atualizar preferências de e-mail
|
|||||||
owner=Proprietário
|
owner=Proprietário
|
||||||
repo_name=Nome do repositório
|
repo_name=Nome do repositório
|
||||||
repo_name_helper=Um bom nome de repositório é composto por palavras curtas, memorizáveis e únicas.
|
repo_name_helper=Um bom nome de repositório é composto por palavras curtas, memorizáveis e únicas.
|
||||||
|
repo_size=Tamanho do repositório
|
||||||
template=Modelo
|
template=Modelo
|
||||||
template_select=Selecione um modelo.
|
template_select=Selecione um modelo.
|
||||||
template_helper=Tornar repositório um modelo
|
template_helper=Tornar repositório um modelo
|
||||||
@ -1711,6 +1712,7 @@ users.auth_login_name=Nome de acesso da autenticação
|
|||||||
users.password_helper=Deixe a senha em branco para mantê-la inalterada.
|
users.password_helper=Deixe a senha em branco para mantê-la inalterada.
|
||||||
users.update_profile_success=A conta de usuário foi atualizada.
|
users.update_profile_success=A conta de usuário foi atualizada.
|
||||||
users.edit_account=Editar a conta de usuário
|
users.edit_account=Editar a conta de usuário
|
||||||
|
users.max_repo_creation=Número máximo de repositórios
|
||||||
users.max_repo_creation_desc=(Use -1 para usar o limite padrão global.)
|
users.max_repo_creation_desc=(Use -1 para usar o limite padrão global.)
|
||||||
users.is_activated=Conta de usuário está ativada
|
users.is_activated=Conta de usuário está ativada
|
||||||
users.prohibit_login=Desabilitar acesso
|
users.prohibit_login=Desabilitar acesso
|
||||||
|
@ -68,6 +68,10 @@ pull_requests=合并请求
|
|||||||
issues=工单管理
|
issues=工单管理
|
||||||
|
|
||||||
cancel=取消
|
cancel=取消
|
||||||
|
add=添加
|
||||||
|
add_all=添加所有
|
||||||
|
remove=移除
|
||||||
|
remove_all=移除所有
|
||||||
|
|
||||||
write=撰写
|
write=撰写
|
||||||
preview=预览
|
preview=预览
|
||||||
@ -577,6 +581,11 @@ email_notifications.submit=邮件通知设置
|
|||||||
owner=拥有者
|
owner=拥有者
|
||||||
repo_name=仓库名称
|
repo_name=仓库名称
|
||||||
repo_name_helper=好的存储库名称使用简短、深刻和独特的关键字。
|
repo_name_helper=好的存储库名称使用简短、深刻和独特的关键字。
|
||||||
|
repo_size=仓库大小
|
||||||
|
template=模板
|
||||||
|
template_select=选择模板
|
||||||
|
template_helper=设置仓库为模板仓库
|
||||||
|
template_description=模板仓库让用户通过拷贝目录结构,文件和可选设置来生成仓库。
|
||||||
visibility=可见性
|
visibility=可见性
|
||||||
visibility_description=只有组织所有人或拥有权利的组织成员才能看到。
|
visibility_description=只有组织所有人或拥有权利的组织成员才能看到。
|
||||||
visibility_helper=将仓库设为私有
|
visibility_helper=将仓库设为私有
|
||||||
@ -586,6 +595,9 @@ clone_helper=不知道如何克隆?查看<a target="_blank" rel="noopener nore
|
|||||||
fork_repo=派生仓库
|
fork_repo=派生仓库
|
||||||
fork_from=派生自
|
fork_from=派生自
|
||||||
fork_visibility_helper=无法更改派生仓库的可见性。
|
fork_visibility_helper=无法更改派生仓库的可见性。
|
||||||
|
use_template=使用此模板
|
||||||
|
generate_repo=生成仓库
|
||||||
|
generate_from=生成自
|
||||||
repo_desc=仓库描述
|
repo_desc=仓库描述
|
||||||
repo_lang=仓库语言
|
repo_lang=仓库语言
|
||||||
repo_gitignore_helper=选择 .gitignore 模板。
|
repo_gitignore_helper=选择 .gitignore 模板。
|
||||||
@ -613,6 +625,11 @@ forks=派生仓库
|
|||||||
pick_reaction=选择你的表情
|
pick_reaction=选择你的表情
|
||||||
reactions_more=再加载 %d
|
reactions_more=再加载 %d
|
||||||
|
|
||||||
|
template.items=模板选项
|
||||||
|
template.git_content=Git数据(默认分支)
|
||||||
|
template.topics=主题
|
||||||
|
template.one_item=必须至少选择一个模板项
|
||||||
|
template.invalid=必须选择一个模板仓库
|
||||||
|
|
||||||
archive.title=此仓库已存档。您可以查看文件和克隆,但不能推送或创建工单/合并请求。
|
archive.title=此仓库已存档。您可以查看文件和克隆,但不能推送或创建工单/合并请求。
|
||||||
archive.issue.nocomment=此仓库已存档,您不能在此工单添加评论。
|
archive.issue.nocomment=此仓库已存档,您不能在此工单添加评论。
|
||||||
@ -648,6 +665,7 @@ migrate.migrating_failed=从 <b>%s</b> 迁移失败。
|
|||||||
|
|
||||||
mirror_from=镜像自地址
|
mirror_from=镜像自地址
|
||||||
forked_from=派生自
|
forked_from=派生自
|
||||||
|
generated_from=生成自
|
||||||
fork_from_self=无法派生已经拥有的仓库!
|
fork_from_self=无法派生已经拥有的仓库!
|
||||||
fork_guest_user=登录并 派生 这个仓库。
|
fork_guest_user=登录并 派生 这个仓库。
|
||||||
copy_link=复制链接
|
copy_link=复制链接
|
||||||
@ -742,6 +760,7 @@ editor.no_changes_to_show=没有可以显示的变更。
|
|||||||
editor.fail_to_update_file=更新/创建文件 '%s' 时发生错误:%v
|
editor.fail_to_update_file=更新/创建文件 '%s' 时发生错误:%v
|
||||||
editor.add_subdir=添加目录
|
editor.add_subdir=添加目录
|
||||||
editor.unable_to_upload_files=上传文件至 '%s' 时发生错误:%v
|
editor.unable_to_upload_files=上传文件至 '%s' 时发生错误:%v
|
||||||
|
editor.upload_file_is_locked=文件%s被 %s 锁定。
|
||||||
editor.upload_files_to_dir=上传文件至 '%s'
|
editor.upload_files_to_dir=上传文件至 '%s'
|
||||||
editor.cannot_commit_to_protected_branch=不可以提交到受保护的分支 '%s'。
|
editor.cannot_commit_to_protected_branch=不可以提交到受保护的分支 '%s'。
|
||||||
|
|
||||||
@ -1021,6 +1040,10 @@ pulls.rebase_merge_pull_request=变基并合并
|
|||||||
pulls.rebase_merge_commit_pull_request=变基合并 (--no-ff)
|
pulls.rebase_merge_commit_pull_request=变基合并 (--no-ff)
|
||||||
pulls.squash_merge_pull_request=压缩提交并合并
|
pulls.squash_merge_pull_request=压缩提交并合并
|
||||||
pulls.invalid_merge_option=你可以在此合并请求中使用合并选项。
|
pulls.invalid_merge_option=你可以在此合并请求中使用合并选项。
|
||||||
|
pulls.merge_conflict=合并失败:合并时发生冲突:%[1]s<br>[2]<br> 提示:尝试不同的合并策略
|
||||||
|
pulls.rebase_conflict=合并失败:Rebase合并时发生冲突:%[1]s<br>[2]<br> 提示:尝试不同的合并策略
|
||||||
|
pulls.unrelated_histories=合并失败:两个分支没有共同历史。提示:尝试不同的策略
|
||||||
|
pulls.merge_out_of_date=合并失败:在生成合并时,主分支已更新。提示:再试一次。
|
||||||
pulls.open_unmerged_pull_exists=`您不能执行重新打开操作, 因为已经存在相同的合并请求 (#%d)。`
|
pulls.open_unmerged_pull_exists=`您不能执行重新打开操作, 因为已经存在相同的合并请求 (#%d)。`
|
||||||
pulls.status_checking=一些检测仍在等待运行
|
pulls.status_checking=一些检测仍在等待运行
|
||||||
pulls.status_checks_success=所有检测均成功
|
pulls.status_checks_success=所有检测均成功
|
||||||
@ -1089,6 +1112,9 @@ activity.period.daily=1 天
|
|||||||
activity.period.halfweekly=3 天
|
activity.period.halfweekly=3 天
|
||||||
activity.period.weekly=1周
|
activity.period.weekly=1周
|
||||||
activity.period.monthly=1 个月
|
activity.period.monthly=1 个月
|
||||||
|
activity.period.quarterly=3个月
|
||||||
|
activity.period.semiyearly=6 个月
|
||||||
|
activity.period.yearly=1年
|
||||||
activity.overview=概览
|
activity.overview=概览
|
||||||
activity.active_prs_count_1=<strong>%d</strong> 合并请求
|
activity.active_prs_count_1=<strong>%d</strong> 合并请求
|
||||||
activity.active_prs_count_n=<strong>%d</strong> 合并请求
|
activity.active_prs_count_n=<strong>%d</strong> 合并请求
|
||||||
@ -1511,6 +1537,7 @@ team_name=团队名称
|
|||||||
team_desc=团队描述
|
team_desc=团队描述
|
||||||
team_name_helper=团队名字应该简单明了。
|
team_name_helper=团队名字应该简单明了。
|
||||||
team_desc_helper=描述团队的目的或作用。
|
team_desc_helper=描述团队的目的或作用。
|
||||||
|
team_access_desc=仓库权限
|
||||||
team_permission_desc=权限
|
team_permission_desc=权限
|
||||||
team_unit_desc=允许访问仓库单元
|
team_unit_desc=允许访问仓库单元
|
||||||
|
|
||||||
@ -1578,10 +1605,21 @@ teams.write_permission_desc=该团队拥有对所属仓库的 <strong>读取</st
|
|||||||
teams.admin_permission_desc=该团队拥有一定的 <strong>管理</strong> 权限,团队成员可以读取、克隆、推送以及添加其它仓库协作者。
|
teams.admin_permission_desc=该团队拥有一定的 <strong>管理</strong> 权限,团队成员可以读取、克隆、推送以及添加其它仓库协作者。
|
||||||
teams.repositories=团队仓库
|
teams.repositories=团队仓库
|
||||||
teams.search_repo_placeholder=搜索仓库...
|
teams.search_repo_placeholder=搜索仓库...
|
||||||
|
teams.remove_all_repos_title=移除所有团队仓库
|
||||||
|
teams.remove_all_repos_desc=这将从团队中移除所有仓库。
|
||||||
|
teams.add_all_repos_title=添加所有仓库
|
||||||
|
teams.add_all_repos_desc=这将把组织的所有仓库添加到团队。
|
||||||
teams.add_nonexistent_repo=您尝试添加到团队的仓库不存在,请先创建仓库!
|
teams.add_nonexistent_repo=您尝试添加到团队的仓库不存在,请先创建仓库!
|
||||||
teams.add_duplicate_users=用户已经是团队成员。
|
teams.add_duplicate_users=用户已经是团队成员。
|
||||||
teams.repos.none=此团队无法访问任何仓库。
|
teams.repos.none=此团队无法访问任何仓库。
|
||||||
teams.members.none=团队中没有成员。
|
teams.members.none=团队中没有成员。
|
||||||
|
teams.specific_repositories=指定仓库
|
||||||
|
teams.specific_repositories_helper=团队成员将只能访问添加到团队的仓库。 选择此项 <strong>将不会</strong> 自动删除已经添加的仓库。
|
||||||
|
teams.all_repositories=所有仓库
|
||||||
|
teams.all_repositories_helper=团队可以访问所有仓库。选择此选项将 <strong>添加所有现有的</strong> 仓库到指定团队。
|
||||||
|
teams.all_repositories_read_permission_desc=此团队授予<strong>读取</strong><strong>所有仓库</strong>的访问权限: 成员可以查看和克隆仓库。
|
||||||
|
teams.all_repositories_write_permission_desc=此团队授予<strong>修改</strong><strong>所有仓库</strong>的访问权限: 成员可以查看和推送至仓库。
|
||||||
|
teams.all_repositories_admin_permission_desc=该团队拥有 <strong>管理</strong> <strong>所有仓库</strong>的权限:团队成员可以读取、克隆、推送以及添加其它仓库协作者。
|
||||||
|
|
||||||
[admin]
|
[admin]
|
||||||
dashboard=管理面板
|
dashboard=管理面板
|
||||||
@ -1674,6 +1712,7 @@ users.auth_login_name=认证登录名称
|
|||||||
users.password_helper=保持密码为空将不更改密码。
|
users.password_helper=保持密码为空将不更改密码。
|
||||||
users.update_profile_success=该帐户已被更新。
|
users.update_profile_success=该帐户已被更新。
|
||||||
users.edit_account=编辑帐号
|
users.edit_account=编辑帐号
|
||||||
|
users.max_repo_creation=最大仓库数
|
||||||
users.max_repo_creation_desc=(设置为 -1 表示使用全局默认值)
|
users.max_repo_creation_desc=(设置为 -1 表示使用全局默认值)
|
||||||
users.is_activated=该用户已被激活
|
users.is_activated=该用户已被激活
|
||||||
users.prohibit_login=禁用登录
|
users.prohibit_login=禁用登录
|
||||||
|
3443
package-lock.json
generated
3443
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
19
package.json
19
package.json
@ -5,14 +5,23 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "9.6.1",
|
"@babel/core": "7.7.2",
|
||||||
"eslint": "6.3.0",
|
"@babel/preset-env": "7.7.1",
|
||||||
|
"autoprefixer": "9.7.1",
|
||||||
|
"babel-loader": "8.0.6",
|
||||||
|
"core-js": "3.4.1",
|
||||||
|
"eslint": "6.6.0",
|
||||||
|
"eslint-config-airbnb-base": "14.0.0",
|
||||||
|
"eslint-plugin-import": "2.18.2",
|
||||||
"less": "3.10.3",
|
"less": "3.10.3",
|
||||||
"less-plugin-clean-css": "1.5.1",
|
"less-plugin-clean-css": "1.5.1",
|
||||||
"postcss-cli": "6.1.3",
|
"postcss-cli": "6.1.3",
|
||||||
"stylelint": "10.1.0",
|
"stylelint": "11.1.1",
|
||||||
"stylelint-config-standard": "18.3.0",
|
"stylelint-config-standard": "19.0.0",
|
||||||
"updates": "8.5.3"
|
"terser-webpack-plugin": "2.2.1",
|
||||||
|
"updates": "9.0.1",
|
||||||
|
"webpack": "4.41.2",
|
||||||
|
"webpack-cli": "3.3.10"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
|
@ -73,7 +73,7 @@ a{cursor:pointer}
|
|||||||
.right.stackable.menu{margin-left:auto;display:flex;align-items:inherit;flex-direction:inherit}
|
.right.stackable.menu{margin-left:auto;display:flex;align-items:inherit;flex-direction:inherit}
|
||||||
.ui.left{float:left}
|
.ui.left{float:left}
|
||||||
.ui.right{float:right}
|
.ui.right{float:right}
|
||||||
.ui.button,.ui.menu .item{-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto}
|
.ui.button,.ui.menu .item{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}
|
||||||
.ui.container.fluid.padded{padding:0 10px 0 10px}
|
.ui.container.fluid.padded{padding:0 10px 0 10px}
|
||||||
.ui.form .ui.button{font-weight:400}
|
.ui.form .ui.button{font-weight:400}
|
||||||
.ui.floating.label{z-index:10}
|
.ui.floating.label{z-index:10}
|
||||||
@ -233,14 +233,14 @@ i.icons .icon:first-child{margin-right:0}
|
|||||||
i.icon.centerlock{top:1.5em}
|
i.icon.centerlock{top:1.5em}
|
||||||
.ui.label>.detail .icons{margin-right:.25em}
|
.ui.label>.detail .icons{margin-right:.25em}
|
||||||
.ui.label>.detail .icons .icon{margin-right:0}
|
.ui.label>.detail .icons .icon{margin-right:0}
|
||||||
.lines-num{vertical-align:top;text-align:right!important;color:#999;background:#f5f5f5;width:1%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
.lines-num{vertical-align:top;text-align:right!important;color:#999;background:#f5f5f5;width:1%;-webkit-user-select:none;-ms-user-select:none;user-select:none}
|
||||||
.lines-num span:before{content:attr(data-line-number);line-height:20px!important;padding:0 10px;cursor:pointer;display:block}
|
.lines-num span:before{content:attr(data-line-number);line-height:20px!important;padding:0 10px;cursor:pointer;display:block}
|
||||||
.lines-code,.lines-num{padding:0!important}
|
.lines-code,.lines-num{padding:0!important}
|
||||||
.lines-code .hljs,.lines-code ol,.lines-code pre,.lines-num .hljs,.lines-num ol,.lines-num pre{background-color:#fff;margin:0;padding:0!important}
|
.lines-code .hljs,.lines-code ol,.lines-code pre,.lines-num .hljs,.lines-num ol,.lines-num pre{background-color:#fff;margin:0;padding:0!important}
|
||||||
.lines-code .hljs li,.lines-code ol li,.lines-code pre li,.lines-num .hljs li,.lines-num ol li,.lines-num pre li{display:block;width:100%}
|
.lines-code .hljs li,.lines-code ol li,.lines-code pre li,.lines-num .hljs li,.lines-num ol li,.lines-num pre li{display:block;width:100%}
|
||||||
.lines-code .hljs li:before,.lines-code ol li:before,.lines-code pre li:before,.lines-num .hljs li:before,.lines-num ol li:before,.lines-num pre li:before{content:' '}
|
.lines-code .hljs li:before,.lines-code ol li:before,.lines-code pre li:before,.lines-num .hljs li:before,.lines-num ol li:before,.lines-num pre li:before{content:' '}
|
||||||
.lines-commit{vertical-align:top;color:#999;padding:0!important;background:#f5f5f5;width:1%;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}
|
.lines-commit{vertical-align:top;color:#999;padding:0!important;background:#f5f5f5;width:1%;-ms-user-select:none;-webkit-user-select:none;user-select:none}
|
||||||
.lines-commit .blame-info{width:350px;max-width:350px;display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:0 0 0 10px}
|
.lines-commit .blame-info{width:350px;max-width:350px;display:block;-webkit-user-select:none;-ms-user-select:none;user-select:none;padding:0 0 0 10px}
|
||||||
.lines-commit .blame-info .blame-data{display:flex;font-family:-apple-system,BlinkMacSystemFont,system-ui,'Segoe UI',Roboto,Helvetica,Arial}
|
.lines-commit .blame-info .blame-data{display:flex;font-family:-apple-system,BlinkMacSystemFont,system-ui,'Segoe UI',Roboto,Helvetica,Arial}
|
||||||
.lines-commit .blame-info .blame-data .blame-message{flex-grow:2;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;line-height:20px}
|
.lines-commit .blame-info .blame-data .blame-message{flex-grow:2;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;line-height:20px}
|
||||||
.lines-commit .blame-info .blame-data .blame-avatar,.lines-commit .blame-info .blame-data .blame-time{flex-shrink:0}
|
.lines-commit .blame-info .blame-data .blame-avatar,.lines-commit .blame-info .blame-data .blame-time{flex-shrink:0}
|
||||||
@ -333,7 +333,7 @@ i.icon.centerlock{top:1.5em}
|
|||||||
.repository.wiki.revisions .ui.container>.ui.stackable.grid>.header{margin-top:0}
|
.repository.wiki.revisions .ui.container>.ui.stackable.grid>.header{margin-top:0}
|
||||||
.repository.wiki.revisions .ui.container>.ui.stackable.grid>.header .sub.header{padding-left:52px;word-break:break-word}
|
.repository.wiki.revisions .ui.container>.ui.stackable.grid>.header .sub.header{padding-left:52px;word-break:break-word}
|
||||||
.file-revisions-btn{display:block;float:left;margin-bottom:2px!important;padding:11px!important;margin-right:10px!important}
|
.file-revisions-btn{display:block;float:left;margin-bottom:2px!important;padding:11px!important;margin-right:10px!important}
|
||||||
.file-revisions-btn i{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
.file-revisions-btn i{-webkit-touch-callout:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}
|
||||||
.home .logo{max-width:220px}
|
.home .logo{max-width:220px}
|
||||||
@media only screen and (max-width:767px){.home .hero h1{font-size:3.5em}
|
@media only screen and (max-width:767px){.home .hero h1{font-size:3.5em}
|
||||||
.home .hero h2{font-size:2em}
|
.home .hero h2{font-size:2em}
|
||||||
@ -687,7 +687,7 @@ i.icon.centerlock{top:1.5em}
|
|||||||
.repository .diff-box .header .file{flex:1;color:#888;word-break:break-all}
|
.repository .diff-box .header .file{flex:1;color:#888;word-break:break-all}
|
||||||
.repository .diff-box .header .button{margin:-5px 0 -5px 12px;padding:8px 10px;flex:0 0 auto}
|
.repository .diff-box .header .button{margin:-5px 0 -5px 12px;padding:8px 10px;flex:0 0 auto}
|
||||||
.repository .diff-file-box .header{background-color:#f7f7f7}
|
.repository .diff-file-box .header{background-color:#f7f7f7}
|
||||||
.repository .diff-file-box .file-body.file-code .lines-num{text-align:right;color:#a6a6a6;background:#fafafa;width:1%;min-width:50px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top}
|
.repository .diff-file-box .file-body.file-code .lines-num{text-align:right;color:#a6a6a6;background:#fafafa;width:1%;min-width:50px;-webkit-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top}
|
||||||
.repository .diff-file-box .file-body.file-code .lines-num span.fold{display:block;text-align:center}
|
.repository .diff-file-box .file-body.file-code .lines-num span.fold{display:block;text-align:center}
|
||||||
.repository .diff-file-box .file-body.file-code .lines-num-old{border-right:1px solid #ddd}
|
.repository .diff-file-box .file-body.file-code .lines-num-old{border-right:1px solid #ddd}
|
||||||
.repository .diff-file-box .code-diff{font-size:12px}
|
.repository .diff-file-box .code-diff{font-size:12px}
|
||||||
@ -698,7 +698,7 @@ i.icon.centerlock{top:1.5em}
|
|||||||
.repository .diff-file-box .code-diff tbody tr .removed-code{background-color:#f99}
|
.repository .diff-file-box .code-diff tbody tr .removed-code{background-color:#f99}
|
||||||
.repository .diff-file-box .code-diff tbody tr .added-code{background-color:#9f9}
|
.repository .diff-file-box .code-diff tbody tr .added-code{background-color:#9f9}
|
||||||
.repository .diff-file-box .code-diff tbody tr [data-line-num]::before{content:attr(data-line-num);text-align:right}
|
.repository .diff-file-box .code-diff tbody tr [data-line-num]::before{content:attr(data-line-num);text-align:right}
|
||||||
.repository .diff-file-box .code-diff tbody tr .lines-type-marker{width:10px;min-width:10px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
.repository .diff-file-box .code-diff tbody tr .lines-type-marker{width:10px;min-width:10px;-webkit-user-select:none;-ms-user-select:none;user-select:none}
|
||||||
.repository .diff-file-box .code-diff tbody tr [data-type-marker]::before{content:attr(data-type-marker);text-align:right;display:inline-block}
|
.repository .diff-file-box .code-diff tbody tr [data-type-marker]::before{content:attr(data-type-marker);text-align:right;display:inline-block}
|
||||||
.repository .diff-file-box .code-diff-unified tbody tr.del-code td{background-color:#ffe0e0!important;border-color:#f1c0c0!important}
|
.repository .diff-file-box .code-diff-unified tbody tr.del-code td{background-color:#ffe0e0!important;border-color:#f1c0c0!important}
|
||||||
.repository .diff-file-box .code-diff-unified tbody tr.add-code td{background-color:#d6fcd6!important;border-color:#c1e9c1!important}
|
.repository .diff-file-box .code-diff-unified tbody tr.add-code td{background-color:#d6fcd6!important;border-color:#c1e9c1!important}
|
||||||
@ -898,6 +898,7 @@ tbody.commit-list{vertical-align:baseline}
|
|||||||
.repo-buttons .disabled-repo-button a.button:hover{background:0 0!important;color:rgba(0,0,0,.6)!important;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset!important}
|
.repo-buttons .disabled-repo-button a.button:hover{background:0 0!important;color:rgba(0,0,0,.6)!important;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset!important}
|
||||||
.repo-buttons .ui.labeled.button>.label{border-left:0!important;margin:0!important}
|
.repo-buttons .ui.labeled.button>.label{border-left:0!important;margin:0!important}
|
||||||
.tag-code,.tag-code td{background-color:#f0f0f0!important;border-color:#d3cfcf!important;padding-top:8px;padding-bottom:8px}
|
.tag-code,.tag-code td{background-color:#f0f0f0!important;border-color:#d3cfcf!important;padding-top:8px;padding-bottom:8px}
|
||||||
|
td.blob-excerpt{background-color:#fafafa}
|
||||||
.issue-keyword{border-bottom:1px dotted #959da5;display:inline-block}
|
.issue-keyword{border-bottom:1px dotted #959da5;display:inline-block}
|
||||||
.file-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px!important}
|
.file-header{display:flex;justify-content:space-between;align-items:center;padding:8px 12px!important}
|
||||||
.file-info{display:flex;align-items:center}
|
.file-info{display:flex;align-items:center}
|
||||||
@ -1068,4 +1069,8 @@ tbody.commit-list{vertical-align:baseline}
|
|||||||
.comment-code-cloud .footer:after{clear:both;content:"";display:block}
|
.comment-code-cloud .footer:after{clear:both;content:"";display:block}
|
||||||
.comment-code-cloud button.comment-form-reply{margin:.5em .5em .5em 4.5em}
|
.comment-code-cloud button.comment-form-reply{margin:.5em .5em .5em 4.5em}
|
||||||
.comment-code-cloud form.comment-form-reply{margin:0 0 0 4em}
|
.comment-code-cloud form.comment-form-reply{margin:0 0 0 4em}
|
||||||
.file-comment{font:12px 'SF Mono',Consolas,Menlo,'Liberation Mono',Monaco,'Lucida Console',monospace;color:rgba(0,0,0,.87)}
|
.file-comment{font:12px 'SF Mono',Consolas,Menlo,'Liberation Mono',Monaco,'Lucida Console',monospace;color:rgba(0,0,0,.87)}
|
||||||
|
.ui.fold-code{margin-right:1em;padding-left:5px;cursor:pointer;width:22px;font-size:12px}
|
||||||
|
.ui.fold-code:hover{color:#428bca}
|
||||||
|
.ui.blob-excerpt{display:block;line-height:20px;font-size:16px;cursor:pointer}
|
||||||
|
.ui.blob-excerpt:hover{color:#428bca}
|
@ -14,7 +14,7 @@ body{background:#383c4a;color:#9e9e9e}
|
|||||||
*{scrollbar-width:thin;scrollbar-color:#87ab63 rgba(255,255,255,.1)}
|
*{scrollbar-width:thin;scrollbar-color:#87ab63 rgba(255,255,255,.1)}
|
||||||
::-webkit-scrollbar{-webkit-appearance:none!important;width:10px!important;height:10px!important}
|
::-webkit-scrollbar{-webkit-appearance:none!important;width:10px!important;height:10px!important}
|
||||||
::-webkit-scrollbar-track{border-radius:0!important;background:rgba(255,255,255,.1)!important}
|
::-webkit-scrollbar-track{border-radius:0!important;background:rgba(255,255,255,.1)!important}
|
||||||
::-webkit-scrollbar-thumb{cursor:pointer!important;border-radius:5px!important;transition:color .2s ease!important;background:#87ab63!important}
|
::-webkit-scrollbar-thumb{cursor:pointer!important;border-radius:5px!important;-webkit-transition:color .2s ease!important;transition:color .2s ease!important;background:#87ab63!important}
|
||||||
::-webkit-scrollbar-thumb:window-inactive{background:#87ab63!important}
|
::-webkit-scrollbar-thumb:window-inactive{background:#87ab63!important}
|
||||||
::-webkit-scrollbar-thumb:hover{background:#87ab63!important}
|
::-webkit-scrollbar-thumb:hover{background:#87ab63!important}
|
||||||
a{color:#87ab63}
|
a{color:#87ab63}
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
/* globals gitGraph */
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
const graphList = [];
|
|
||||||
|
|
||||||
if (!document.getElementById('graph-canvas')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#graph-raw-list li span.node-relation").each(function () {
|
|
||||||
graphList.push($(this).text());
|
|
||||||
})
|
|
||||||
|
|
||||||
gitGraph(document.getElementById('graph-canvas'), graphList);
|
|
||||||
})
|
|
3426
public/js/index.js
3426
public/js/index.js
File diff suppressed because one or more lines are too long
1
public/js/index.js.map
Normal file
1
public/js/index.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/vendor/VERSIONS
vendored
2
public/vendor/VERSIONS
vendored
@ -23,7 +23,7 @@ Version: 745f604212e2abfe2f0a59169ea530857b46625c
|
|||||||
File(s): /vendor/plugins/vue/vue.min.js
|
File(s): /vendor/plugins/vue/vue.min.js
|
||||||
Version: 2.1.10
|
Version: 2.1.10
|
||||||
|
|
||||||
File(s): /vendor/plugins/emojify/emojify.min.js
|
File(s): /vendor/plugins/emojify/emojify.custom.js
|
||||||
Version: 1.1.0
|
Version: 1.1.0
|
||||||
|
|
||||||
File(s): /vendor/plugins/cssrelpreload/
|
File(s): /vendor/plugins/cssrelpreload/
|
||||||
|
9
public/vendor/librejs.html
vendored
9
public/vendor/librejs.html
vendored
@ -38,12 +38,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><a href="../js/index.js">index.js</a></td>
|
<td><a href="../js/index.js">index.js</a></td>
|
||||||
<td><a href="https://github.com/go-gitea/gitea/blob/master/LICENSE">Expat</a></td>
|
<td><a href="https://github.com/go-gitea/gitea/blob/master/LICENSE">Expat</a></td>
|
||||||
<td><a href="https://github.com/go-gitea/gitea/tree/master/public/js">index.js</a></td>
|
<td><a href="https://github.com/go-gitea/gitea/tree/master/web_src/js">*.js</a></td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a href="../js/draw.js">draw.js</a></td>
|
|
||||||
<td><a href="https://github.com/go-gitea/gitea/blob/master/LICENSE">Expat</a></td>
|
|
||||||
<td><a href="https://github.com/go-gitea/gitea/tree/master/public/js">draw.js</a></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="./plugins/clipboard/clipboard.min.js">clipboard.min.js</a></td>
|
<td><a href="./plugins/clipboard/clipboard.min.js">clipboard.min.js</a></td>
|
||||||
@ -61,7 +56,7 @@
|
|||||||
<td><a href="https://github.com/vuejs/vue/archive/v2.6.6.tar.gz">vue.js-v2.6.6.tar.gz</a></td>
|
<td><a href="https://github.com/vuejs/vue/archive/v2.6.6.tar.gz">vue.js-v2.6.6.tar.gz</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="./plugins/emojify/emojify.min.js">emojify.min.js</a></td>
|
<td><a href="./plugins/emojify/emojify.custom.js">emojify.custom.js</a></td>
|
||||||
<td><a href="http://www.freebsd.org/copyright/freebsd-license.html">Expat</a></td>
|
<td><a href="http://www.freebsd.org/copyright/freebsd-license.html">Expat</a></td>
|
||||||
<td><a href="https://github.com/Ranks/emojify.js/archive/1.1.0.tar.gz">emojify-1.1.0.tar.gz</a></td>
|
<td><a href="https://github.com/Ranks/emojify.js/archive/1.1.0.tar.gz">emojify-1.1.0.tar.gz</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
1
public/vendor/plugins/emojify/emojify.custom.js
vendored
Normal file
1
public/vendor/plugins/emojify/emojify.custom.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
public/vendor/plugins/emojify/emojify.min.js
vendored
4
public/vendor/plugins/emojify/emojify.min.js
vendored
File diff suppressed because one or more lines are too long
BIN
public/vendor/plugins/emojify/images/gitea.png
vendored
Normal file
BIN
public/vendor/plugins/emojify/images/gitea.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
@ -6,6 +6,7 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@ -25,6 +26,7 @@ import (
|
|||||||
"code.gitea.io/gitea/services/mailer"
|
"code.gitea.io/gitea/services/mailer"
|
||||||
|
|
||||||
"gitea.com/macaron/macaron"
|
"gitea.com/macaron/macaron"
|
||||||
|
"gitea.com/macaron/session"
|
||||||
"github.com/unknwon/com"
|
"github.com/unknwon/com"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -207,7 +209,7 @@ func SendTestMail(ctx *context.Context) {
|
|||||||
ctx.Redirect(setting.AppSubURL + "/admin/config")
|
ctx.Redirect(setting.AppSubURL + "/admin/config")
|
||||||
}
|
}
|
||||||
|
|
||||||
func shadownPasswordKV(cfgItem, splitter string) string {
|
func shadowPasswordKV(cfgItem, splitter string) string {
|
||||||
fields := strings.Split(cfgItem, splitter)
|
fields := strings.Split(cfgItem, splitter)
|
||||||
for i := 0; i < len(fields); i++ {
|
for i := 0; i < len(fields); i++ {
|
||||||
if strings.HasPrefix(fields[i], "password=") {
|
if strings.HasPrefix(fields[i], "password=") {
|
||||||
@ -218,10 +220,10 @@ func shadownPasswordKV(cfgItem, splitter string) string {
|
|||||||
return strings.Join(fields, splitter)
|
return strings.Join(fields, splitter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shadownURL(provider, cfgItem string) string {
|
func shadowURL(provider, cfgItem string) string {
|
||||||
u, err := url.Parse(cfgItem)
|
u, err := url.Parse(cfgItem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("shodowPassword %v failed: %v", provider, err)
|
log.Error("Shadowing Password for %v failed: %v", provider, err)
|
||||||
return cfgItem
|
return cfgItem
|
||||||
}
|
}
|
||||||
if u.User != nil {
|
if u.User != nil {
|
||||||
@ -239,7 +241,7 @@ func shadownURL(provider, cfgItem string) string {
|
|||||||
func shadowPassword(provider, cfgItem string) string {
|
func shadowPassword(provider, cfgItem string) string {
|
||||||
switch provider {
|
switch provider {
|
||||||
case "redis":
|
case "redis":
|
||||||
return shadownPasswordKV(cfgItem, ",")
|
return shadowPasswordKV(cfgItem, ",")
|
||||||
case "mysql":
|
case "mysql":
|
||||||
//root:@tcp(localhost:3306)/macaron?charset=utf8
|
//root:@tcp(localhost:3306)/macaron?charset=utf8
|
||||||
atIdx := strings.Index(cfgItem, "@")
|
atIdx := strings.Index(cfgItem, "@")
|
||||||
@ -253,15 +255,21 @@ func shadowPassword(provider, cfgItem string) string {
|
|||||||
case "postgres":
|
case "postgres":
|
||||||
// user=jiahuachen dbname=macaron port=5432 sslmode=disable
|
// user=jiahuachen dbname=macaron port=5432 sslmode=disable
|
||||||
if !strings.HasPrefix(cfgItem, "postgres://") {
|
if !strings.HasPrefix(cfgItem, "postgres://") {
|
||||||
return shadownPasswordKV(cfgItem, " ")
|
return shadowPasswordKV(cfgItem, " ")
|
||||||
}
|
}
|
||||||
|
fallthrough
|
||||||
|
case "couchbase":
|
||||||
|
return shadowURL(provider, cfgItem)
|
||||||
// postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full
|
// postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full
|
||||||
// Notice: use shadwonURL
|
// Notice: use shadowURL
|
||||||
|
case "VirtualSession":
|
||||||
|
var realSession session.Options
|
||||||
|
if err := json.Unmarshal([]byte(cfgItem), &realSession); err == nil {
|
||||||
|
return shadowPassword(realSession.Provider, realSession.ProviderConfig)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "couchbase"
|
return cfgItem
|
||||||
return shadownURL(provider, cfgItem)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config show admin config page
|
// Config show admin config page
|
||||||
|
@ -631,15 +631,13 @@ func Edit(ctx *context.APIContext, opts api.EditRepoOption) {
|
|||||||
func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) error {
|
func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) error {
|
||||||
owner := ctx.Repo.Owner
|
owner := ctx.Repo.Owner
|
||||||
repo := ctx.Repo.Repository
|
repo := ctx.Repo.Repository
|
||||||
|
|
||||||
oldRepoName := repo.Name
|
|
||||||
newRepoName := repo.Name
|
newRepoName := repo.Name
|
||||||
if opts.Name != nil {
|
if opts.Name != nil {
|
||||||
newRepoName = *opts.Name
|
newRepoName = *opts.Name
|
||||||
}
|
}
|
||||||
// Check if repository name has been changed and not just a case change
|
// Check if repository name has been changed and not just a case change
|
||||||
if repo.LowerName != strings.ToLower(newRepoName) {
|
if repo.LowerName != strings.ToLower(newRepoName) {
|
||||||
if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil {
|
if err := repo_service.ChangeRepositoryName(ctx.User, repo, newRepoName); err != nil {
|
||||||
switch {
|
switch {
|
||||||
case models.IsErrRepoAlreadyExist(err):
|
case models.IsErrRepoAlreadyExist(err):
|
||||||
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err)
|
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err)
|
||||||
@ -653,14 +651,6 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err := models.NewRepoRedirect(ctx.Repo.Owner.ID, repo.ID, repo.Name, newRepoName)
|
|
||||||
if err != nil {
|
|
||||||
ctx.Error(http.StatusUnprocessableEntity, "NewRepoRedirect", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
notification.NotifyRenameRepository(ctx.User, repo, oldRepoName)
|
|
||||||
|
|
||||||
log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName)
|
log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName)
|
||||||
}
|
}
|
||||||
// Update the name in the repo object for the response
|
// Update the name in the repo object for the response
|
||||||
|
@ -245,6 +245,7 @@ func Diff(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["CommitID"] = commitID
|
ctx.Data["CommitID"] = commitID
|
||||||
|
ctx.Data["AfterCommitID"] = commitID
|
||||||
ctx.Data["Username"] = userName
|
ctx.Data["Username"] = userName
|
||||||
ctx.Data["Reponame"] = repoName
|
ctx.Data["Reponame"] = repoName
|
||||||
|
|
||||||
|
@ -5,21 +5,26 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"html"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/highlight"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/services/gitdiff"
|
"code.gitea.io/gitea/services/gitdiff"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tplCompare base.TplName = "repo/diff/compare"
|
tplCompare base.TplName = "repo/diff/compare"
|
||||||
|
tplBlobExcerpt base.TplName = "repo/diff/blob_excerpt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// setPathsCompareContext sets context data for source and raw paths
|
// setPathsCompareContext sets context data for source and raw paths
|
||||||
@ -434,3 +439,109 @@ func CompareDiff(ctx *context.Context) {
|
|||||||
|
|
||||||
ctx.HTML(200, tplCompare)
|
ctx.HTML(200, tplCompare)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExcerptBlob render blob excerpt contents
|
||||||
|
func ExcerptBlob(ctx *context.Context) {
|
||||||
|
commitID := ctx.Params("sha")
|
||||||
|
lastLeft := ctx.QueryInt("last_left")
|
||||||
|
lastRight := ctx.QueryInt("last_right")
|
||||||
|
idxLeft := ctx.QueryInt("left")
|
||||||
|
idxRight := ctx.QueryInt("right")
|
||||||
|
leftHunkSize := ctx.QueryInt("left_hunk_size")
|
||||||
|
rightHunkSize := ctx.QueryInt("right_hunk_size")
|
||||||
|
anchor := ctx.Query("anchor")
|
||||||
|
direction := ctx.Query("direction")
|
||||||
|
filePath := ctx.Query("path")
|
||||||
|
gitRepo := ctx.Repo.GitRepo
|
||||||
|
chunkSize := gitdiff.BlobExceprtChunkSize
|
||||||
|
commit, err := gitRepo.GetCommit(commitID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(500, "GetCommit")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
section := &gitdiff.DiffSection{
|
||||||
|
Name: filePath,
|
||||||
|
}
|
||||||
|
if direction == "up" && (idxLeft-lastLeft) > chunkSize {
|
||||||
|
idxLeft -= chunkSize
|
||||||
|
idxRight -= chunkSize
|
||||||
|
leftHunkSize += chunkSize
|
||||||
|
rightHunkSize += chunkSize
|
||||||
|
section.Lines, err = getExcerptLines(commit, filePath, idxLeft-1, idxRight-1, chunkSize)
|
||||||
|
} else if direction == "down" && (idxLeft-lastLeft) > chunkSize {
|
||||||
|
section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, chunkSize)
|
||||||
|
lastLeft += chunkSize
|
||||||
|
lastRight += chunkSize
|
||||||
|
} else {
|
||||||
|
section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, idxRight-lastRight-1)
|
||||||
|
leftHunkSize = 0
|
||||||
|
rightHunkSize = 0
|
||||||
|
idxLeft = lastLeft
|
||||||
|
idxRight = lastRight
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(500, "getExcerptLines")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if idxRight > lastRight {
|
||||||
|
lineText := " "
|
||||||
|
if rightHunkSize > 0 || leftHunkSize > 0 {
|
||||||
|
lineText = fmt.Sprintf("@@ -%d,%d +%d,%d @@\n", idxLeft, leftHunkSize, idxRight, rightHunkSize)
|
||||||
|
}
|
||||||
|
lineText = html.EscapeString(lineText)
|
||||||
|
lineSection := &gitdiff.DiffLine{
|
||||||
|
Type: gitdiff.DiffLineSection,
|
||||||
|
Content: lineText,
|
||||||
|
SectionInfo: &gitdiff.DiffLineSectionInfo{
|
||||||
|
Path: filePath,
|
||||||
|
LastLeftIdx: lastLeft,
|
||||||
|
LastRightIdx: lastRight,
|
||||||
|
LeftIdx: idxLeft,
|
||||||
|
RightIdx: idxRight,
|
||||||
|
LeftHunkSize: leftHunkSize,
|
||||||
|
RightHunkSize: rightHunkSize,
|
||||||
|
}}
|
||||||
|
if direction == "up" {
|
||||||
|
section.Lines = append([]*gitdiff.DiffLine{lineSection}, section.Lines...)
|
||||||
|
} else if direction == "down" {
|
||||||
|
section.Lines = append(section.Lines, lineSection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.Data["section"] = section
|
||||||
|
ctx.Data["fileName"] = filePath
|
||||||
|
ctx.Data["highlightClass"] = highlight.FileNameToHighlightClass(filepath.Base(filePath))
|
||||||
|
ctx.Data["AfterCommitID"] = commitID
|
||||||
|
ctx.Data["Anchor"] = anchor
|
||||||
|
ctx.HTML(200, tplBlobExcerpt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getExcerptLines(commit *git.Commit, filePath string, idxLeft int, idxRight int, chunkSize int) ([]*gitdiff.DiffLine, error) {
|
||||||
|
blob, err := commit.Tree.GetBlobByPath(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
reader, err := blob.DataAsync()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
scanner := bufio.NewScanner(reader)
|
||||||
|
var diffLines []*gitdiff.DiffLine
|
||||||
|
for line := 0; line < idxRight+chunkSize; line++ {
|
||||||
|
if ok := scanner.Scan(); !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if line < idxRight {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lineText := scanner.Text()
|
||||||
|
diffLine := &gitdiff.DiffLine{
|
||||||
|
LeftIdx: idxLeft + (line - idxRight) + 1,
|
||||||
|
RightIdx: line + 1,
|
||||||
|
Type: gitdiff.DiffLinePlain,
|
||||||
|
Content: " " + lineText,
|
||||||
|
}
|
||||||
|
diffLines = append(diffLines, diffLine)
|
||||||
|
}
|
||||||
|
return diffLines, nil
|
||||||
|
}
|
||||||
|
@ -552,6 +552,7 @@ func ViewPullFiles(ctx *context.Context) {
|
|||||||
ctx.Data["Username"] = pull.MustHeadUserName()
|
ctx.Data["Username"] = pull.MustHeadUserName()
|
||||||
ctx.Data["Reponame"] = pull.HeadRepo.Name
|
ctx.Data["Reponame"] = pull.HeadRepo.Name
|
||||||
}
|
}
|
||||||
|
ctx.Data["AfterCommitID"] = endCommitID
|
||||||
|
|
||||||
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(diffRepoPath,
|
diff, err := gitdiff.GetDiffRangeWithWhitespaceBehavior(diffRepoPath,
|
||||||
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
|
startCommitID, endCommitID, setting.Git.MaxGitDiffLines,
|
||||||
|
@ -11,8 +11,6 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/auth"
|
"code.gitea.io/gitea/modules/auth"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/notification"
|
|
||||||
comment_service "code.gitea.io/gitea/services/comments"
|
|
||||||
pull_service "code.gitea.io/gitea/services/pull"
|
pull_service "code.gitea.io/gitea/services/pull"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,64 +29,33 @@ func CreateCodeComment(ctx *context.Context, form auth.CodeCommentForm) {
|
|||||||
ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
|
ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var comment *models.Comment
|
|
||||||
defer func() {
|
|
||||||
if comment != nil {
|
|
||||||
ctx.Redirect(comment.HTMLURL())
|
|
||||||
} else {
|
|
||||||
ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
signedLine := form.Line
|
signedLine := form.Line
|
||||||
if form.Side == "previous" {
|
if form.Side == "previous" {
|
||||||
signedLine *= -1
|
signedLine *= -1
|
||||||
}
|
}
|
||||||
|
|
||||||
review := new(models.Review)
|
comment, err := pull_service.CreateCodeComment(
|
||||||
if form.IsReview {
|
|
||||||
var err error
|
|
||||||
// Check if the user has already a pending review for this issue
|
|
||||||
if review, err = models.GetCurrentReview(ctx.User, issue); err != nil {
|
|
||||||
if !models.IsErrReviewNotExist(err) {
|
|
||||||
ctx.ServerError("CreateCodeComment", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// No pending review exists
|
|
||||||
// Create a new pending review for this issue & user
|
|
||||||
if review, err = pull_service.CreateReview(models.CreateReviewOptions{
|
|
||||||
Type: models.ReviewTypePending,
|
|
||||||
Reviewer: ctx.User,
|
|
||||||
Issue: issue,
|
|
||||||
}); err != nil {
|
|
||||||
ctx.ServerError("CreateCodeComment", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if review.ID == 0 {
|
|
||||||
review.ID = form.Reply
|
|
||||||
}
|
|
||||||
//FIXME check if line, commit and treepath exist
|
|
||||||
comment, err := comment_service.CreateCodeComment(
|
|
||||||
ctx.User,
|
ctx.User,
|
||||||
issue.Repo,
|
|
||||||
issue,
|
issue,
|
||||||
|
signedLine,
|
||||||
form.Content,
|
form.Content,
|
||||||
form.TreePath,
|
form.TreePath,
|
||||||
signedLine,
|
form.IsReview,
|
||||||
review.ID,
|
form.Reply,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("CreateCodeComment", err)
|
ctx.ServerError("CreateCodeComment", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Send no notification if comment is pending
|
|
||||||
if !form.IsReview || form.Reply != 0 {
|
|
||||||
notification.NotifyCreateIssueComment(ctx.User, issue.Repo, issue, comment)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Trace("Comment created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID)
|
log.Trace("Comment created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, comment.ID)
|
||||||
|
|
||||||
|
if comment != nil {
|
||||||
|
ctx.Redirect(comment.HTMLURL())
|
||||||
|
} else {
|
||||||
|
ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist
|
// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist
|
||||||
@ -105,23 +72,17 @@ func SubmitReview(ctx *context.Context, form auth.SubmitReviewForm) {
|
|||||||
ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
|
ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var review *models.Review
|
|
||||||
var err error
|
|
||||||
|
|
||||||
reviewType := form.ReviewType()
|
reviewType := form.ReviewType()
|
||||||
|
|
||||||
switch reviewType {
|
switch reviewType {
|
||||||
case models.ReviewTypeUnknown:
|
case models.ReviewTypeUnknown:
|
||||||
ctx.ServerError("GetCurrentReview", fmt.Errorf("unknown ReviewType: %s", form.Type))
|
ctx.ServerError("ReviewType", fmt.Errorf("unknown ReviewType: %s", form.Type))
|
||||||
return
|
return
|
||||||
|
|
||||||
// can not approve/reject your own PR
|
// can not approve/reject your own PR
|
||||||
case models.ReviewTypeApprove, models.ReviewTypeReject:
|
case models.ReviewTypeApprove, models.ReviewTypeReject:
|
||||||
|
|
||||||
if issue.Poster.ID == ctx.User.ID {
|
if issue.Poster.ID == ctx.User.ID {
|
||||||
|
|
||||||
var translated string
|
var translated string
|
||||||
|
|
||||||
if reviewType == models.ReviewTypeApprove {
|
if reviewType == models.ReviewTypeApprove {
|
||||||
translated = ctx.Tr("repo.issues.review.self.approval")
|
translated = ctx.Tr("repo.issues.review.self.approval")
|
||||||
} else {
|
} else {
|
||||||
@ -134,69 +95,16 @@ func SubmitReview(ctx *context.Context, form auth.SubmitReviewForm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
review, err = models.GetCurrentReview(ctx.User, issue)
|
_, comm, err := pull_service.SubmitReview(ctx.User, issue, reviewType, form.Content)
|
||||||
if err == nil {
|
|
||||||
review.Issue = issue
|
|
||||||
if errl := review.LoadCodeComments(); errl != nil {
|
|
||||||
ctx.ServerError("LoadCodeComments", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err == nil && len(review.CodeComments) == 0) ||
|
|
||||||
(err != nil && models.IsErrReviewNotExist(err))) &&
|
|
||||||
form.HasEmptyContent() {
|
|
||||||
ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty"))
|
|
||||||
ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !models.IsErrReviewNotExist(err) {
|
if models.IsContentEmptyErr(err) {
|
||||||
ctx.ServerError("GetCurrentReview", err)
|
ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty"))
|
||||||
return
|
ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
|
||||||
|
} else {
|
||||||
|
ctx.ServerError("SubmitReview", err)
|
||||||
}
|
}
|
||||||
// No current review. Create a new one!
|
|
||||||
if review, err = pull_service.CreateReview(models.CreateReviewOptions{
|
|
||||||
Type: reviewType,
|
|
||||||
Issue: issue,
|
|
||||||
Reviewer: ctx.User,
|
|
||||||
Content: form.Content,
|
|
||||||
}); err != nil {
|
|
||||||
ctx.ServerError("CreateReview", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
review.Content = form.Content
|
|
||||||
review.Type = reviewType
|
|
||||||
if err = pull_service.UpdateReview(review); err != nil {
|
|
||||||
ctx.ServerError("UpdateReview", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
comm, err := models.CreateComment(&models.CreateCommentOptions{
|
|
||||||
Type: models.CommentTypeReview,
|
|
||||||
Doer: ctx.User,
|
|
||||||
Content: review.Content,
|
|
||||||
Issue: issue,
|
|
||||||
Repo: issue.Repo,
|
|
||||||
ReviewID: review.ID,
|
|
||||||
})
|
|
||||||
if err != nil || comm == nil {
|
|
||||||
ctx.ServerError("CreateComment", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = review.Publish(); err != nil {
|
|
||||||
ctx.ServerError("Publish", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pr, err := issue.GetPullRequest()
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetPullRequest", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
notification.NotifyPullRequestReview(pr, review, comm)
|
|
||||||
|
|
||||||
ctx.Redirect(fmt.Sprintf("%s/pulls/%d#%s", ctx.Repo.RepoLink, issue.Index, comm.HashTag()))
|
ctx.Redirect(fmt.Sprintf("%s/pulls/%d#%s", ctx.Repo.RepoLink, issue.Index, comm.HashTag()))
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/notification"
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
"code.gitea.io/gitea/modules/validation"
|
"code.gitea.io/gitea/modules/validation"
|
||||||
@ -67,18 +66,15 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isNameChanged := false
|
|
||||||
oldRepoName := repo.Name
|
|
||||||
newRepoName := form.RepoName
|
newRepoName := form.RepoName
|
||||||
// Check if repository name has been changed.
|
// Check if repository name has been changed.
|
||||||
if repo.LowerName != strings.ToLower(newRepoName) {
|
if repo.LowerName != strings.ToLower(newRepoName) {
|
||||||
isNameChanged = true
|
|
||||||
// Close the GitRepo if open
|
// Close the GitRepo if open
|
||||||
if ctx.Repo.GitRepo != nil {
|
if ctx.Repo.GitRepo != nil {
|
||||||
ctx.Repo.GitRepo.Close()
|
ctx.Repo.GitRepo.Close()
|
||||||
ctx.Repo.GitRepo = nil
|
ctx.Repo.GitRepo = nil
|
||||||
}
|
}
|
||||||
if err := models.ChangeRepositoryName(ctx.Repo.Owner, repo.Name, newRepoName); err != nil {
|
if err := repo_service.ChangeRepositoryName(ctx.Repo.Owner, repo, newRepoName); err != nil {
|
||||||
ctx.Data["Err_RepoName"] = true
|
ctx.Data["Err_RepoName"] = true
|
||||||
switch {
|
switch {
|
||||||
case models.IsErrRepoAlreadyExist(err):
|
case models.IsErrRepoAlreadyExist(err):
|
||||||
@ -93,12 +89,6 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := models.NewRepoRedirect(ctx.Repo.Owner.ID, repo.ID, repo.Name, newRepoName)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("NewRepoRedirect", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName)
|
log.Trace("Repository name changed: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newRepoName)
|
||||||
}
|
}
|
||||||
// In case it's just a case change.
|
// In case it's just a case change.
|
||||||
@ -127,10 +117,6 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
|||||||
}
|
}
|
||||||
log.Trace("Repository basic settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
log.Trace("Repository basic settings updated: %s/%s", ctx.Repo.Owner.Name, repo.Name)
|
||||||
|
|
||||||
if isNameChanged {
|
|
||||||
notification.NotifyRenameRepository(ctx.User, repo, oldRepoName)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success"))
|
||||||
ctx.Redirect(repo.Link() + "/settings")
|
ctx.Redirect(repo.Link() + "/settings")
|
||||||
|
|
||||||
@ -383,13 +369,12 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
oldOwnerID := ctx.Repo.Owner.ID
|
|
||||||
// Close the GitRepo if open
|
// Close the GitRepo if open
|
||||||
if ctx.Repo.GitRepo != nil {
|
if ctx.Repo.GitRepo != nil {
|
||||||
ctx.Repo.GitRepo.Close()
|
ctx.Repo.GitRepo.Close()
|
||||||
ctx.Repo.GitRepo = nil
|
ctx.Repo.GitRepo = nil
|
||||||
}
|
}
|
||||||
if err = models.TransferOwnership(ctx.User, newOwner, repo); err != nil {
|
if err = repo_service.TransferOwnership(ctx.User, newOwner, repo); err != nil {
|
||||||
if models.IsErrRepoAlreadyExist(err) {
|
if models.IsErrRepoAlreadyExist(err) {
|
||||||
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
|
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
|
||||||
} else {
|
} else {
|
||||||
@ -398,12 +383,6 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.NewRepoRedirect(oldOwnerID, repo.ID, repo.Name, repo.Name)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("NewRepoRedirect", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Trace("Repository transferred: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newOwner)
|
log.Trace("Repository transferred: %s/%s -> %s", ctx.Repo.Owner.Name, repo.Name, newOwner)
|
||||||
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed"))
|
ctx.Flash.Success(ctx.Tr("repo.settings.transfer_succeed"))
|
||||||
ctx.Redirect(setting.AppSubURL + "/" + newOwner + "/" + repo.Name)
|
ctx.Redirect(setting.AppSubURL + "/" + newOwner + "/" + repo.Name)
|
||||||
@ -707,6 +686,7 @@ func GitHooks(ctx *context.Context) {
|
|||||||
func GitHooksEdit(ctx *context.Context) {
|
func GitHooksEdit(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.settings.githooks")
|
ctx.Data["Title"] = ctx.Tr("repo.settings.githooks")
|
||||||
ctx.Data["PageIsSettingsGitHooks"] = true
|
ctx.Data["PageIsSettingsGitHooks"] = true
|
||||||
|
ctx.Data["RequireSimpleMDE"] = true
|
||||||
|
|
||||||
name := ctx.Params(":name")
|
name := ctx.Params(":name")
|
||||||
hook, err := ctx.Repo.GitRepo.GetHook(name)
|
hook, err := ctx.Repo.GitRepo.GetHook(name)
|
||||||
|
@ -864,6 +864,10 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Get("", repo.Branches)
|
m.Get("", repo.Branches)
|
||||||
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
|
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
|
||||||
|
|
||||||
|
m.Group("/blob_excerpt", func() {
|
||||||
|
m.Get("/:sha", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ExcerptBlob)
|
||||||
|
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
|
||||||
|
|
||||||
m.Group("/pulls/:index", func() {
|
m.Group("/pulls/:index", func() {
|
||||||
m.Get(".diff", repo.DownloadPullDiff)
|
m.Get(".diff", repo.DownloadPullDiff)
|
||||||
m.Get(".patch", repo.DownloadPullPatch)
|
m.Get(".patch", repo.DownloadPullPatch)
|
||||||
|
@ -5,15 +5,8 @@
|
|||||||
package comments
|
package comments
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/git"
|
|
||||||
"code.gitea.io/gitea/modules/notification"
|
"code.gitea.io/gitea/modules/notification"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
|
||||||
"code.gitea.io/gitea/services/gitdiff"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateIssueComment creates a plain issue comment.
|
// CreateIssueComment creates a plain issue comment.
|
||||||
@ -35,60 +28,6 @@ func CreateIssueComment(doer *models.User, repo *models.Repository, issue *model
|
|||||||
return comment, nil
|
return comment, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCodeComment creates a plain code comment at the specified line / path
|
|
||||||
func CreateCodeComment(doer *models.User, repo *models.Repository, issue *models.Issue, content, treePath string, line, reviewID int64) (*models.Comment, error) {
|
|
||||||
var commitID, patch string
|
|
||||||
pr, err := models.GetPullRequestByIssueID(issue.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("GetPullRequestByIssueID: %v", err)
|
|
||||||
}
|
|
||||||
if err := pr.GetBaseRepo(); err != nil {
|
|
||||||
return nil, fmt.Errorf("GetHeadRepo: %v", err)
|
|
||||||
}
|
|
||||||
gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
|
||||||
}
|
|
||||||
defer gitRepo.Close()
|
|
||||||
|
|
||||||
// FIXME validate treePath
|
|
||||||
// Get latest commit referencing the commented line
|
|
||||||
// No need for get commit for base branch changes
|
|
||||||
if line > 0 {
|
|
||||||
commit, err := gitRepo.LineBlame(pr.GetGitRefName(), gitRepo.Path, treePath, uint(line))
|
|
||||||
if err == nil {
|
|
||||||
commitID = commit.ID.String()
|
|
||||||
} else if !strings.Contains(err.Error(), "exit status 128 - fatal: no such path") {
|
|
||||||
return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %v", pr.GetGitRefName(), gitRepo.Path, treePath, line, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only fetch diff if comment is review comment
|
|
||||||
if reviewID != 0 {
|
|
||||||
headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName())
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err)
|
|
||||||
}
|
|
||||||
patchBuf := new(bytes.Buffer)
|
|
||||||
if err := gitdiff.GetRawDiffForFile(gitRepo.Path, pr.MergeBase, headCommitID, gitdiff.RawDiffNormal, treePath, patchBuf); err != nil {
|
|
||||||
return nil, fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %v", err, gitRepo.Path, pr.MergeBase, headCommitID, treePath)
|
|
||||||
}
|
|
||||||
patch = gitdiff.CutDiffAroundLine(patchBuf, int64((&models.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines)
|
|
||||||
}
|
|
||||||
return models.CreateComment(&models.CreateCommentOptions{
|
|
||||||
Type: models.CommentTypeCode,
|
|
||||||
Doer: doer,
|
|
||||||
Repo: repo,
|
|
||||||
Issue: issue,
|
|
||||||
Content: content,
|
|
||||||
LineNum: line,
|
|
||||||
TreePath: treePath,
|
|
||||||
CommitSHA: commitID,
|
|
||||||
ReviewID: reviewID,
|
|
||||||
Patch: patch,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateComment updates information of comment.
|
// UpdateComment updates information of comment.
|
||||||
func UpdateComment(c *models.Comment, doer *models.User, oldContent string) error {
|
func UpdateComment(c *models.Comment, doer *models.User, oldContent string) error {
|
||||||
if err := models.UpdateComment(c, doer); err != nil {
|
if err := models.UpdateComment(c, doer); err != nil {
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -56,15 +57,42 @@ const (
|
|||||||
DiffFileRename
|
DiffFileRename
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DiffLineExpandDirection represents the DiffLineSection expand direction
|
||||||
|
type DiffLineExpandDirection uint8
|
||||||
|
|
||||||
|
// DiffLineExpandDirection possible values.
|
||||||
|
const (
|
||||||
|
DiffLineExpandNone DiffLineExpandDirection = iota + 1
|
||||||
|
DiffLineExpandSingle
|
||||||
|
DiffLineExpandUpDown
|
||||||
|
DiffLineExpandUp
|
||||||
|
DiffLineExpandDown
|
||||||
|
)
|
||||||
|
|
||||||
// DiffLine represents a line difference in a DiffSection.
|
// DiffLine represents a line difference in a DiffSection.
|
||||||
type DiffLine struct {
|
type DiffLine struct {
|
||||||
LeftIdx int
|
LeftIdx int
|
||||||
RightIdx int
|
RightIdx int
|
||||||
Type DiffLineType
|
Type DiffLineType
|
||||||
Content string
|
Content string
|
||||||
Comments []*models.Comment
|
Comments []*models.Comment
|
||||||
|
SectionInfo *DiffLineSectionInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiffLineSectionInfo represents diff line section meta data
|
||||||
|
type DiffLineSectionInfo struct {
|
||||||
|
Path string
|
||||||
|
LastLeftIdx int
|
||||||
|
LastRightIdx int
|
||||||
|
LeftIdx int
|
||||||
|
RightIdx int
|
||||||
|
LeftHunkSize int
|
||||||
|
RightHunkSize int
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlobExceprtChunkSize represent max lines of excerpt
|
||||||
|
const BlobExceprtChunkSize = 20
|
||||||
|
|
||||||
// GetType returns the type of a DiffLine.
|
// GetType returns the type of a DiffLine.
|
||||||
func (d *DiffLine) GetType() int {
|
func (d *DiffLine) GetType() int {
|
||||||
return int(d.Type)
|
return int(d.Type)
|
||||||
@ -91,6 +119,71 @@ func (d *DiffLine) GetLineTypeMarker() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlobExcerptQuery builds query string to get blob excerpt
|
||||||
|
func (d *DiffLine) GetBlobExcerptQuery() string {
|
||||||
|
query := fmt.Sprintf(
|
||||||
|
"last_left=%d&last_right=%d&"+
|
||||||
|
"left=%d&right=%d&"+
|
||||||
|
"left_hunk_size=%d&right_hunk_size=%d&"+
|
||||||
|
"path=%s",
|
||||||
|
d.SectionInfo.LastLeftIdx, d.SectionInfo.LastRightIdx,
|
||||||
|
d.SectionInfo.LeftIdx, d.SectionInfo.RightIdx,
|
||||||
|
d.SectionInfo.LeftHunkSize, d.SectionInfo.RightHunkSize,
|
||||||
|
url.QueryEscape(d.SectionInfo.Path))
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetExpandDirection gets DiffLineExpandDirection
|
||||||
|
func (d *DiffLine) GetExpandDirection() DiffLineExpandDirection {
|
||||||
|
if d.Type != DiffLineSection || d.SectionInfo == nil || d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx <= 1 {
|
||||||
|
return DiffLineExpandNone
|
||||||
|
}
|
||||||
|
if d.SectionInfo.LastLeftIdx <= 0 && d.SectionInfo.LastRightIdx <= 0 {
|
||||||
|
return DiffLineExpandUp
|
||||||
|
} else if d.SectionInfo.RightIdx-d.SectionInfo.LastRightIdx > BlobExceprtChunkSize && d.SectionInfo.RightHunkSize > 0 {
|
||||||
|
return DiffLineExpandUpDown
|
||||||
|
} else if d.SectionInfo.LeftHunkSize <= 0 && d.SectionInfo.RightHunkSize <= 0 {
|
||||||
|
return DiffLineExpandDown
|
||||||
|
}
|
||||||
|
return DiffLineExpandSingle
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDiffLineSectionInfo(curFile *DiffFile, line string, lastLeftIdx, lastRightIdx int) *DiffLineSectionInfo {
|
||||||
|
var (
|
||||||
|
leftLine int
|
||||||
|
leftHunk int
|
||||||
|
rightLine int
|
||||||
|
righHunk int
|
||||||
|
)
|
||||||
|
ss := strings.Split(line, "@@")
|
||||||
|
ranges := strings.Split(ss[1][1:], " ")
|
||||||
|
leftRange := strings.Split(ranges[0], ",")
|
||||||
|
leftLine, _ = com.StrTo(leftRange[0][1:]).Int()
|
||||||
|
if len(leftRange) > 1 {
|
||||||
|
leftHunk, _ = com.StrTo(leftRange[1]).Int()
|
||||||
|
}
|
||||||
|
if len(ranges) > 1 {
|
||||||
|
rightRange := strings.Split(ranges[1], ",")
|
||||||
|
rightLine, _ = com.StrTo(rightRange[0]).Int()
|
||||||
|
if len(rightRange) > 1 {
|
||||||
|
righHunk, _ = com.StrTo(rightRange[1]).Int()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Warn("Parse line number failed: %v", line)
|
||||||
|
rightLine = leftLine
|
||||||
|
righHunk = leftHunk
|
||||||
|
}
|
||||||
|
return &DiffLineSectionInfo{
|
||||||
|
Path: curFile.Name,
|
||||||
|
LastLeftIdx: lastLeftIdx,
|
||||||
|
LastRightIdx: lastRightIdx,
|
||||||
|
LeftIdx: leftLine,
|
||||||
|
RightIdx: rightLine,
|
||||||
|
LeftHunkSize: leftHunk,
|
||||||
|
RightHunkSize: righHunk,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// escape a line's content or return <br> needed for copy/paste purposes
|
// escape a line's content or return <br> needed for copy/paste purposes
|
||||||
func getLineContent(content string) string {
|
func getLineContent(content string) string {
|
||||||
if len(content) > 0 {
|
if len(content) > 0 {
|
||||||
@ -248,6 +341,53 @@ func (diffFile *DiffFile) GetHighlightClass() string {
|
|||||||
return highlight.FileNameToHighlightClass(diffFile.Name)
|
return highlight.FileNameToHighlightClass(diffFile.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTailSection creates a fake DiffLineSection if the last section is not the end of the file
|
||||||
|
func (diffFile *DiffFile) GetTailSection(gitRepo *git.Repository, leftCommitID, rightCommitID string) *DiffSection {
|
||||||
|
if diffFile.Type != DiffFileChange || diffFile.IsBin || diffFile.IsLFSFile {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
leftCommit, err := gitRepo.GetCommit(leftCommitID)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
rightCommit, err := gitRepo.GetCommit(rightCommitID)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
lastSection := diffFile.Sections[len(diffFile.Sections)-1]
|
||||||
|
lastLine := lastSection.Lines[len(lastSection.Lines)-1]
|
||||||
|
leftLineCount := getCommitFileLineCount(leftCommit, diffFile.Name)
|
||||||
|
rightLineCount := getCommitFileLineCount(rightCommit, diffFile.Name)
|
||||||
|
if leftLineCount <= lastLine.LeftIdx || rightLineCount <= lastLine.RightIdx {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
tailDiffLine := &DiffLine{
|
||||||
|
Type: DiffLineSection,
|
||||||
|
Content: " ",
|
||||||
|
SectionInfo: &DiffLineSectionInfo{
|
||||||
|
Path: diffFile.Name,
|
||||||
|
LastLeftIdx: lastLine.LeftIdx,
|
||||||
|
LastRightIdx: lastLine.RightIdx,
|
||||||
|
LeftIdx: leftLineCount,
|
||||||
|
RightIdx: rightLineCount,
|
||||||
|
}}
|
||||||
|
tailSection := &DiffSection{Lines: []*DiffLine{tailDiffLine}}
|
||||||
|
return tailSection
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCommitFileLineCount(commit *git.Commit, filePath string) int {
|
||||||
|
blob, err := commit.GetBlobByPath(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
lineCount, err := blob.GetBlobLineCount()
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return lineCount
|
||||||
|
}
|
||||||
|
|
||||||
// Diff represents a difference between two git trees.
|
// Diff represents a difference between two git trees.
|
||||||
type Diff struct {
|
type Diff struct {
|
||||||
TotalAddition, TotalDeletion int
|
TotalAddition, TotalDeletion int
|
||||||
@ -510,19 +650,16 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
|
|||||||
case line[0] == '@':
|
case line[0] == '@':
|
||||||
curSection = &DiffSection{}
|
curSection = &DiffSection{}
|
||||||
curFile.Sections = append(curFile.Sections, curSection)
|
curFile.Sections = append(curFile.Sections, curSection)
|
||||||
ss := strings.Split(line, "@@")
|
lineSectionInfo := getDiffLineSectionInfo(curFile, line, leftLine-1, rightLine-1)
|
||||||
diffLine := &DiffLine{Type: DiffLineSection, Content: line}
|
diffLine := &DiffLine{
|
||||||
curSection.Lines = append(curSection.Lines, diffLine)
|
Type: DiffLineSection,
|
||||||
|
Content: line,
|
||||||
// Parse line number.
|
SectionInfo: lineSectionInfo,
|
||||||
ranges := strings.Split(ss[1][1:], " ")
|
|
||||||
leftLine, _ = com.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int()
|
|
||||||
if len(ranges) > 1 {
|
|
||||||
rightLine, _ = com.StrTo(strings.Split(ranges[1], ",")[0]).Int()
|
|
||||||
} else {
|
|
||||||
log.Warn("Parse line number failed: %v", line)
|
|
||||||
rightLine = leftLine
|
|
||||||
}
|
}
|
||||||
|
curSection.Lines = append(curSection.Lines, diffLine)
|
||||||
|
// update line number.
|
||||||
|
leftLine = lineSectionInfo.LeftIdx
|
||||||
|
rightLine = lineSectionInfo.RightIdx
|
||||||
continue
|
continue
|
||||||
case line[0] == '+':
|
case line[0] == '+':
|
||||||
curFile.Addition++
|
curFile.Addition++
|
||||||
@ -599,6 +736,8 @@ func ParsePatch(maxLines, maxLineCharacters, maxFiles int, reader io.Reader) (*D
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
curFileLinesCount = 0
|
curFileLinesCount = 0
|
||||||
|
leftLine = 1
|
||||||
|
rightLine = 1
|
||||||
curFileLFSPrefix = false
|
curFileLFSPrefix = false
|
||||||
|
|
||||||
// Check file diff type and is submodule.
|
// Check file diff type and is submodule.
|
||||||
@ -701,6 +840,7 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
|
|||||||
diffArgs = append(diffArgs, actualBeforeCommitID)
|
diffArgs = append(diffArgs, actualBeforeCommitID)
|
||||||
diffArgs = append(diffArgs, afterCommitID)
|
diffArgs = append(diffArgs, afterCommitID)
|
||||||
cmd = exec.Command(git.GitExecutable, diffArgs...)
|
cmd = exec.Command(git.GitExecutable, diffArgs...)
|
||||||
|
beforeCommitID = actualBeforeCommitID
|
||||||
}
|
}
|
||||||
cmd.Dir = repoPath
|
cmd.Dir = repoPath
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
@ -721,6 +861,12 @@ func GetDiffRangeWithWhitespaceBehavior(repoPath, beforeCommitID, afterCommitID
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ParsePatch: %v", err)
|
return nil, fmt.Errorf("ParsePatch: %v", err)
|
||||||
}
|
}
|
||||||
|
for _, diffFile := range diff.Files {
|
||||||
|
tailSection := diffFile.GetTailSection(gitRepo, beforeCommitID, afterCommitID)
|
||||||
|
if tailSection != nil {
|
||||||
|
diffFile.Sections = append(diffFile.Sections, tailSection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err = cmd.Wait(); err != nil {
|
if err = cmd.Wait(); err != nil {
|
||||||
return nil, fmt.Errorf("Wait: %v", err)
|
return nil, fmt.Errorf("Wait: %v", err)
|
||||||
|
@ -76,6 +76,7 @@ func TestRelease_MirrorDelete(t *testing.T) {
|
|||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
||||||
count, err := models.GetReleaseCountByRepoID(mirror.ID, findOptions)
|
count, err := models.GetReleaseCountByRepoID(mirror.ID, findOptions)
|
||||||
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, initCount+1, count)
|
assert.EqualValues(t, initCount+1, count)
|
||||||
|
|
||||||
release, err := models.GetRelease(repo.ID, "v0.2")
|
release, err := models.GetRelease(repo.ID, "v0.2")
|
||||||
@ -86,5 +87,6 @@ func TestRelease_MirrorDelete(t *testing.T) {
|
|||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
||||||
count, err = models.GetReleaseCountByRepoID(mirror.ID, findOptions)
|
count, err = models.GetReleaseCountByRepoID(mirror.ID, findOptions)
|
||||||
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, initCount, count)
|
assert.EqualValues(t, initCount, count)
|
||||||
}
|
}
|
||||||
|
@ -424,8 +424,16 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor
|
|||||||
log.Error("setMerged [%d]: %v", pr.ID, err)
|
log.Error("setMerged [%d]: %v", pr.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = models.MergePullRequestAction(doer, pr.Issue.Repo, pr.Issue); err != nil {
|
if err := models.NotifyWatchers(&models.Action{
|
||||||
log.Error("MergePullRequestAction [%d]: %v", pr.ID, err)
|
ActUserID: doer.ID,
|
||||||
|
ActUser: doer,
|
||||||
|
OpType: models.ActionMergePullRequest,
|
||||||
|
Content: fmt.Sprintf("%d|%s", pr.Issue.Index, pr.Issue.Title),
|
||||||
|
RepoID: pr.Issue.Repo.ID,
|
||||||
|
Repo: pr.Issue.Repo,
|
||||||
|
IsPrivate: pr.Issue.Repo.IsPrivate,
|
||||||
|
}); err != nil {
|
||||||
|
log.Error("NotifyWatchers [%d]: %v", pr.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset cached commit count
|
// Reset cached commit count
|
||||||
|
@ -6,30 +6,144 @@
|
|||||||
package pull
|
package pull
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/notification"
|
"code.gitea.io/gitea/modules/notification"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/services/gitdiff"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateReview creates a new review based on opts
|
// CreateCodeComment creates a comment on the code line
|
||||||
func CreateReview(opts models.CreateReviewOptions) (*models.Review, error) {
|
func CreateCodeComment(doer *models.User, issue *models.Issue, line int64, content string, treePath string, isReview bool, replyReviewID int64) (*models.Comment, error) {
|
||||||
review, err := models.CreateReview(opts)
|
// It's not a review, maybe a reply to a review comment or a single comment.
|
||||||
|
if !isReview {
|
||||||
|
if err := issue.LoadRepo(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
comment, err := createCodeComment(
|
||||||
|
doer,
|
||||||
|
issue.Repo,
|
||||||
|
issue,
|
||||||
|
content,
|
||||||
|
treePath,
|
||||||
|
line,
|
||||||
|
replyReviewID,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.NotifyCreateIssueComment(doer, issue.Repo, issue, comment)
|
||||||
|
|
||||||
|
return comment, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
review, err := models.GetCurrentReview(doer, issue)
|
||||||
|
if err != nil {
|
||||||
|
if !models.IsErrReviewNotExist(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
review, err = models.CreateReview(models.CreateReviewOptions{
|
||||||
|
Type: models.ReviewTypePending,
|
||||||
|
Reviewer: doer,
|
||||||
|
Issue: issue,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comment, err := createCodeComment(
|
||||||
|
doer,
|
||||||
|
issue.Repo,
|
||||||
|
issue,
|
||||||
|
content,
|
||||||
|
treePath,
|
||||||
|
line,
|
||||||
|
review.ID,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
notification.NotifyPullRequestReview(review.Issue.PullRequest, review, nil)
|
// NOTICE: it's a pending review, so the notifications will not be fired until user submit review.
|
||||||
|
|
||||||
return review, nil
|
return comment, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateReview updates a review
|
// createCodeComment creates a plain code comment at the specified line / path
|
||||||
func UpdateReview(review *models.Review) error {
|
func createCodeComment(doer *models.User, repo *models.Repository, issue *models.Issue, content, treePath string, line, reviewID int64) (*models.Comment, error) {
|
||||||
err := models.UpdateReview(review)
|
var commitID, patch string
|
||||||
|
if err := issue.LoadPullRequest(); err != nil {
|
||||||
|
return nil, fmt.Errorf("GetPullRequestByIssueID: %v", err)
|
||||||
|
}
|
||||||
|
pr := issue.PullRequest
|
||||||
|
if err := pr.GetBaseRepo(); err != nil {
|
||||||
|
return nil, fmt.Errorf("GetHeadRepo: %v", err)
|
||||||
|
}
|
||||||
|
gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||||
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
// FIXME validate treePath
|
||||||
|
// Get latest commit referencing the commented line
|
||||||
|
// No need for get commit for base branch changes
|
||||||
|
if line > 0 {
|
||||||
|
commit, err := gitRepo.LineBlame(pr.GetGitRefName(), gitRepo.Path, treePath, uint(line))
|
||||||
|
if err == nil {
|
||||||
|
commitID = commit.ID.String()
|
||||||
|
} else if !strings.Contains(err.Error(), "exit status 128 - fatal: no such path") {
|
||||||
|
return nil, fmt.Errorf("LineBlame[%s, %s, %s, %d]: %v", pr.GetGitRefName(), gitRepo.Path, treePath, line, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
notification.NotifyPullRequestReview(review.Issue.PullRequest, review, nil)
|
// Only fetch diff if comment is review comment
|
||||||
|
if reviewID != 0 {
|
||||||
return nil
|
headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err)
|
||||||
|
}
|
||||||
|
patchBuf := new(bytes.Buffer)
|
||||||
|
if err := gitdiff.GetRawDiffForFile(gitRepo.Path, pr.MergeBase, headCommitID, gitdiff.RawDiffNormal, treePath, patchBuf); err != nil {
|
||||||
|
return nil, fmt.Errorf("GetRawDiffForLine[%s, %s, %s, %s]: %v", err, gitRepo.Path, pr.MergeBase, headCommitID, treePath)
|
||||||
|
}
|
||||||
|
patch = gitdiff.CutDiffAroundLine(patchBuf, int64((&models.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines)
|
||||||
|
}
|
||||||
|
return models.CreateComment(&models.CreateCommentOptions{
|
||||||
|
Type: models.CommentTypeCode,
|
||||||
|
Doer: doer,
|
||||||
|
Repo: repo,
|
||||||
|
Issue: issue,
|
||||||
|
Content: content,
|
||||||
|
LineNum: line,
|
||||||
|
TreePath: treePath,
|
||||||
|
CommitSHA: commitID,
|
||||||
|
ReviewID: reviewID,
|
||||||
|
Patch: patch,
|
||||||
|
NoAction: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist
|
||||||
|
func SubmitReview(doer *models.User, issue *models.Issue, reviewType models.ReviewType, content string) (*models.Review, *models.Comment, error) {
|
||||||
|
review, comm, err := models.SubmitReview(doer, issue, reviewType, content)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pr, err := issue.GetPullRequest()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
notification.NotifyPullRequestReview(pr, review, comm)
|
||||||
|
|
||||||
|
return review, comm, nil
|
||||||
}
|
}
|
||||||
|
16
services/repository/main_test.go
Normal file
16
services/repository/main_test.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
models.MainTest(m, filepath.Join("..", ".."))
|
||||||
|
}
|
54
services/repository/transfer.go
Normal file
54
services/repository/transfer.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/notification"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TransferOwnership transfers all corresponding setting from old user to new one.
|
||||||
|
func TransferOwnership(doer *models.User, newOwnerName string, repo *models.Repository) error {
|
||||||
|
if err := repo.GetOwner(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
oldOwner := repo.Owner
|
||||||
|
|
||||||
|
if err := models.TransferOwnership(doer, newOwnerName, repo); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.NewRepoRedirect(oldOwner.ID, repo.ID, repo.Name, repo.Name); err != nil {
|
||||||
|
return fmt.Errorf("NewRepoRedirect: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.NotifyTransferRepository(doer, repo, oldOwner.Name)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
|
||||||
|
func ChangeRepositoryName(doer *models.User, repo *models.Repository, newRepoName string) error {
|
||||||
|
oldRepoName := repo.Name
|
||||||
|
|
||||||
|
if err := models.ChangeRepositoryName(doer, repo, newRepoName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := repo.GetOwner(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.NewRepoRedirect(repo.Owner.ID, repo.ID, oldRepoName, newRepoName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
notification.NotifyRenameRepository(doer, repo, oldRepoName)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
50
services/repository/transfer_test.go
Normal file
50
services/repository/transfer_test.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/notification"
|
||||||
|
"code.gitea.io/gitea/modules/notification/action"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/unknwon/com"
|
||||||
|
)
|
||||||
|
|
||||||
|
var notifySync sync.Once
|
||||||
|
|
||||||
|
func registerNotifier() {
|
||||||
|
notifySync.Do(func() {
|
||||||
|
notification.RegisterNotifier(action.NewNotifier())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTransferOwnership(t *testing.T) {
|
||||||
|
registerNotifier()
|
||||||
|
|
||||||
|
assert.NoError(t, models.PrepareTestDatabase())
|
||||||
|
|
||||||
|
doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
|
||||||
|
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository)
|
||||||
|
repo.Owner = models.AssertExistsAndLoadBean(t, &models.User{ID: repo.OwnerID}).(*models.User)
|
||||||
|
assert.NoError(t, TransferOwnership(doer, "user2", repo))
|
||||||
|
|
||||||
|
transferredRepo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository)
|
||||||
|
assert.EqualValues(t, 2, transferredRepo.OwnerID)
|
||||||
|
|
||||||
|
assert.False(t, com.IsExist(models.RepoPath("user3", "repo3")))
|
||||||
|
assert.True(t, com.IsExist(models.RepoPath("user2", "repo3")))
|
||||||
|
models.AssertExistsAndLoadBean(t, &models.Action{
|
||||||
|
OpType: models.ActionTransferRepo,
|
||||||
|
ActUserID: 2,
|
||||||
|
RepoID: 3,
|
||||||
|
Content: "user3/repo3",
|
||||||
|
})
|
||||||
|
|
||||||
|
models.CheckConsistencyFor(t, &models.Repository{}, &models.User{}, &models.Team{})
|
||||||
|
}
|
@ -26,7 +26,6 @@
|
|||||||
{{if .RequireGitGraph}}
|
{{if .RequireGitGraph}}
|
||||||
<!-- graph -->
|
<!-- graph -->
|
||||||
<script src="{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js"></script>
|
<script src="{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js"></script>
|
||||||
<script src="{{StaticUrlPrefix}}/js/draw.js"></script>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<!-- Third-party libraries -->
|
<!-- Third-party libraries -->
|
||||||
@ -117,7 +116,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
<script src="{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.min.js"></script>
|
<script src="{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.custom.js"></script>
|
||||||
<script src="{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js"></script>
|
<script src="{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js"></script>
|
||||||
<script src="{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js"></script>
|
<script src="{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js"></script>
|
||||||
|
|
||||||
@ -129,7 +128,7 @@
|
|||||||
<script src="{{StaticUrlPrefix}}/vendor/plugins/moment/moment.min.js" charset="utf-8"></script>
|
<script src="{{StaticUrlPrefix}}/vendor/plugins/moment/moment.min.js" charset="utf-8"></script>
|
||||||
<script src="{{StaticUrlPrefix}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.browser.js" charset="utf-8"></script>
|
<script src="{{StaticUrlPrefix}}/vendor/plugins/vue-calendar-heatmap/vue-calendar-heatmap.browser.js" charset="utf-8"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
initHeatmap('user-heatmap', '{{.HeatmapUser}}');
|
window.initHeatmap('user-heatmap', '{{.HeatmapUser}}');
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{template "custom/footer" .}}
|
{{template "custom/footer" .}}
|
||||||
|
@ -7,11 +7,10 @@ var urlsToCache = [
|
|||||||
'{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/semantic/semantic.min.js',
|
||||||
'{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}',
|
'{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}',
|
||||||
'{{StaticUrlPrefix}}/js/semantic.dropdown.custom.js?v={{MD5 AppVer}}',
|
'{{StaticUrlPrefix}}/js/semantic.dropdown.custom.js?v={{MD5 AppVer}}',
|
||||||
'{{StaticUrlPrefix}}/js/draw.js',
|
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/clipboard/clipboard.min.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/gitgraph/gitgraph.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/vue/vue.min.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/emojify/emojify.custom.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/loadCSS.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/loadCSS.min.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/cssrelpreload/cssrelpreload.min.js',
|
||||||
'{{StaticUrlPrefix}}/vendor/plugins/dropzone/dropzone.js',
|
'{{StaticUrlPrefix}}/vendor/plugins/dropzone/dropzone.js',
|
||||||
|
50
templates/repo/diff/blob_excerpt.tmpl
Normal file
50
templates/repo/diff/blob_excerpt.tmpl
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{{if $.IsSplitStyle}}
|
||||||
|
{{range $k, $line := $.section.Lines}}
|
||||||
|
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
|
||||||
|
{{if eq .GetType 4}}
|
||||||
|
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}">
|
||||||
|
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
|
||||||
|
<i class="ui blob-excerpt fa fa-caret-down" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down" data-anchor="{{$.Anchor}}"></i>
|
||||||
|
{{end}}
|
||||||
|
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
|
||||||
|
<i class="ui blob-excerpt fa fa-caret-up" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up" data-anchor="{{$.Anchor}}"></i>
|
||||||
|
{{end}}
|
||||||
|
{{if or (eq $line.GetExpandDirection 2)}}
|
||||||
|
<i class="ui blob-excerpt octicon octicon-fold" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=" data-anchor="{{$.Anchor}}"></i>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td colspan="5" class="lines-code lines-code-old "><span class="mono wrap{{if $.highlightClass}} language-{{$.highlightClass}}{{else}} nohighlight{{end}}">{{$.section.GetComputedInlineDiffFor $line}}</span></td>
|
||||||
|
{{else}}
|
||||||
|
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $.fileName}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
||||||
|
<td class="blob-excerpt lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="mono" data-type-marker=""></span>{{end}}</td>
|
||||||
|
<td class="blob-excerpt lines-code lines-code-old halfwidth"><span class="mono wrap{{if $.highlightClass}} language-{{$.highlightClass}}{{else}} nohighlight{{end}}">{{if $line.LeftIdx}}{{$.section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
||||||
|
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $.fileName}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||||
|
<td class="blob-excerpt lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="mono" data-type-marker=""></span>{{end}}</td>
|
||||||
|
<td class="blob-excerpt lines-code lines-code-new halfwidth"><span class="mono wrap{{if $.highlightClass}} language-{{$.highlightClass}}{{else}} nohighlight{{end}}">{{if $line.RightIdx}}{{$.section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
||||||
|
{{end}}
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{else}}
|
||||||
|
{{range $k, $line := $.section.Lines}}
|
||||||
|
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
|
||||||
|
{{if eq .GetType 4}}
|
||||||
|
<td colspan="2" class="lines-num">
|
||||||
|
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
|
||||||
|
<i class="ui blob-excerpt fa fa-caret-up" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up" data-anchor="{{$.Anchor}}"></i>
|
||||||
|
{{end}}
|
||||||
|
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
|
||||||
|
<i class="ui blob-excerpt fa fa-caret-down" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down" data-anchor="{{$.Anchor}}"></i>
|
||||||
|
{{end}}
|
||||||
|
{{if or (eq $line.GetExpandDirection 2)}}
|
||||||
|
<i class="ui blob-excerpt octicon octicon-fold" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=" data-anchor="{{$.Anchor}}"></i>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
{{else}}
|
||||||
|
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $.fileName}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
||||||
|
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $.fileName}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||||
|
{{end}}
|
||||||
|
<td class="blob-excerpt lines-type-marker"><span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span></td>
|
||||||
|
<td class="blob-excerpt lines-code{{if (not $line.RightIdx)}} lines-code-old{{end}}"><span class="mono wrap{{if $.highlightClass}} language-{{$.highlightClass}}{{else}} nohighlight{{end}}">{{$.section.GetComputedInlineDiffFor $line}}</span></td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
@ -81,6 +81,15 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}}" id="diff-{{.Index}}">
|
<div class="diff-file-box diff-box file-content {{TabSizeClass $.Editorconfig $file.Name}}" id="diff-{{.Index}}">
|
||||||
<h4 class="ui top attached normal header">
|
<h4 class="ui top attached normal header">
|
||||||
|
{{$isImage := false}}
|
||||||
|
{{if $file.IsDeleted}}
|
||||||
|
{{$isImage = (call $.IsImageFileInBase $file.Name)}}
|
||||||
|
{{else}}
|
||||||
|
{{$isImage = (call $.IsImageFileInHead $file.Name)}}
|
||||||
|
{{end}}
|
||||||
|
{{if or (not $file.IsBin) $isImage}}
|
||||||
|
<i class="ui fold-code grey fa fa-chevron-down"></i>
|
||||||
|
{{end}}
|
||||||
<div class="diff-counter count">
|
<div class="diff-counter count">
|
||||||
{{if $file.IsBin}}
|
{{if $file.IsBin}}
|
||||||
{{$.i18n.Tr "repo.diff.bin"}}
|
{{$.i18n.Tr "repo.diff.bin"}}
|
||||||
@ -104,12 +113,6 @@
|
|||||||
</h4>
|
</h4>
|
||||||
<div class="ui attached unstackable table segment">
|
<div class="ui attached unstackable table segment">
|
||||||
{{if ne $file.Type 4}}
|
{{if ne $file.Type 4}}
|
||||||
{{$isImage := false}}
|
|
||||||
{{if $file.IsDeleted}}
|
|
||||||
{{$isImage = (call $.IsImageFileInBase $file.Name)}}
|
|
||||||
{{else}}
|
|
||||||
{{$isImage = (call $.IsImageFileInHead $file.Name)}}
|
|
||||||
{{end}}
|
|
||||||
<div class="file-body file-code code-view code-diff {{if $.IsSplitStyle}}code-diff-split{{else}}code-diff-unified{{end}}">
|
<div class="file-body file-code code-view code-diff {{if $.IsSplitStyle}}code-diff-split{{else}}code-diff-unified{{end}}">
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -121,12 +124,27 @@
|
|||||||
{{range $j, $section := $file.Sections}}
|
{{range $j, $section := $file.Sections}}
|
||||||
{{range $k, $line := $section.Lines}}
|
{{range $k, $line := $section.Lines}}
|
||||||
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
|
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
|
||||||
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
{{if eq .GetType 4}}
|
||||||
<td class="lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
|
<td class="lines-num lines-num-old">
|
||||||
<td class="lines-code lines-code-old halfwidth">{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}<a class="ui green button add-code-comment add-code-comment-left" data-path="{{$file.Name}}" data-side="left" data-idx="{{$line.LeftIdx}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
|
||||||
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}"></span></td>
|
<i class="ui blob-excerpt fa fa-caret-down" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=down" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}"></i>
|
||||||
<td class="lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
|
{{end}}
|
||||||
<td class="lines-code lines-code-new halfwidth">{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}<a class="ui green button add-code-comment add-code-comment-right" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
|
||||||
|
<i class="ui blob-excerpt fa fa-caret-up" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=up" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}"></i>
|
||||||
|
{{end}}
|
||||||
|
{{if or (eq $line.GetExpandDirection 2)}}
|
||||||
|
<i class="ui blob-excerpt octicon octicon-fold" data-url="{{$.RepoLink}}/blob_excerpt/{{$.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=split&direction=" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}"></i>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td colspan="5" class="lines-code lines-code-old "><span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{$section.GetComputedInlineDiffFor $line}}</span></td>
|
||||||
|
{{else}}
|
||||||
|
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
||||||
|
<td class="lines-type-marker lines-type-marker-old">{{if $line.LeftIdx}}<span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
|
||||||
|
<td class="lines-code lines-code-old halfwidth">{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 2))}}<a class="ui green button add-code-comment add-code-comment-left" data-path="{{$file.Name}}" data-side="left" data-idx="{{$line.LeftIdx}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{if $line.LeftIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
||||||
|
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||||
|
<td class="lines-type-marker lines-type-marker-new">{{if $line.RightIdx}}<span class="mono" data-type-marker="{{$line.GetLineTypeMarker}}"></span>{{end}}</td>
|
||||||
|
<td class="lines-code lines-code-new halfwidth">{{if and $.SignedUserID $line.CanComment $.PageIsPullFiles (not (eq .GetType 3))}}<a class="ui green button add-code-comment add-code-comment-right" data-path="{{$file.Name}}" data-side="right" data-idx="{{$line.RightIdx}}">+</a>{{end}}<span class="mono wrap{{if $highlightClass}} language-{{$highlightClass}}{{else}} nohighlight{{end}}">{{if $line.RightIdx}}{{$section.GetComputedInlineDiffFor $line}}{{end}}</span></td>
|
||||||
|
{{end}}
|
||||||
</tr>
|
</tr>
|
||||||
{{if gt (len $line.Comments) 0}}
|
{{if gt (len $line.Comments) 0}}
|
||||||
<tr class="add-code-comment">
|
<tr class="add-code-comment">
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if or (not $.HasComments) $.hidden}}
|
{{if or (not $.HasComments) $.hidden}}
|
||||||
<button type="button" class="ui submit tiny basic button btn-cancel" onclick="cancelCodeComment(this);">{{$.root.i18n.Tr "cancel"}}</button>
|
<button type="button" class="ui submit tiny basic button btn-cancel" onclick="window.cancelCodeComment(this);">{{$.root.i18n.Tr "cancel"}}</button>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,9 +4,17 @@
|
|||||||
{{range $k, $line := $section.Lines}}
|
{{range $k, $line := $section.Lines}}
|
||||||
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
|
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
|
||||||
{{if eq .GetType 4}}
|
{{if eq .GetType 4}}
|
||||||
<td colspan="2" class="lines-num">
|
<td colspan="2" class="lines-num">
|
||||||
{{/* {{if gt $j 0}}<span class="fold octicon octicon-fold"></span>{{end}} */}}
|
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5) }}
|
||||||
</td>
|
<i class="ui blob-excerpt fa fa-caret-down" data-url="{{$.root.RepoLink}}/blob_excerpt/{{$.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=down" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}"></i>
|
||||||
|
{{end}}
|
||||||
|
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 4) }}
|
||||||
|
<i class="ui blob-excerpt fa fa-caret-up" data-url="{{$.root.RepoLink}}/blob_excerpt/{{$.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=up" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}"></i>
|
||||||
|
{{end}}
|
||||||
|
{{if or (eq $line.GetExpandDirection 2)}}
|
||||||
|
<i class="ui blob-excerpt octicon octicon-fold" data-url="{{$.root.RepoLink}}/blob_excerpt/{{$.root.AfterCommitID}}" data-query="{{$line.GetBlobExcerptQuery}}&style=unified&direction=" data-anchor="diff-{{Sha1 $file.Name}}K{{$line.SectionInfo.RightIdx}}"></i>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
{{else}}
|
{{else}}
|
||||||
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}"><span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}"></span></td>
|
||||||
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}"></span></td>
|
<td class="lines-num lines-num-new" data-line-num="{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}"><span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}"></span></td>
|
||||||
|
@ -155,8 +155,8 @@
|
|||||||
</form>
|
</form>
|
||||||
{{if $.IsStopwatchRunning}}
|
{{if $.IsStopwatchRunning}}
|
||||||
<div class="ui buttons fluid stop-cancel">
|
<div class="ui buttons fluid stop-cancel">
|
||||||
<button onclick="this.disabled=true;toggleStopwatch()" class="ui button stop">{{.i18n.Tr "repo.issues.stop_tracking"}}</button>
|
<button onclick="this.disabled=true;window.toggleStopwatch()" class="ui button stop">{{.i18n.Tr "repo.issues.stop_tracking"}}</button>
|
||||||
<button onclick="this.disabled=true;cancelStopwatch()" class="ui negative button cancel">{{.i18n.Tr "repo.issues.cancel_tracking"}}</button>
|
<button onclick="this.disabled=true;window.cancelStopwatch()" class="ui negative button cancel">{{.i18n.Tr "repo.issues.cancel_tracking"}}</button>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{if .HasUserStopwatch}}
|
{{if .HasUserStopwatch}}
|
||||||
@ -165,8 +165,8 @@
|
|||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="ui buttons two fluid start-add">
|
<div class="ui buttons two fluid start-add">
|
||||||
<button onclick="this.disabled=true;toggleStopwatch()" class="ui button poping up start" data-content='{{.i18n.Tr "repo.issues.start_tracking"}}' data-position="top center" data-variation="small inverted">{{.i18n.Tr "repo.issues.start_tracking_short"}}</button>
|
<button onclick="this.disabled=true;window.toggleStopwatch()" class="ui button poping up start" data-content='{{.i18n.Tr "repo.issues.start_tracking"}}' data-position="top center" data-variation="small inverted">{{.i18n.Tr "repo.issues.start_tracking_short"}}</button>
|
||||||
<button onclick="timeAddManual()" class="ui button green poping up add-time" data-content='{{.i18n.Tr "repo.issues.add_time"}}' data-position="top center" data-variation="small inverted">{{.i18n.Tr "repo.issues.add_time_short"}}</button>
|
<button onclick="window.timeAddManual()" class="ui button green poping up add-time" data-content='{{.i18n.Tr "repo.issues.add_time"}}' data-position="top center" data-variation="small inverted">{{.i18n.Tr "repo.issues.add_time_short"}}</button>
|
||||||
<div class="ui mini modal">
|
<div class="ui mini modal">
|
||||||
<div class="header">{{.i18n.Tr "repo.issues.add_time"}}</div>
|
<div class="header">{{.i18n.Tr "repo.issues.add_time"}}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@ -225,8 +225,8 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
{{if and .IsIssueWriter (not .Repository.IsArchived)}}
|
{{if and .IsIssueWriter (not .Repository.IsArchived)}}
|
||||||
<br/>
|
<br/>
|
||||||
<a style="cursor:pointer;" onclick="toggleDeadlineForm();"><i class="edit icon"></i>{{$.i18n.Tr "repo.issues.due_date_form_edit"}}</a> -
|
<a style="cursor:pointer;" onclick="window.toggleDeadlineForm();"><i class="edit icon"></i>{{$.i18n.Tr "repo.issues.due_date_form_edit"}}</a> -
|
||||||
<a style="cursor:pointer;" onclick="updateDeadline('');"><i class="remove icon"></i>{{$.i18n.Tr "repo.issues.due_date_form_remove"}}</a>
|
<a style="cursor:pointer;" onclick="window.updateDeadline('');"><i class="remove icon"></i>{{$.i18n.Tr "repo.issues.due_date_form_remove"}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</p>
|
</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
@ -235,7 +235,7 @@
|
|||||||
|
|
||||||
{{if and .IsIssueWriter (not .Repository.IsArchived)}}
|
{{if and .IsIssueWriter (not .Repository.IsArchived)}}
|
||||||
<div {{if ne .Issue.DeadlineUnix 0}} style="display: none;"{{end}} id="deadlineForm">
|
<div {{if ne .Issue.DeadlineUnix 0}} style="display: none;"{{end}} id="deadlineForm">
|
||||||
<form class="ui fluid action input" action="{{AppSubUrl}}/api/v1/repos/{{.Repository.Owner.Name}}/{{.Repository.Name}}/issues/{{.Issue.Index}}" method="post" id="update-issue-deadline-form" onsubmit="setDeadline();return false;">
|
<form class="ui fluid action input" action="{{AppSubUrl}}/api/v1/repos/{{.Repository.Owner.Name}}/{{.Repository.Name}}/issues/{{.Issue.Index}}" method="post" id="update-issue-deadline-form" onsubmit="window.setDeadline();return false;">
|
||||||
{{$.CsrfTokenHtml}}
|
{{$.CsrfTokenHtml}}
|
||||||
<input required placeholder="{{.i18n.Tr "repo.issues.due_date_form"}}" {{if gt .Issue.DeadlineUnix 0}}value="{{.Issue.DeadlineUnix.Format "2006-01-02"}}"{{end}} type="date" name="deadlineDate" id="deadlineDate">
|
<input required placeholder="{{.i18n.Tr "repo.issues.due_date_form"}}" {{if gt .Issue.DeadlineUnix 0}}value="{{.Issue.DeadlineUnix.Format "2006-01-02"}}"{{end}} type="date" name="deadlineDate" id="deadlineDate">
|
||||||
<button class="ui green icon button">
|
<button class="ui green icon button">
|
||||||
@ -280,7 +280,7 @@
|
|||||||
<div class="text small">{{.Repository.OwnerName}}/{{.Repository.Name}}</div>
|
<div class="text small">{{.Repository.OwnerName}}/{{.Repository.Name}}</div>
|
||||||
<div class="ui transparent label right floated nopadding">
|
<div class="ui transparent label right floated nopadding">
|
||||||
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}}
|
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}}
|
||||||
<a class="delete-dependency-button" onclick="deleteDependencyModal({{.Issue.ID}}, 'blocking');"
|
<a class="delete-dependency-button" onclick="window.deleteDependencyModal({{.Issue.ID}}, 'blocking');"
|
||||||
data-tooltip="{{$.i18n.Tr "repo.issues.dependency.remove_info"}}" data-inverted="">
|
data-tooltip="{{$.i18n.Tr "repo.issues.dependency.remove_info"}}" data-inverted="">
|
||||||
<i class="delete icon text red nopadding nomargin"></i>
|
<i class="delete icon text red nopadding nomargin"></i>
|
||||||
</a>
|
</a>
|
||||||
@ -307,7 +307,7 @@
|
|||||||
<div class="text small">{{.Repository.OwnerName}}/{{.Repository.Name}}</div>
|
<div class="text small">{{.Repository.OwnerName}}/{{.Repository.Name}}</div>
|
||||||
<div class="ui transparent label right floated nopadding">
|
<div class="ui transparent label right floated nopadding">
|
||||||
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}}
|
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}}
|
||||||
<a class="delete-dependency-button" onclick="deleteDependencyModal({{.Issue.ID}}, 'blockedBy');"
|
<a class="delete-dependency-button" onclick="window.deleteDependencyModal({{.Issue.ID}}, 'blockedBy');"
|
||||||
data-tooltip="{{$.i18n.Tr "repo.issues.dependency.remove_info"}}" data-inverted="">
|
data-tooltip="{{$.i18n.Tr "repo.issues.dependency.remove_info"}}" data-inverted="">
|
||||||
<i class="delete icon text red nopadding nomargin"></i>
|
<i class="delete icon text red nopadding nomargin"></i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
title="{{$provider.DisplayName}}{{if eq $provider.Name "openidConnect"}} ({{$key}}){{end}}"
|
title="{{$provider.DisplayName}}{{if eq $provider.Name "openidConnect"}} ({{$key}}){{end}}"
|
||||||
class="{{$provider.Name}}"
|
class="{{$provider.Name}}"
|
||||||
src="{{AppSubUrl}}{{$provider.Image}}"
|
src="{{AppSubUrl}}{{$provider.Image}}"
|
||||||
onclick="onOAuthLoginClick()"
|
onclick="window.onOAuthLoginClick()"
|
||||||
></a>
|
></a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -61,6 +61,12 @@
|
|||||||
{{$.i18n.Tr "action.mirror_sync_create" .GetRepoLink .GetBranch .ShortRepoPath | Str2html}}
|
{{$.i18n.Tr "action.mirror_sync_create" .GetRepoLink .GetBranch .ShortRepoPath | Str2html}}
|
||||||
{{else if eq .GetOpType 20}}
|
{{else if eq .GetOpType 20}}
|
||||||
{{$.i18n.Tr "action.mirror_sync_delete" .GetRepoLink .GetBranch .ShortRepoPath | Str2html}}
|
{{$.i18n.Tr "action.mirror_sync_delete" .GetRepoLink .GetBranch .ShortRepoPath | Str2html}}
|
||||||
|
{{else if eq .GetOpType 21}}
|
||||||
|
{{ $index := index .GetIssueInfos 0}}
|
||||||
|
{{$.i18n.Tr "action.approve_pull_request" .GetRepoLink $index .ShortRepoPath | Str2html}}
|
||||||
|
{{else if eq .GetOpType 22}}
|
||||||
|
{{ $index := index .GetIssueInfos 0}}
|
||||||
|
{{$.i18n.Tr "action.reject_pull_request" .GetRepoLink $index .ShortRepoPath | Str2html}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</p>
|
</p>
|
||||||
{{if or (eq .GetOpType 5) (eq .GetOpType 18)}}
|
{{if or (eq .GetOpType 5) (eq .GetOpType 18)}}
|
||||||
@ -80,7 +86,7 @@
|
|||||||
<span class="text truncate issue title has-emoji">{{index .GetIssueInfos 1}}</span>
|
<span class="text truncate issue title has-emoji">{{index .GetIssueInfos 1}}</span>
|
||||||
{{else if eq .GetOpType 7}}
|
{{else if eq .GetOpType 7}}
|
||||||
<span class="text truncate issue title has-emoji">{{index .GetIssueInfos 1}}</span>
|
<span class="text truncate issue title has-emoji">{{index .GetIssueInfos 1}}</span>
|
||||||
{{else if eq .GetOpType 10}}
|
{{else if or (eq .GetOpType 10) (eq .GetOpType 21) (eq .GetOpType 22)}}
|
||||||
<a href="{{.GetCommentLink}}" class="text truncate issue title has-emoji">{{.GetIssueTitle}}</a>
|
<a href="{{.GetCommentLink}}" class="text truncate issue title has-emoji">{{.GetIssueTitle}}</a>
|
||||||
<p class="text light grey has-emoji">{{index .GetIssueInfos 1}}</p>
|
<p class="text light grey has-emoji">{{index .GetIssueInfos 1}}</p>
|
||||||
{{else if eq .GetOpType 11}}
|
{{else if eq .GetOpType 11}}
|
||||||
|
15
web_src/js/draw.js
Normal file
15
web_src/js/draw.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* globals gitGraph */
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
const graphList = [];
|
||||||
|
|
||||||
|
if (!document.getElementById('graph-canvas')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#graph-raw-list li span.node-relation').each(function () {
|
||||||
|
graphList.push($(this).text());
|
||||||
|
});
|
||||||
|
|
||||||
|
gitGraph(document.getElementById('graph-canvas'), graphList);
|
||||||
|
});
|
3309
web_src/js/index.js
Normal file
3309
web_src/js/index.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -2438,6 +2438,10 @@ tbody.commit-list {
|
|||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td.blob-excerpt {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
.issue-keyword {
|
.issue-keyword {
|
||||||
border-bottom: 1px dotted #959da5;
|
border-bottom: 1px dotted #959da5;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -108,3 +108,26 @@
|
|||||||
font: 12px @monospaced-fonts, monospace;
|
font: 12px @monospaced-fonts, monospace;
|
||||||
color: rgba(0, 0, 0, 0.87);
|
color: rgba(0, 0, 0, 0.87);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ui.fold-code {
|
||||||
|
margin-right: 1em;
|
||||||
|
padding-left: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 22px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.fold-code:hover {
|
||||||
|
color: #428bca;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.blob-excerpt {
|
||||||
|
display: block;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui.blob-excerpt:hover {
|
||||||
|
color: #428bca;
|
||||||
|
}
|
||||||
|
42
webpack.config.js
Normal file
42
webpack.config.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: 'production',
|
||||||
|
entry: {
|
||||||
|
index: ['./web_src/js/index', './web_src/js/draw']
|
||||||
|
},
|
||||||
|
devtool: 'source-map',
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'public/js'),
|
||||||
|
filename: 'index.js'
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
minimize: true,
|
||||||
|
minimizer: [new TerserPlugin({
|
||||||
|
sourceMap: true,
|
||||||
|
})],
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
'@babel/preset-env',
|
||||||
|
{
|
||||||
|
useBuiltIns: 'entry',
|
||||||
|
corejs: 3,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user