forked from Gitlink/gitea-1120-rc1
FIX merge upsteam master branch
This commit is contained in:
commit
1e82b5adb8
|
@ -0,0 +1,9 @@
|
||||||
|
root = "."
|
||||||
|
tmp_dir = ".air"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
cmd = "make backend"
|
||||||
|
bin = "gitea"
|
||||||
|
include_ext = ["go", "tmpl"]
|
||||||
|
exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata"]
|
||||||
|
include_dir = ["cmd", "models", "modules", "options", "routers", "services", "templates"]
|
|
@ -154,7 +154,7 @@ steps:
|
||||||
|
|
||||||
- name: tag-pre-condition
|
- name: tag-pre-condition
|
||||||
pull: always
|
pull: always
|
||||||
image: alpine/git
|
image: drone/git
|
||||||
commands:
|
commands:
|
||||||
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
|
- git update-ref refs/heads/tag_test ${DRONE_COMMIT_SHA}
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ steps:
|
||||||
|
|
||||||
- name: update
|
- name: update
|
||||||
pull: default
|
pull: default
|
||||||
image: alpine:3.11
|
image: alpine:3.12
|
||||||
commands:
|
commands:
|
||||||
- ./build/update-locales.sh
|
- ./build/update-locales.sh
|
||||||
|
|
||||||
|
|
|
@ -23,3 +23,6 @@ indent_size = 2
|
||||||
|
|
||||||
[Makefile]
|
[Makefile]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.svg]
|
||||||
|
insert_final_newline = false
|
||||||
|
|
333
.eslintrc
333
.eslintrc
|
@ -1,15 +1,17 @@
|
||||||
root: true
|
root: true
|
||||||
|
reportUnusedDisableDirectives: true
|
||||||
extends:
|
|
||||||
- eslint-config-airbnb-base
|
|
||||||
- eslint:recommended
|
|
||||||
|
|
||||||
ignorePatterns:
|
ignorePatterns:
|
||||||
- /web_src/js/vendor
|
- /web_src/js/vendor
|
||||||
|
|
||||||
parserOptions:
|
parserOptions:
|
||||||
|
sourceType: module
|
||||||
ecmaVersion: 2020
|
ecmaVersion: 2020
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- eslint-plugin-unicorn
|
||||||
|
- eslint-plugin-import
|
||||||
|
|
||||||
env:
|
env:
|
||||||
browser: true
|
browser: true
|
||||||
es6: true
|
es6: true
|
||||||
|
@ -25,48 +27,361 @@ globals:
|
||||||
Tribute: false
|
Tribute: false
|
||||||
|
|
||||||
overrides:
|
overrides:
|
||||||
- files: ["web_src/**/*.worker.js"]
|
- files: ["web_src/**/*worker.js"]
|
||||||
env:
|
env:
|
||||||
worker: true
|
worker: true
|
||||||
rules:
|
rules:
|
||||||
no-restricted-globals: [0]
|
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top]
|
||||||
|
- files: ["build/generate-images.js"]
|
||||||
|
rules:
|
||||||
|
import/no-unresolved: [0]
|
||||||
|
import/no-extraneous-dependencies: [0]
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
|
accessor-pairs: [2]
|
||||||
|
array-bracket-newline: [0]
|
||||||
|
array-bracket-spacing: [2, never]
|
||||||
|
array-callback-return: [0]
|
||||||
|
array-element-newline: [0]
|
||||||
arrow-body-style: [0]
|
arrow-body-style: [0]
|
||||||
arrow-parens: [2, always]
|
arrow-parens: [2, always]
|
||||||
|
arrow-spacing: [2, {before: true, after: true}]
|
||||||
|
block-scoped-var: [2]
|
||||||
|
brace-style: [2, 1tbs, {allowSingleLine: true}]
|
||||||
camelcase: [0]
|
camelcase: [0]
|
||||||
|
capitalized-comments: [0]
|
||||||
|
class-methods-use-this: [0]
|
||||||
comma-dangle: [2, only-multiline]
|
comma-dangle: [2, only-multiline]
|
||||||
|
comma-spacing: [2, {before: false, after: true}]
|
||||||
|
comma-style: [2, last]
|
||||||
|
complexity: [0]
|
||||||
|
computed-property-spacing: [2, never]
|
||||||
consistent-return: [0]
|
consistent-return: [0]
|
||||||
|
consistent-this: [0]
|
||||||
|
constructor-super: [2]
|
||||||
|
curly: [0]
|
||||||
|
default-case-last: [2]
|
||||||
default-case: [0]
|
default-case: [0]
|
||||||
|
default-param-last: [0]
|
||||||
|
dot-location: [2, property]
|
||||||
|
dot-notation: [0]
|
||||||
|
eol-last: [2]
|
||||||
|
eqeqeq: [2]
|
||||||
|
for-direction: [2]
|
||||||
|
func-call-spacing: [2, never]
|
||||||
|
func-name-matching: [2]
|
||||||
func-names: [0]
|
func-names: [0]
|
||||||
|
func-style: [0]
|
||||||
|
function-call-argument-newline: [0]
|
||||||
|
function-paren-newline: [0]
|
||||||
|
generator-star-spacing: [0]
|
||||||
|
getter-return: [2]
|
||||||
|
grouped-accessor-pairs: [2]
|
||||||
|
guard-for-in: [0]
|
||||||
|
id-blacklist: [0]
|
||||||
|
id-length: [0]
|
||||||
|
id-match: [0]
|
||||||
|
implicit-arrow-linebreak: [0]
|
||||||
|
import/default: [0]
|
||||||
|
import/dynamic-import-chunkname: [0]
|
||||||
|
import/export: [2]
|
||||||
|
import/exports-last: [0]
|
||||||
import/extensions: [2, always, {ignorePackages: true}]
|
import/extensions: [2, always, {ignorePackages: true}]
|
||||||
|
import/first: [2]
|
||||||
|
import/group-exports: [0]
|
||||||
|
import/max-dependencies: [0]
|
||||||
|
import/named: [2]
|
||||||
|
import/namespace: [0]
|
||||||
|
import/newline-after-import: [0]
|
||||||
|
import/no-absolute-path: [0]
|
||||||
|
import/no-amd: [0]
|
||||||
|
import/no-anonymous-default-export: [0]
|
||||||
|
import/no-commonjs: [0]
|
||||||
|
import/no-cycle: [0]
|
||||||
|
import/no-default-export: [0]
|
||||||
|
import/no-deprecated: [0]
|
||||||
|
import/no-dynamic-require: [0]
|
||||||
|
import/no-extraneous-dependencies: [2]
|
||||||
|
import/no-internal-modules: [0]
|
||||||
|
import/no-mutable-exports: [2]
|
||||||
|
import/no-named-as-default-member: [0]
|
||||||
|
import/no-named-as-default: [2]
|
||||||
|
import/no-named-default: [0]
|
||||||
|
import/no-named-export: [0]
|
||||||
|
import/no-namespace: [0]
|
||||||
|
import/no-nodejs-modules: [0]
|
||||||
|
import/no-relative-parent-imports: [0]
|
||||||
|
import/no-restricted-paths: [0]
|
||||||
|
import/no-self-import: [2]
|
||||||
|
import/no-unassigned-import: [0]
|
||||||
|
import/no-unresolved: [2, {commonjs: true}]
|
||||||
|
import/no-unused-modules: [0]
|
||||||
|
import/no-useless-path-segments: [2, {commonjs: true}]
|
||||||
|
import/no-webpack-loader-syntax: [2]
|
||||||
|
import/order: [0]
|
||||||
import/prefer-default-export: [0]
|
import/prefer-default-export: [0]
|
||||||
|
import/unambiguous: [0]
|
||||||
|
indent: [2, 2, {SwitchCase: 1}]
|
||||||
|
init-declarations: [0]
|
||||||
|
key-spacing: [2]
|
||||||
|
keyword-spacing: [2]
|
||||||
|
line-comment-position: [0]
|
||||||
|
linebreak-style: [2, unix]
|
||||||
|
lines-around-comment: [0]
|
||||||
|
lines-between-class-members: [0]
|
||||||
|
max-classes-per-file: [0]
|
||||||
|
max-depth: [0]
|
||||||
max-len: [0]
|
max-len: [0]
|
||||||
|
max-lines-per-function: [0]
|
||||||
|
max-lines: [0]
|
||||||
|
max-nested-callbacks: [0]
|
||||||
|
max-params: [0]
|
||||||
|
max-statements-per-line: [0]
|
||||||
|
max-statements: [0]
|
||||||
multiline-comment-style: [2, separate-lines]
|
multiline-comment-style: [2, separate-lines]
|
||||||
|
multiline-ternary: [0]
|
||||||
|
new-cap: [0]
|
||||||
|
new-parens: [2]
|
||||||
newline-per-chained-call: [0]
|
newline-per-chained-call: [0]
|
||||||
no-alert: [0]
|
no-alert: [0]
|
||||||
|
no-array-constructor: [2]
|
||||||
|
no-async-promise-executor: [2]
|
||||||
|
no-await-in-loop: [0]
|
||||||
|
no-bitwise: [0]
|
||||||
|
no-buffer-constructor: [0]
|
||||||
|
no-caller: [2]
|
||||||
|
no-case-declarations: [2]
|
||||||
|
no-class-assign: [2]
|
||||||
|
no-compare-neg-zero: [2]
|
||||||
no-cond-assign: [2, except-parens]
|
no-cond-assign: [2, except-parens]
|
||||||
|
no-confusing-arrow: [0]
|
||||||
no-console: [1, {allow: [info, warn, error]}]
|
no-console: [1, {allow: [info, warn, error]}]
|
||||||
|
no-const-assign: [2]
|
||||||
|
no-constant-condition: [0]
|
||||||
|
no-constructor-return: [2]
|
||||||
no-continue: [0]
|
no-continue: [0]
|
||||||
|
no-control-regex: [0]
|
||||||
|
no-debugger: [1]
|
||||||
|
no-delete-var: [2]
|
||||||
|
no-div-regex: [0]
|
||||||
|
no-dupe-args: [2]
|
||||||
|
no-dupe-class-members: [2]
|
||||||
|
no-dupe-else-if: [2]
|
||||||
|
no-dupe-keys: [2]
|
||||||
|
no-duplicate-case: [2]
|
||||||
|
no-duplicate-imports: [2]
|
||||||
|
no-else-return: [2]
|
||||||
|
no-empty-character-class: [2]
|
||||||
|
no-empty-function: [0]
|
||||||
|
no-empty-pattern: [2]
|
||||||
|
no-empty: [2, {allowEmptyCatch: true}]
|
||||||
no-eq-null: [2]
|
no-eq-null: [2]
|
||||||
|
no-eval: [2]
|
||||||
|
no-ex-assign: [2]
|
||||||
|
no-extend-native: [2]
|
||||||
|
no-extra-bind: [2]
|
||||||
|
no-extra-boolean-cast: [2]
|
||||||
|
no-extra-label: [0]
|
||||||
|
no-extra-parens: [0]
|
||||||
|
no-extra-semi: [2]
|
||||||
|
no-fallthrough: [2]
|
||||||
|
no-floating-decimal: [0]
|
||||||
|
no-func-assign: [2]
|
||||||
|
no-global-assign: [2]
|
||||||
|
no-implicit-coercion: [0]
|
||||||
|
no-implicit-globals: [0]
|
||||||
|
no-implied-eval: [2]
|
||||||
|
no-import-assign: [2]
|
||||||
|
no-inline-comments: [0]
|
||||||
|
no-inner-declarations: [2]
|
||||||
|
no-invalid-regexp: [2]
|
||||||
|
no-invalid-this: [0]
|
||||||
|
no-irregular-whitespace: [2]
|
||||||
|
no-iterator: [2]
|
||||||
|
no-label-var: [2]
|
||||||
|
no-labels: [2]
|
||||||
|
no-lone-blocks: [2]
|
||||||
|
no-lonely-if: [0]
|
||||||
|
no-loop-func: [0]
|
||||||
|
no-loss-of-precision: [2]
|
||||||
|
no-magic-numbers: [0]
|
||||||
|
no-misleading-character-class: [2]
|
||||||
no-mixed-operators: [0]
|
no-mixed-operators: [0]
|
||||||
|
no-mixed-spaces-and-tabs: [2]
|
||||||
no-multi-assign: [0]
|
no-multi-assign: [0]
|
||||||
|
no-multi-spaces: [2, {ignoreEOLComments: true, exceptions: {Property: true, VariableDeclarator: true}}]
|
||||||
|
no-multi-str: [2]
|
||||||
|
no-negated-condition: [0]
|
||||||
|
no-nested-ternary: [0]
|
||||||
|
no-new-func: [2]
|
||||||
|
no-new-object: [2]
|
||||||
|
no-new-symbol: [2]
|
||||||
|
no-new-wrappers: [2]
|
||||||
no-new: [0]
|
no-new: [0]
|
||||||
|
no-obj-calls: [2]
|
||||||
|
no-octal-escape: [2]
|
||||||
|
no-octal: [2]
|
||||||
no-param-reassign: [0]
|
no-param-reassign: [0]
|
||||||
no-plusplus: [0]
|
no-plusplus: [0]
|
||||||
no-restricted-syntax: [0]
|
no-promise-executor-return: [0]
|
||||||
|
no-proto: [2]
|
||||||
|
no-prototype-builtins: [2]
|
||||||
|
no-redeclare: [2]
|
||||||
|
no-regex-spaces: [2]
|
||||||
|
no-restricted-exports: [0]
|
||||||
|
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top]
|
||||||
|
no-restricted-imports: [0]
|
||||||
|
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement]
|
||||||
|
no-return-assign: [0]
|
||||||
no-return-await: [0]
|
no-return-await: [0]
|
||||||
|
no-script-url: [2]
|
||||||
|
no-self-assign: [2, {props: true}]
|
||||||
|
no-self-compare: [2]
|
||||||
|
no-sequences: [2]
|
||||||
|
no-setter-return: [2]
|
||||||
|
no-shadow-restricted-names: [2]
|
||||||
no-shadow: [0]
|
no-shadow: [0]
|
||||||
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}]
|
no-sparse-arrays: [2]
|
||||||
no-use-before-define: [0]
|
no-tabs: [2]
|
||||||
|
no-template-curly-in-string: [2]
|
||||||
|
no-ternary: [0]
|
||||||
|
no-this-before-super: [2]
|
||||||
|
no-throw-literal: [2]
|
||||||
|
no-trailing-spaces: [2]
|
||||||
|
no-undef-init: [2]
|
||||||
|
no-undef: [2, {typeof: true}]
|
||||||
|
no-undefined: [0]
|
||||||
|
no-underscore-dangle: [0]
|
||||||
|
no-unexpected-multiline: [2]
|
||||||
|
no-unmodified-loop-condition: [2]
|
||||||
|
no-unneeded-ternary: [0]
|
||||||
|
no-unreachable-loop: [2]
|
||||||
|
no-unreachable: [2]
|
||||||
|
no-unsafe-finally: [2]
|
||||||
|
no-unsafe-negation: [2]
|
||||||
|
no-unused-expressions: [2]
|
||||||
|
no-unused-labels: [2]
|
||||||
|
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, ignoreRestSiblings: false}]
|
||||||
|
no-use-before-define: [2, nofunc]
|
||||||
|
no-useless-backreference: [0]
|
||||||
|
no-useless-call: [2]
|
||||||
|
no-useless-catch: [2]
|
||||||
|
no-useless-computed-key: [2]
|
||||||
|
no-useless-concat: [2]
|
||||||
|
no-useless-constructor: [2]
|
||||||
|
no-useless-escape: [2]
|
||||||
|
no-useless-rename: [2]
|
||||||
|
no-useless-return: [2]
|
||||||
no-var: [2]
|
no-var: [2]
|
||||||
|
no-void: [2]
|
||||||
|
no-warning-comments: [0]
|
||||||
|
no-whitespace-before-property: [2]
|
||||||
|
no-with: [2]
|
||||||
|
nonblock-statement-body-position: [2]
|
||||||
object-curly-newline: [0]
|
object-curly-newline: [0]
|
||||||
object-curly-spacing: [2, never]
|
object-curly-spacing: [2, never]
|
||||||
|
object-shorthand: [2, always]
|
||||||
one-var-declaration-per-line: [0]
|
one-var-declaration-per-line: [0]
|
||||||
one-var: [0]
|
one-var: [0]
|
||||||
|
operator-assignment: [2, always]
|
||||||
operator-linebreak: [2, after]
|
operator-linebreak: [2, after]
|
||||||
|
padded-blocks: [2, never]
|
||||||
|
padding-line-between-statements: [0]
|
||||||
|
prefer-arrow-callback: [2, {allowNamedFunctions: true, allowUnboundThis: true}]
|
||||||
prefer-const: [2, {destructuring: all}]
|
prefer-const: [2, {destructuring: all}]
|
||||||
prefer-destructuring: [0]
|
prefer-destructuring: [0]
|
||||||
|
prefer-exponentiation-operator: [2]
|
||||||
|
prefer-named-capture-group: [0]
|
||||||
|
prefer-numeric-literals: [2]
|
||||||
|
prefer-object-spread: [0]
|
||||||
|
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
|
||||||
|
prefer-regex-literals: [2]
|
||||||
|
prefer-rest-params: [2]
|
||||||
|
prefer-spread: [2]
|
||||||
|
prefer-template: [2]
|
||||||
|
quote-props: [0]
|
||||||
quotes: [2, single, {avoidEscape: true, allowTemplateLiterals: true}]
|
quotes: [2, single, {avoidEscape: true, allowTemplateLiterals: true}]
|
||||||
radix: [2, as-needed]
|
radix: [2, as-needed]
|
||||||
|
require-atomic-updates: [0]
|
||||||
|
require-await: [0]
|
||||||
|
require-unicode-regexp: [0]
|
||||||
|
require-yield: [2]
|
||||||
|
rest-spread-spacing: [2, never]
|
||||||
|
semi-spacing: [2, {before: false, after: true}]
|
||||||
|
semi-style: [2, last]
|
||||||
semi: [2, always, {omitLastInOneLineBlock: true}]
|
semi: [2, always, {omitLastInOneLineBlock: true}]
|
||||||
|
sort-imports: [0]
|
||||||
|
sort-keys: [0]
|
||||||
|
sort-vars: [0]
|
||||||
|
space-before-blocks: [2, always]
|
||||||
|
space-in-parens: [2, never]
|
||||||
|
space-infix-ops: [2]
|
||||||
|
space-unary-ops: [2]
|
||||||
|
spaced-comment: [2, always]
|
||||||
|
strict: [0]
|
||||||
|
switch-colon-spacing: [2]
|
||||||
|
symbol-description: [2]
|
||||||
|
template-curly-spacing: [2, never]
|
||||||
|
template-tag-spacing: [2, never]
|
||||||
|
unicode-bom: [2, never]
|
||||||
|
unicorn/better-regex: [0]
|
||||||
|
unicorn/catch-error-name: [0]
|
||||||
|
unicorn/consistent-function-scoping: [2]
|
||||||
|
unicorn/custom-error-definition: [0]
|
||||||
|
unicorn/error-message: [0]
|
||||||
|
unicorn/escape-case: [0]
|
||||||
|
unicorn/expiring-todo-comments: [0]
|
||||||
|
unicorn/explicit-length-check: [0]
|
||||||
|
unicorn/filename-case: [0]
|
||||||
|
unicorn/import-index: [0]
|
||||||
|
unicorn/new-for-builtins: [2]
|
||||||
|
unicorn/no-abusive-eslint-disable: [0]
|
||||||
|
unicorn/no-array-instanceof: [0]
|
||||||
|
unicorn/no-console-spaces: [0]
|
||||||
|
unicorn/no-fn-reference-in-iterator: [0]
|
||||||
|
unicorn/no-for-loop: [0]
|
||||||
|
unicorn/no-hex-escape: [0]
|
||||||
|
unicorn/no-keyword-prefix: [0]
|
||||||
|
unicorn/no-nested-ternary: [0]
|
||||||
|
unicorn/no-new-buffer: [0]
|
||||||
|
unicorn/no-null: [0]
|
||||||
|
unicorn/no-object-as-default-parameter: [2]
|
||||||
|
unicorn/no-process-exit: [0]
|
||||||
|
unicorn/no-reduce: [2]
|
||||||
|
unicorn/no-unreadable-array-destructuring: [0]
|
||||||
|
unicorn/no-unsafe-regex: [0]
|
||||||
|
unicorn/no-unused-properties: [2]
|
||||||
|
unicorn/no-useless-undefined: [0]
|
||||||
|
unicorn/no-zero-fractions: [2]
|
||||||
|
unicorn/number-literal-case: [0]
|
||||||
|
unicorn/prefer-add-event-listener: [2]
|
||||||
|
unicorn/prefer-array-find: [2]
|
||||||
|
unicorn/prefer-dataset: [2]
|
||||||
|
unicorn/prefer-event-key: [2]
|
||||||
|
unicorn/prefer-includes: [2]
|
||||||
|
unicorn/prefer-modern-dom-apis: [0]
|
||||||
|
unicorn/prefer-negative-index: [2]
|
||||||
|
unicorn/prefer-node-append: [0]
|
||||||
|
unicorn/prefer-node-remove: [0]
|
||||||
|
unicorn/prefer-number-properties: [0]
|
||||||
|
unicorn/prefer-optional-catch-binding: [2]
|
||||||
|
unicorn/prefer-query-selector: [0]
|
||||||
|
unicorn/prefer-reflect-apply: [0]
|
||||||
|
unicorn/prefer-replace-all: [0]
|
||||||
|
unicorn/prefer-set-has: [0]
|
||||||
|
unicorn/prefer-spread: [0]
|
||||||
|
unicorn/prefer-starts-ends-with: [2]
|
||||||
|
unicorn/prefer-string-slice: [0]
|
||||||
|
unicorn/prefer-text-content: [2]
|
||||||
|
unicorn/prefer-trim-start-end: [2]
|
||||||
|
unicorn/prefer-type-error: [0]
|
||||||
|
unicorn/prevent-abbreviations: [0]
|
||||||
|
unicorn/string-content: [0]
|
||||||
|
unicorn/throw-new-error: [2]
|
||||||
|
use-isnan: [2]
|
||||||
|
valid-typeof: [2, {requireStringLiterals: true}]
|
||||||
|
vars-on-top: [0]
|
||||||
|
wrap-iife: [2, inside]
|
||||||
|
wrap-regex: [0]
|
||||||
|
yield-star-spacing: [2, after]
|
||||||
|
yoda: [2, never]
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
/vendor/** -text -eol
|
/vendor/** -text -eol linguist-vendored
|
||||||
/public/vendor/** -text -eol
|
/public/vendor/** -text -eol linguist-vendored
|
||||||
|
|
||||||
conf/* linguist-vendored
|
|
||||||
docker/* linguist-vendored
|
|
||||||
options/* linguist-vendored
|
|
||||||
public/* linguist-vendored
|
|
||||||
build/* linguist-vendored
|
|
||||||
templates/* linguist-vendored
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ coverage.all
|
||||||
/custom/*
|
/custom/*
|
||||||
!/custom/conf
|
!/custom/conf
|
||||||
/custom/conf/*
|
/custom/conf/*
|
||||||
!/custom/conf/app.ini.sample
|
!/custom/conf/app.example.ini
|
||||||
/data
|
/data
|
||||||
/indexers
|
/indexers
|
||||||
/log
|
/log
|
||||||
|
@ -76,11 +76,13 @@ coverage.all
|
||||||
/node_modules
|
/node_modules
|
||||||
/yarn.lock
|
/yarn.lock
|
||||||
/public/js
|
/public/js
|
||||||
|
/public/serviceworker.js
|
||||||
/public/css
|
/public/css
|
||||||
/public/fonts
|
/public/fonts
|
||||||
/public/fomantic
|
/public/img/webpack
|
||||||
/public/img/svg
|
/web_src/fomantic/build
|
||||||
/VERSION
|
/VERSION
|
||||||
|
/.air
|
||||||
|
|
||||||
# Snapcraft
|
# Snapcraft
|
||||||
snap/.snapcraft/
|
snap/.snapcraft/
|
||||||
|
|
1
.ignore
1
.ignore
|
@ -1,6 +1,5 @@
|
||||||
/vendor
|
/vendor
|
||||||
/public/vendor/plugins
|
/public/vendor/plugins
|
||||||
/public/vendor/assets
|
|
||||||
/modules/options/bindata.go
|
/modules/options/bindata.go
|
||||||
/modules/public/bindata.go
|
/modules/public/bindata.go
|
||||||
/modules/templates/bindata.go
|
/modules/templates/bindata.go
|
||||||
|
|
|
@ -14,3 +14,4 @@ rules:
|
||||||
number-leading-zero: never
|
number-leading-zero: never
|
||||||
rule-empty-line-before: null
|
rule-empty-line-before: null
|
||||||
selector-pseudo-element-colon-notation: null
|
selector-pseudo-element-colon-notation: null
|
||||||
|
shorthand-property-no-redundant-values: true
|
||||||
|
|
146
CHANGELOG.md
146
CHANGELOG.md
|
@ -4,16 +4,63 @@ 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.12.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.12.0-rc1) - 2020-05-18
|
## [1.12.3](https://github.com/go-gitea/gitea/releases/tag/v1.12.3) - 2020-07-28
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* Don't change creation date when updating Release (#12343) (#12351)
|
||||||
|
* Show 404 page when release not found (#12328) (#12332)
|
||||||
|
* Fix emoji detection in certain cases (#12320) (#12327)
|
||||||
|
* Reduce emoji size (#12317) (#12327)
|
||||||
|
* Fix double-indirection bug in logging IDs (#12294) (#12308)
|
||||||
|
* Link to pull list page on sidebar when view pr (#12256) (#12263)
|
||||||
|
* Extend Notifications API and return pinned notifications by default (#12164) (#12232)
|
||||||
|
|
||||||
|
## [1.12.2](https://github.com/go-gitea/gitea/releases/tag/v1.12.2) - 2020-07-11
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* When deleting repository decrese user repository count in cache (#11954) (#12188)
|
||||||
|
* Return full commit message instead of summary in commits API (#12186) (#12187)
|
||||||
|
* Properly set HEAD when a repo is created with a default branch that is not named 'master' (#12135) (#12182)
|
||||||
|
* Ensure GPG Subkeys are verified (#12155) (#12168)
|
||||||
|
* Fix failing to cache last commit with key being to long (#12151) (#12161)
|
||||||
|
* Multiple small admin dashboard fixes (#12153) (#12156)
|
||||||
|
* Remove spurious logging of " Delete all repository archives" at startup (#12139) (#12148)
|
||||||
|
* Fix repository setup instructions when default branch is not named 'master' (#12122) (#12147)
|
||||||
|
* Move EventSource to SharedWorker (#12095) (#12130)
|
||||||
|
* Fix ui bug in wiki commit page (#12089) (#12125)
|
||||||
|
* Fix gitgraph branch continues after merge (#12044) (#12105)
|
||||||
|
* Set the base url when migrating from Gitlab using access token or username without password (#11852) (#12104)
|
||||||
|
* Ensure BlameReaders close at end of request (#12102) (#12103)
|
||||||
|
* Fix panic when adding review comment (#12058)
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* Disable dropzone's timeout for file uploads (#12024) (#12032)
|
||||||
|
|
||||||
|
## [1.12.1](https://github.com/go-gitea/gitea/releases/tag/v1.12.1) - 2020-06-21
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* Handle multiple merges in gitgraph.js (#11996) (#12000)
|
||||||
|
* Add serviceworker.js to KnownPublicEntries (#11992) (#11994)
|
||||||
|
* For language detection do not try to analyze big files by content (#11971) (#11975)
|
||||||
|
* ENHANCEMENTS
|
||||||
|
* Fix scrollable header on dropdowns (#11893) (#11965)
|
||||||
|
|
||||||
|
## [1.11.8](https://github.com/go-gitea/gitea/releases/tag/v1.11.8) - 2020-06-21
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* Really fix __webpack_public_path__ for 1.11 (#11961)
|
||||||
|
|
||||||
|
## [1.12.0](https://github.com/go-gitea/gitea/releases/tag/v1.12.0) - 2020-06-17
|
||||||
|
|
||||||
* BREAKING
|
* BREAKING
|
||||||
* Remove migration support from versions earlier than 1.6.0 (#10026)
|
* When using API CreateRelease set created_unix to the tag commit time (#11218)
|
||||||
* Enable ENABLE_HARD_LINE_BREAK by default for rendering markdown (#11162)
|
* Enable ENABLE_HARD_LINE_BREAK by default for rendering markdown (#11162)
|
||||||
* Fix sanitizer config - multiple rules (#11133)
|
* Fix sanitizer config - multiple rules (#11133)
|
||||||
* When using API CreateRelease set created_unix to the tag commit time (#11218)
|
|
||||||
* Remove check on username when using AccessToken authentication for the API (#11015)
|
* Remove check on username when using AccessToken authentication for the API (#11015)
|
||||||
* Return 404 from Contents API when items don't exist (#10323)
|
* Return 404 from Contents API when items don't exist (#10323)
|
||||||
* Notification API should always return a JSON object with the current count of notifications (#10059)
|
* Notification API should always return a JSON object with the current count of notifications (#10059)
|
||||||
|
* Remove migration support from versions earlier than 1.6.0 (#10026)
|
||||||
|
* SECURITY
|
||||||
|
* Use -1 to disable key algorithm type in ssh.minimum_key_sizes (#11635) (#11662)
|
||||||
* FEATURES
|
* FEATURES
|
||||||
* Improve config logging when WrappedQueue times out (#11174)
|
* Improve config logging when WrappedQueue times out (#11174)
|
||||||
* Add branch delete to API (#11112)
|
* Add branch delete to API (#11112)
|
||||||
|
@ -55,6 +102,53 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
* Language statistics bar for repositories (#8037)
|
* Language statistics bar for repositories (#8037)
|
||||||
* Restricted users (#6274)
|
* Restricted users (#6274)
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
* Fix commenting on non-utf8 encoded files (#11916) (#11950)
|
||||||
|
* Use google/uuid to instead satori/go.uuid (#11943) (#11946)
|
||||||
|
* Align show/hide outdated button on code review block (#11932) (#11944)
|
||||||
|
* Update to go-git v5.1.0 (#11936) (#11941)
|
||||||
|
* Use ID or Where to instead directly use Get when load object from database (#11925) (#11934)
|
||||||
|
* Update CommitsAhead CommitsBehind on Pull BaseBranch Change too (#11912) (#11915)
|
||||||
|
* Invalidate comments when file is shortened (#11882) (#11884)
|
||||||
|
* Rework api/user/repos for pagination (#11827) (#11877)
|
||||||
|
* Handle more pathological branch and tag names (#11843) (#11863)
|
||||||
|
* Add doctor check to set IsArchived false if it is null (partial #11853) (#11859)
|
||||||
|
* Prevent panic on empty HOST for mysql (#11850) (#11856)
|
||||||
|
* Use DEFAULT_PAGING_NUM instead of MAX_RESPONSE_ITEMS in ListOptions (#11831) (#11836)
|
||||||
|
* Fix reply octicon (#11821) (#11822)
|
||||||
|
* Honor DEFAULT_PAGING_NUM for API (#11805) (#11813)
|
||||||
|
* Ensure rejected push to refs/pull/index/head fails nicely (#11724) (#11809)
|
||||||
|
* In File Create/Update API return 404 if Branch does not exist (#11791) (#11795)
|
||||||
|
* Fix doer of rename repo (#11789) (#11794)
|
||||||
|
* Initialize SimpleMDE when making a code comment (#11749) (#11785)
|
||||||
|
* Fix timezone on issue deadline (#11697) (#11784)
|
||||||
|
* Fix to allow comment poster to edit or delete his own comments (#11671) (#11774)
|
||||||
|
* Show full 500 error in API when Gitea in dev mode (#11641) (#11753)
|
||||||
|
* Add missing templates for Matrix system webhooks (#11729) (#11748)
|
||||||
|
* Fix verification of subkeys of default gpg key (#11713) (#11747)
|
||||||
|
* Fix styling for commiter on diff view (#11715) (#11744)
|
||||||
|
* Properly truncate system notices (#11714) (#11742)
|
||||||
|
* Handle expected errors in FileCreate & FileUpdate API (#11643) (#11718)
|
||||||
|
* Fix missing authorization check on pull for public repos of private/limited org (#11656) (#11682)
|
||||||
|
* Doctor check & fix db consistency (#11111) (#11676)
|
||||||
|
* Exclude generated files from language statistics (#11653) (#11670)
|
||||||
|
* Return json on 500 error from API (#11574) (#11659)
|
||||||
|
* When must change password only show Signout (#11600) (#11637)
|
||||||
|
* Backport various styling fixes (#11619)
|
||||||
|
* Fix wrong milestone in webhook message (#11596) (#11611)
|
||||||
|
* Fix serviceworker output file and misc improvements (#11562) (#11610)
|
||||||
|
* When initialising repositories ensure that the user doing the creation is the initializer (#11601) (#11608)
|
||||||
|
* Prevent empty query parameter being set on dashboard (#11561) (#11604)
|
||||||
|
* Fix images in wiki edit preview (#11546) (#11602)
|
||||||
|
* Prevent (caught) panic on login (#11590) (#11597)
|
||||||
|
* Prevent transferring repos to invisible orgs (#11517) (#11549)
|
||||||
|
* Move serviceworker to workbox and fix SSE interference (#11538) (#11547)
|
||||||
|
* API PullReviewComment HTMLPullURL should return the HTMLURL (#11501) (#11533)
|
||||||
|
* Fix repo-list private and total count bugs (#11500) (#11532)
|
||||||
|
* Fix form action template substitutions on admin pages (backport #11519) (#11531)
|
||||||
|
* Fix a bug where the reaction emoji doesn't disappear. (#11489) (#11530)
|
||||||
|
* TrimSpace when reading InternalToken from a file (#11502) (#11524)
|
||||||
|
* Fix selected line color in arc-green (#11492) (#11520)
|
||||||
|
* Make localstorage read ssh or https correctly (#11483) (#11490)
|
||||||
* Check branch protection on IsUserAllowedToUpdate (#11448)
|
* Check branch protection on IsUserAllowedToUpdate (#11448)
|
||||||
* Fix margin on attached segment headers when they are separated by other element (#11425)
|
* Fix margin on attached segment headers when they are separated by other element (#11425)
|
||||||
* Fix webhook template when validation errors occur (#11421)
|
* Fix webhook template when validation errors occur (#11421)
|
||||||
|
@ -122,6 +216,22 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
* Fix wrong original git service type on a migrated repository (#9693)
|
* Fix wrong original git service type on a migrated repository (#9693)
|
||||||
* Fix ref links in issue overviews for tags (#8742)
|
* Fix ref links in issue overviews for tags (#8742)
|
||||||
* ENHANCEMENTS
|
* ENHANCEMENTS
|
||||||
|
* Fix search form button overlap (#11840) (#11864)
|
||||||
|
* Make tabular menu styling consistent for arc-green (#11570) (#11798)
|
||||||
|
* Add option to API to update PullRequest base branch (#11666) (#11796)
|
||||||
|
* Increase maximum SQLite variables count to 32766 (#11696) (#11783)
|
||||||
|
* Update emoji dataset with skin tone variants (#11678) (#11763)
|
||||||
|
* Add logging to long migrations (#11647) (#11691)
|
||||||
|
* Change language statistics to save size instead of percentage (#11681) (#11690)
|
||||||
|
* Allow different HardBreaks settings for documents and comments (#11515) (#11599)
|
||||||
|
* Fix alignment for commits on dashboard (#11595) (#11680)
|
||||||
|
* Default MSSQL port 0 to allow automatic detection by default (#11642) (#11673)
|
||||||
|
* Handle expected errors in AddGPGkey API (#11644) (#11661)
|
||||||
|
* Close EventSource before unloading the page (#11539) (#11557)
|
||||||
|
* Ensure emoji render with regular font-weight (#11541) (#11545)
|
||||||
|
* Fix webpack chunk loading with STATIC_URL_PREFIX (#11526) (#11542)
|
||||||
|
* Tweak reaction buttons (#11516)
|
||||||
|
* Use more toned colors for selected line (#11493) (#11511)
|
||||||
* Increase width for authors on commit view (#11441)
|
* Increase width for authors on commit view (#11441)
|
||||||
* Hide archived repos by default in repo-list (#11440)
|
* Hide archived repos by default in repo-list (#11440)
|
||||||
* Better styling for code review comment textarea (#11428)
|
* Better styling for code review comment textarea (#11428)
|
||||||
|
@ -284,6 +394,36 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
* Fix queue log param (#10733)
|
* Fix queue log param (#10733)
|
||||||
* Add warning when using relative path to app.ini (#10104)
|
* Add warning when using relative path to app.ini (#10104)
|
||||||
|
|
||||||
|
## [1.11.7](https://github.com/go-gitea/gitea/releases/tag/v1.11.7) - 2020-06-18
|
||||||
|
|
||||||
|
* BUGFIXES
|
||||||
|
* Use ID or Where to instead directly use Get when load object from database (#11925) (#11935)
|
||||||
|
* Fix __webpack_public_path__ for 1.11 (#11907)
|
||||||
|
* Fix verification of subkeys of default gpg key (#11713) (#11902)
|
||||||
|
* Remove unnecessary parentheses in wiki/view template (#11781)
|
||||||
|
* Doctor fix xorm.Count nil on sqlite error (#11741)
|
||||||
|
|
||||||
|
## [1.11.6](https://github.com/go-gitea/gitea/releases/tag/v1.11.6) - 2020-05-30
|
||||||
|
|
||||||
|
* SECURITY
|
||||||
|
* Fix missing authorization check on pull for public repos of private/limited org (#11656) (#11683)
|
||||||
|
* Use session for retrieving org teams (#11438) (#11439)
|
||||||
|
* BUGFIXES
|
||||||
|
* Return json on 500 error from API (#11574) (#11660)
|
||||||
|
* Fix wrong milestone in webhook message (#11596) (#11612)
|
||||||
|
* Prevent (caught) panic on login (#11590) (#11598)
|
||||||
|
* Fix commit page js error (#11527)
|
||||||
|
* Use media links for img in post-process (#10515) (#11504)
|
||||||
|
* Ensure public repositories in private organizations are visible and fix admin organizations list (#11465) (#11475)
|
||||||
|
* Set correct Content-Type value for Gogs/Gitea webhooks (#9504) (#10456) (#11461)
|
||||||
|
* Allow all members of private orgs to see public repos (#11442) (#11459)
|
||||||
|
* Whenever the ctx.Session is updated, release it to save it before sending the redirect (#11456) (#11457)
|
||||||
|
* Forcibly clean and destroy the session on logout (#11447) (#11451)
|
||||||
|
* Fix /api/v1/orgs/* endpoints by changing parameter to :org from :orgname (#11381)
|
||||||
|
* Add tracked time fix to doctor (part of #11111) (#11138)
|
||||||
|
* Fix webpack chunk loading with STATIC_URL_PREFIX (#11526) (#11544)
|
||||||
|
* Remove unnecessary parentheses in wiki/revision.tmpl to allow 1.11 to build on go1.14 (#11481)
|
||||||
|
|
||||||
## [1.11.5](https://github.com/go-gitea/gitea/releases/tag/v1.11.5) - 2020-05-09
|
## [1.11.5](https://github.com/go-gitea/gitea/releases/tag/v1.11.5) - 2020-05-09
|
||||||
|
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
|
|
|
@ -293,25 +293,25 @@ and lead the development of Gitea.
|
||||||
To honor the past owners, here's the history of the owners and the time
|
To honor the past owners, here's the history of the owners and the time
|
||||||
they served:
|
they served:
|
||||||
|
|
||||||
* 2016-11-04 ~ 2017-12-31
|
* 2020-01-01 ~ 2020-12-31 - https://github.com/go-gitea/gitea/issues/9230
|
||||||
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
|
* [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
|
||||||
* [Thomas Boerger](https://github.com/tboerger) <thomas@webhippie.de>
|
* [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) <lauris@nix.lv>
|
||||||
* [Kim Carlbäcker](https://github.com/bkcsoft) <kim.carlbacker@gmail.com>
|
* [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.io>
|
||||||
|
|
||||||
* 2018-01-01 ~ 2018-12-31
|
* 2019-01-01 ~ 2019-12-31 - https://github.com/go-gitea/gitea/issues/5572
|
||||||
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
|
|
||||||
* [Lauris Bukšis-Haberkorns](https://github.com/lafriks) <lauris@nix.lv>
|
|
||||||
* [Kim Carlbäcker](https://github.com/bkcsoft) <kim.carlbacker@gmail.com>
|
|
||||||
|
|
||||||
* 2019-01-01 ~ 2019-12-31
|
|
||||||
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
|
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
|
||||||
* [Lauris Bukšis-Haberkorns](https://github.com/lafriks) <lauris@nix.lv>
|
* [Lauris Bukšis-Haberkorns](https://github.com/lafriks) <lauris@nix.lv>
|
||||||
* [Matti Ranta](https://github.com/techknowlogick) <techknowlogick@gitea.io>
|
* [Matti Ranta](https://github.com/techknowlogick) <techknowlogick@gitea.io>
|
||||||
|
|
||||||
* 2020-01-01 ~ 2020-12-31
|
* 2018-01-01 ~ 2018-12-31 - https://github.com/go-gitea/gitea/issues/3255
|
||||||
* [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
|
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
|
||||||
* [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) <lauris@nix.lv>
|
* [Lauris Bukšis-Haberkorns](https://github.com/lafriks) <lauris@nix.lv>
|
||||||
* [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.io>
|
* [Kim Carlbäcker](https://github.com/bkcsoft) <kim.carlbacker@gmail.com>
|
||||||
|
|
||||||
|
* 2016-11-04 ~ 2017-12-31
|
||||||
|
* [Lunny Xiao](https://github.com/lunny) <xiaolunwen@gmail.com>
|
||||||
|
* [Thomas Boerger](https://github.com/tboerger) <thomas@webhippie.de>
|
||||||
|
* [Kim Carlbäcker](https://github.com/bkcsoft) <kim.carlbacker@gmail.com>
|
||||||
|
|
||||||
## Versions
|
## Versions
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
#Build stage
|
#Build stage
|
||||||
FROM golang:1.14-alpine3.11 AS build-env
|
FROM golang:1.14-alpine3.12 AS build-env
|
||||||
|
|
||||||
ARG GOPROXY
|
ARG GOPROXY
|
||||||
ENV GOPROXY ${GOPROXY:-direct}
|
ENV GOPROXY ${GOPROXY:-direct}
|
||||||
|
@ -9,6 +9,7 @@ ENV GOPROXY ${GOPROXY:-direct}
|
||||||
ARG GITEA_VERSION
|
ARG GITEA_VERSION
|
||||||
ARG TAGS="sqlite sqlite_unlock_notify"
|
ARG TAGS="sqlite sqlite_unlock_notify"
|
||||||
ENV TAGS "bindata $TAGS"
|
ENV TAGS "bindata $TAGS"
|
||||||
|
ARG CGO_EXTRA_CFLAGS
|
||||||
|
|
||||||
#Build deps
|
#Build deps
|
||||||
RUN apk --no-cache add build-base git nodejs npm
|
RUN apk --no-cache add build-base git nodejs npm
|
||||||
|
@ -21,7 +22,7 @@ WORKDIR ${GOPATH}/src/code.gitea.io/gitea
|
||||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||||
&& make clean-all build
|
&& make clean-all build
|
||||||
|
|
||||||
FROM alpine:3.11
|
FROM alpine:3.12
|
||||||
LABEL maintainer="maintainers@gitea.io"
|
LABEL maintainer="maintainers@gitea.io"
|
||||||
|
|
||||||
EXPOSE 22 3000
|
EXPOSE 22 3000
|
||||||
|
|
|
@ -36,3 +36,4 @@ Mura Li <typeless@ctli.io> (@typeless)
|
||||||
6543 <6543@obermui.de> (@6543)
|
6543 <6543@obermui.de> (@6543)
|
||||||
jaqra <jaqra@hotmail.com> (@jaqra)
|
jaqra <jaqra@hotmail.com> (@jaqra)
|
||||||
David Svantesson <davidsvantesson@gmail.com> (@davidsvantesson)
|
David Svantesson <davidsvantesson@gmail.com> (@davidsvantesson)
|
||||||
|
CirnoT <gitea.m@i32.pl> (@CirnoT)
|
||||||
|
|
155
Makefile
155
Makefile
|
@ -21,7 +21,6 @@ IMPORT := code.gitea.io/gitea
|
||||||
export GO111MODULE=on
|
export GO111MODULE=on
|
||||||
|
|
||||||
GO ?= go
|
GO ?= go
|
||||||
SED_INPLACE := sed -i
|
|
||||||
SHASUM ?= shasum -a 256
|
SHASUM ?= shasum -a 256
|
||||||
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
||||||
COMMA := ,
|
COMMA := ,
|
||||||
|
@ -30,23 +29,28 @@ XGO_VERSION := go-1.14.x
|
||||||
MIN_GO_VERSION := 001012000
|
MIN_GO_VERSION := 001012000
|
||||||
MIN_NODE_VERSION := 010013000
|
MIN_NODE_VERSION := 010013000
|
||||||
|
|
||||||
|
DOCKER_IMAGE ?= gitea/gitea
|
||||||
|
DOCKER_TAG ?= latest
|
||||||
|
DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
|
||||||
|
|
||||||
ifeq ($(HAS_GO), GO)
|
ifeq ($(HAS_GO), GO)
|
||||||
GOPATH ?= $(shell $(GO) env GOPATH)
|
GOPATH ?= $(shell $(GO) env GOPATH)
|
||||||
export PATH := $(GOPATH)/bin:$(PATH)
|
export PATH := $(GOPATH)/bin:$(PATH)
|
||||||
endif
|
|
||||||
|
|
||||||
|
CGO_EXTRA_CFLAGS := -DSQLITE_MAX_VARIABLE_NUMBER=32766
|
||||||
|
CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(OS), Windows_NT)
|
ifeq ($(OS), Windows_NT)
|
||||||
EXECUTABLE ?= gitea.exe
|
EXECUTABLE ?= gitea.exe
|
||||||
else
|
else
|
||||||
EXECUTABLE ?= gitea
|
EXECUTABLE ?= gitea
|
||||||
UNAME_S := $(shell uname -s)
|
endif
|
||||||
ifeq ($(UNAME_S),Darwin)
|
|
||||||
SED_INPLACE := sed -i ''
|
ifeq ($(shell sed --version 2>/dev/null | grep -q GNU && echo gnu),gnu)
|
||||||
endif
|
SED_INPLACE := sed -i
|
||||||
ifeq ($(UNAME_S),FreeBSD)
|
else
|
||||||
SED_INPLACE := sed -i ''
|
SED_INPLACE := sed -i ''
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
GOFMT ?= gofmt -s
|
GOFMT ?= gofmt -s
|
||||||
|
@ -85,14 +89,22 @@ LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(G
|
||||||
|
|
||||||
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(filter-out code.gitea.io/gitea/integrations,$(shell $(GO) list -mod=vendor ./... | grep -v /vendor/)))
|
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(filter-out code.gitea.io/gitea/integrations,$(shell $(GO) list -mod=vendor ./... | grep -v /vendor/)))
|
||||||
|
|
||||||
WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f)
|
FOMANTIC_CONFIGS := semantic.json web_src/fomantic/theme.config.less web_src/fomantic/_site/globals/site.variables
|
||||||
|
FOMANTIC_DEST := web_src/fomantic/build/semantic.js web_src/fomantic/build/semantic.css
|
||||||
|
FOMANTIC_DEST_DIR := web_src/fomantic/build
|
||||||
|
|
||||||
|
WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f) $(FOMANTIC_DEST)
|
||||||
WEBPACK_CONFIGS := webpack.config.js
|
WEBPACK_CONFIGS := webpack.config.js
|
||||||
WEBPACK_DEST := public/js/index.js public/css/index.css
|
WEBPACK_DEST := public/js/index.js public/css/index.css
|
||||||
WEBPACK_DEST_DIRS := public/js public/css public/fonts
|
WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/img/webpack public/serviceworker.js
|
||||||
|
|
||||||
BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
|
BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
|
||||||
BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))
|
BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))
|
||||||
|
|
||||||
|
SVG_DEST_DIR := public/img/svg
|
||||||
|
|
||||||
|
AIR_TMP_DIR := .air
|
||||||
|
|
||||||
TAGS ?=
|
TAGS ?=
|
||||||
TAGS_SPLIT := $(subst $(COMMA), ,$(TAGS))
|
TAGS_SPLIT := $(subst $(COMMA), ,$(TAGS))
|
||||||
TAGS_EVIDENCE := $(MAKE_EVIDENCE_DIR)/tags
|
TAGS_EVIDENCE := $(MAKE_EVIDENCE_DIR)/tags
|
||||||
|
@ -107,10 +119,6 @@ endif
|
||||||
|
|
||||||
GO_SOURCES_OWN := $(filter-out vendor/% %/bindata.go, $(GO_SOURCES))
|
GO_SOURCES_OWN := $(filter-out vendor/% %/bindata.go, $(GO_SOURCES))
|
||||||
|
|
||||||
FOMANTIC_CONFIGS := semantic.json web_src/fomantic/theme.config.less web_src/fomantic/_site/globals/site.variables web_src/fomantic/css.js
|
|
||||||
FOMANTIC_DEST := public/fomantic/semantic.min.js public/fomantic/semantic.min.css
|
|
||||||
FOMANTIC_DEST_DIR := public/fomantic
|
|
||||||
|
|
||||||
#To update swagger use: GO111MODULE=on go get -u github.com/go-swagger/go-swagger/cmd/swagger@v0.20.1
|
#To update swagger use: GO111MODULE=on go get -u github.com/go-swagger/go-swagger/cmd/swagger@v0.20.1
|
||||||
SWAGGER := $(GO) run -mod=vendor github.com/go-swagger/go-swagger/cmd/swagger
|
SWAGGER := $(GO) run -mod=vendor github.com/go-swagger/go-swagger/cmd/swagger
|
||||||
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
|
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
|
||||||
|
@ -139,8 +147,6 @@ TEST_MSSQL_PASSWORD ?= MwantsaSecurePassword1
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
include docker/Makefile
|
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
help:
|
help:
|
||||||
@echo "Make Routines:"
|
@echo "Make Routines:"
|
||||||
|
@ -154,7 +160,9 @@ help:
|
||||||
@echo " - lint-frontend lint frontend files"
|
@echo " - lint-frontend lint frontend files"
|
||||||
@echo " - lint-backend lint backend files"
|
@echo " - lint-backend lint backend files"
|
||||||
@echo " - watch-frontend watch frontend files and continuously rebuild"
|
@echo " - watch-frontend watch frontend files and continuously rebuild"
|
||||||
|
@echo " - watch-backend watch backend files and continuously rebuild"
|
||||||
@echo " - webpack build webpack files"
|
@echo " - webpack build webpack files"
|
||||||
|
@echo " - svg build svg files"
|
||||||
@echo " - fomantic build fomantic files"
|
@echo " - fomantic build fomantic files"
|
||||||
@echo " - generate run \"go generate\""
|
@echo " - generate run \"go generate\""
|
||||||
@echo " - fmt format the Go code"
|
@echo " - fmt format the Go code"
|
||||||
|
@ -194,7 +202,7 @@ node-check:
|
||||||
|
|
||||||
.PHONY: clean-all
|
.PHONY: clean-all
|
||||||
clean-all: clean
|
clean-all: clean
|
||||||
rm -rf $(WEBPACK_DEST_DIRS) $(FOMANTIC_DEST_DIR)
|
rm -rf $(WEBPACK_DEST_ENTRIES) $(FOMANTIC_DEST_DIR)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
@ -250,7 +258,7 @@ swagger-validate:
|
||||||
.PHONY: errcheck
|
.PHONY: errcheck
|
||||||
errcheck:
|
errcheck:
|
||||||
@hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/kisielk/errcheck; \
|
GO111MODULE=off $(GO) get -u github.com/kisielk/errcheck; \
|
||||||
fi
|
fi
|
||||||
errcheck $(GO_PACKAGES)
|
errcheck $(GO_PACKAGES)
|
||||||
|
|
||||||
|
@ -261,14 +269,14 @@ revive:
|
||||||
.PHONY: misspell-check
|
.PHONY: misspell-check
|
||||||
misspell-check:
|
misspell-check:
|
||||||
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
||||||
fi
|
fi
|
||||||
misspell -error -i unknwon,destory $(GO_SOURCES_OWN)
|
misspell -error -i unknwon,destory $(GO_SOURCES_OWN)
|
||||||
|
|
||||||
.PHONY: misspell
|
.PHONY: misspell
|
||||||
misspell:
|
misspell:
|
||||||
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
||||||
fi
|
fi
|
||||||
misspell -w -i unknwon $(GO_SOURCES_OWN)
|
misspell -w -i unknwon $(GO_SOURCES_OWN)
|
||||||
|
|
||||||
|
@ -289,14 +297,22 @@ lint: lint-backend lint-frontend
|
||||||
lint-backend: golangci-lint revive vet swagger-check swagger-validate test-vendor
|
lint-backend: golangci-lint revive vet swagger-check swagger-validate test-vendor
|
||||||
|
|
||||||
.PHONY: lint-frontend
|
.PHONY: lint-frontend
|
||||||
lint-frontend: node_modules
|
lint-frontend: node_modules svg-check
|
||||||
npx eslint web_src/js webpack.config.js
|
npx eslint web_src/js build webpack.config.js
|
||||||
npx stylelint web_src/less
|
npx stylelint web_src/less
|
||||||
|
|
||||||
.PHONY: watch-frontend
|
.PHONY: watch-frontend
|
||||||
watch-frontend: node_modules
|
watch-frontend: node-check $(FOMANTIC_DEST) node_modules
|
||||||
|
rm -rf $(WEBPACK_DEST_ENTRIES)
|
||||||
NODE_ENV=development npx webpack --hide-modules --display-entrypoints=false --watch --progress
|
NODE_ENV=development npx webpack --hide-modules --display-entrypoints=false --watch --progress
|
||||||
|
|
||||||
|
.PHONY: watch-backend
|
||||||
|
watch-backend: go-check
|
||||||
|
@hash air > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
|
GO111MODULE=off $(GO) get -u github.com/cosmtrek/air; \
|
||||||
|
fi
|
||||||
|
air -c .air.conf
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='sqlite sqlite_unlock_notify' $(GO_PACKAGES)
|
$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='sqlite sqlite_unlock_notify' $(GO_PACKAGES)
|
||||||
|
@ -498,7 +514,7 @@ check: test
|
||||||
|
|
||||||
.PHONY: install $(TAGS_PREREQ)
|
.PHONY: install $(TAGS_PREREQ)
|
||||||
install: $(wildcard *.go)
|
install: $(wildcard *.go)
|
||||||
$(GO) install -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)'
|
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) install -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)'
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: frontend backend
|
build: frontend backend
|
||||||
|
@ -514,10 +530,10 @@ generate: $(TAGS_PREREQ)
|
||||||
CC= GOOS= GOARCH= $(GO) generate -mod=vendor -tags '$(TAGS)' $(GO_PACKAGES)
|
CC= GOOS= GOARCH= $(GO) generate -mod=vendor -tags '$(TAGS)' $(GO_PACKAGES)
|
||||||
|
|
||||||
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
||||||
$(GO) build -mod=vendor $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build -mod=vendor $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
||||||
|
|
||||||
.PHONY: release
|
.PHONY: release
|
||||||
release: frontend generate release-windows release-linux release-darwin release-copy release-compress release-sources release-check
|
release: frontend generate release-windows release-linux release-darwin release-copy release-compress release-sources release-docs release-check
|
||||||
|
|
||||||
$(DIST_DIRS):
|
$(DIST_DIRS):
|
||||||
mkdir -p $(DIST_DIRS)
|
mkdir -p $(DIST_DIRS)
|
||||||
|
@ -525,9 +541,9 @@ $(DIST_DIRS):
|
||||||
.PHONY: release-windows
|
.PHONY: release-windows
|
||||||
release-windows: | $(DIST_DIRS)
|
release-windows: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
cp /build/* $(DIST)/binaries
|
cp /build/* $(DIST)/binaries
|
||||||
endif
|
endif
|
||||||
|
@ -535,9 +551,9 @@ endif
|
||||||
.PHONY: release-linux
|
.PHONY: release-linux
|
||||||
release-linux: | $(DIST_DIRS)
|
release-linux: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/mips64le,linux/mips,linux/mipsle' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/mips64le,linux/mips,linux/mipsle' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
cp /build/* $(DIST)/binaries
|
cp /build/* $(DIST)/binaries
|
||||||
endif
|
endif
|
||||||
|
@ -545,9 +561,9 @@ endif
|
||||||
.PHONY: release-darwin
|
.PHONY: release-darwin
|
||||||
release-darwin: | $(DIST_DIRS)
|
release-darwin: | $(DIST_DIRS)
|
||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
GO111MODULE=off $(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
|
CGO_CFLAGS="$(CGO_CFLAGS)" GO111MODULE=off xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin/*' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
cp /build/* $(DIST)/binaries
|
cp /build/* $(DIST)/binaries
|
||||||
endif
|
endif
|
||||||
|
@ -570,9 +586,20 @@ release-compress: | $(DIST_DIRS)
|
||||||
.PHONY: release-sources
|
.PHONY: release-sources
|
||||||
release-sources: | $(DIST_DIRS) node_modules
|
release-sources: | $(DIST_DIRS) node_modules
|
||||||
echo $(VERSION) > $(STORED_VERSION_FILE)
|
echo $(VERSION) > $(STORED_VERSION_FILE)
|
||||||
tar --exclude=./$(DIST) --exclude=./.git --exclude=./$(MAKE_EVIDENCE_DIR) --exclude=./node_modules/.cache -czf $(DIST)/release/gitea-src-$(VERSION).tar.gz .
|
tar --exclude=./$(DIST) --exclude=./.git --exclude=./$(MAKE_EVIDENCE_DIR) --exclude=./node_modules/.cache --exclude=./$(AIR_TMP_DIR) -czf $(DIST)/release/gitea-src-$(VERSION).tar.gz .
|
||||||
rm -f $(STORED_VERSION_FILE)
|
rm -f $(STORED_VERSION_FILE)
|
||||||
|
|
||||||
|
.PHONY: release-docs
|
||||||
|
release-docs: | $(DIST_DIRS) docs
|
||||||
|
tar -czf $(DIST)/release/gitea-docs-$(VERSION).tar.gz -C ./docs/public .
|
||||||
|
|
||||||
|
.PHONY: docs
|
||||||
|
docs:
|
||||||
|
@hash hugo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
|
$(GO) get -u github.com/gohugoio/hugo; \
|
||||||
|
fi
|
||||||
|
cd docs; make trans-copy clean build-offline;
|
||||||
|
|
||||||
node_modules: package-lock.json
|
node_modules: package-lock.json
|
||||||
npm install --no-save
|
npm install --no-save
|
||||||
@touch node_modules
|
@touch node_modules
|
||||||
|
@ -582,15 +609,15 @@ npm-update: node-check | node_modules
|
||||||
npx updates -cu
|
npx updates -cu
|
||||||
rm -rf node_modules package-lock.json
|
rm -rf node_modules package-lock.json
|
||||||
npm install --package-lock
|
npm install --package-lock
|
||||||
|
@touch node_modules
|
||||||
|
|
||||||
.PHONY: fomantic
|
.PHONY: fomantic
|
||||||
fomantic: $(FOMANTIC_DEST)
|
fomantic: $(FOMANTIC_DEST)
|
||||||
|
|
||||||
$(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) package-lock.json | node_modules
|
$(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) | node_modules
|
||||||
rm -rf $(FOMANTIC_DEST_DIR)
|
rm -rf $(FOMANTIC_DEST_DIR)
|
||||||
cp web_src/fomantic/theme.config.less node_modules/fomantic-ui/src/theme.config
|
cp web_src/fomantic/theme.config.less node_modules/fomantic-ui/src/theme.config
|
||||||
cp -r web_src/fomantic/_site/* node_modules/fomantic-ui/src/_site/
|
cp -r web_src/fomantic/_site/* node_modules/fomantic-ui/src/_site/
|
||||||
cp web_src/fomantic/css.js node_modules/fomantic-ui/tasks/build/css.js
|
|
||||||
npx gulp -f node_modules/fomantic-ui/gulpfile.js build
|
npx gulp -f node_modules/fomantic-ui/gulpfile.js build
|
||||||
@touch $(FOMANTIC_DEST)
|
@touch $(FOMANTIC_DEST)
|
||||||
|
|
||||||
|
@ -598,10 +625,25 @@ $(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) package-lock.json | node_modules
|
||||||
webpack: $(WEBPACK_DEST)
|
webpack: $(WEBPACK_DEST)
|
||||||
|
|
||||||
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules
|
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules
|
||||||
rm -rf $(WEBPACK_DEST_DIRS)
|
rm -rf $(WEBPACK_DEST_ENTRIES)
|
||||||
npx webpack --hide-modules --display-entrypoints=false
|
npx webpack --hide-modules --display-entrypoints=false
|
||||||
@touch $(WEBPACK_DEST)
|
@touch $(WEBPACK_DEST)
|
||||||
|
|
||||||
|
.PHONY: svg
|
||||||
|
svg: node-check | node_modules
|
||||||
|
rm -rf $(SVG_DEST_DIR)
|
||||||
|
node build/generate-svg.js
|
||||||
|
|
||||||
|
.PHONY: svg-check
|
||||||
|
svg-check: svg
|
||||||
|
@git add $(SVG_DEST_DIR)
|
||||||
|
@diff=$$(git diff --cached $(SVG_DEST_DIR)); \
|
||||||
|
if [ -n "$$diff" ]; then \
|
||||||
|
echo "Please run 'make svg' and 'git add $(SVG_DEST_DIR)' and commit the result:"; \
|
||||||
|
echo "$${diff}"; \
|
||||||
|
exit 1; \
|
||||||
|
fi;
|
||||||
|
|
||||||
.PHONY: update-translations
|
.PHONY: update-translations
|
||||||
update-translations:
|
update-translations:
|
||||||
mkdir -p ./translations
|
mkdir -p ./translations
|
||||||
|
@ -614,34 +656,8 @@ update-translations:
|
||||||
|
|
||||||
.PHONY: generate-images
|
.PHONY: generate-images
|
||||||
generate-images:
|
generate-images:
|
||||||
$(eval TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'gitea-temp'))
|
npm install --no-save --no-package-lock xmldom fabric imagemin-zopfli
|
||||||
mkdir -p $(TMPDIR)/images
|
node build/generate-images.js
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 880 -h 880 -e $(PWD)/public/img/gitea-lg.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 512 -h 512 -e $(PWD)/public/img/gitea-512.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 192 -h 192 -e $(PWD)/public/img/gitea-192.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer1 -e $(TMPDIR)/images/sm-1.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 120 -h 120 -jC -i layer2 -e $(TMPDIR)/images/sm-2.png
|
|
||||||
composite -compose atop $(TMPDIR)/images/sm-2.png $(TMPDIR)/images/sm-1.png $(PWD)/public/img/gitea-sm.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 200 -h 200 -e $(PWD)/public/img/avatar_default.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 180 -h 180 -e $(PWD)/public/img/favicon.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 128 -h 128 -e $(TMPDIR)/images/128-raw.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 64 -h 64 -e $(TMPDIR)/images/64-raw.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 32 -h 32 -jC -i layer1 -e $(TMPDIR)/images/32-1.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 32 -h 32 -jC -i layer2 -e $(TMPDIR)/images/32-2.png
|
|
||||||
composite -compose atop $(TMPDIR)/images/32-2.png $(TMPDIR)/images/32-1.png $(TMPDIR)/images/32-raw.png
|
|
||||||
inkscape -f $(PWD)/assets/logo.svg -w 16 -h 16 -jC -i layer1 -e $(TMPDIR)/images/16-raw.png
|
|
||||||
zopflipng -m -y $(TMPDIR)/images/128-raw.png $(TMPDIR)/images/128.png
|
|
||||||
zopflipng -m -y $(TMPDIR)/images/64-raw.png $(TMPDIR)/images/64.png
|
|
||||||
zopflipng -m -y $(TMPDIR)/images/32-raw.png $(TMPDIR)/images/32.png
|
|
||||||
zopflipng -m -y $(TMPDIR)/images/16-raw.png $(TMPDIR)/images/16.png
|
|
||||||
rm -f $(TMPDIR)/images/*-*.png
|
|
||||||
convert $(TMPDIR)/images/16.png $(TMPDIR)/images/32.png \
|
|
||||||
$(TMPDIR)/images/64.png $(TMPDIR)/images/128.png \
|
|
||||||
$(PWD)/public/img/favicon.ico
|
|
||||||
convert -flatten $(PWD)/public/img/favicon.png $(PWD)/public/img/apple-touch-icon.png
|
|
||||||
|
|
||||||
rm -rf $(TMPDIR)/images
|
|
||||||
$(foreach file, $(shell find public/img -type f -name '*.png' ! -name 'loading.png'),zopflipng -m -y $(file) $(file);)
|
|
||||||
|
|
||||||
.PHONY: pr\#%
|
.PHONY: pr\#%
|
||||||
pr\#%: clean-all
|
pr\#%: clean-all
|
||||||
|
@ -655,5 +671,14 @@ golangci-lint:
|
||||||
fi
|
fi
|
||||||
golangci-lint run --timeout 5m
|
golangci-lint run --timeout 5m
|
||||||
|
|
||||||
|
.PHONY: docker
|
||||||
|
docker:
|
||||||
|
docker build --disable-content-trust=false -t $(DOCKER_REF) .
|
||||||
|
# support also build args docker build --build-arg GITEA_VERSION=v1.2.3 --build-arg TAGS="bindata sqlite sqlite_unlock_notify" .
|
||||||
|
|
||||||
|
.PHONY: docker-build
|
||||||
|
docker-build:
|
||||||
|
docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" CGO_EXTRA_CFLAGS="$(CGO_EXTRA_CFLAGS)" webhippie/golang:edge make clean build
|
||||||
|
|
||||||
# This endif closes the if at the top of the file
|
# This endif closes the if at the top of the file
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<h1> <img src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea-192.png" alt="logo" width="30" height="30"> Gitea - Git with a cup of tea</h1>
|
<h1> <img src="https://raw.githubusercontent.com/go-gitea/gitea/master/public/img/gitea-192.png" alt="logo" width="30" height="30"> Gitea - Git with a cup of tea</h1>
|
||||||
|
|
||||||
[](https://drone.gitea.io/go-gitea/gitea)
|
[](https://drone.gitea.io/go-gitea/gitea)
|
||||||
[](https://discord.gg/Gitea)
|
[](https://discord.gg/Gitea)
|
||||||
[](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
|
[](https://microbadger.com/images/gitea/gitea "Get your own image badge on microbadger.com")
|
||||||
[](https://codecov.io/gh/go-gitea/gitea)
|
[](https://codecov.io/gh/go-gitea/gitea)
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
[](https://opencollective.com/gitea)
|
[](https://opencollective.com/gitea)
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://crowdin.com/project/gitea)
|
[](https://crowdin.com/project/gitea)
|
||||||
|
[](https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea)
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -115,6 +115,7 @@
|
||||||
<g
|
<g
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer3"
|
id="layer3"
|
||||||
|
class="detail-remove"
|
||||||
inkscape:label="Layer 3"
|
inkscape:label="Layer 3"
|
||||||
style="display:inline">
|
style="display:inline">
|
||||||
<g
|
<g
|
||||||
|
@ -157,4 +158,4 @@
|
||||||
style="fill:none;stroke:#609926;stroke-width:2.68000007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
style="fill:none;stroke:#609926;stroke-width:2.68000007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
@ -19,6 +19,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -39,6 +40,7 @@ type Emoji struct {
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
Aliases []string `json:"aliases"`
|
Aliases []string `json:"aliases"`
|
||||||
UnicodeVersion string `json:"unicode_version,omitempty"`
|
UnicodeVersion string `json:"unicode_version,omitempty"`
|
||||||
|
SkinTones bool `json:"skin_tones,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't include some fields in JSON
|
// Don't include some fields in JSON
|
||||||
|
@ -47,6 +49,7 @@ func (e Emoji) MarshalJSON() ([]byte, error) {
|
||||||
x := emoji(e)
|
x := emoji(e)
|
||||||
x.UnicodeVersion = ""
|
x.UnicodeVersion = ""
|
||||||
x.Description = ""
|
x.Description = ""
|
||||||
|
x.SkinTones = false
|
||||||
return json.Marshal(x)
|
return json.Marshal(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +78,7 @@ var replacer = strings.NewReplacer(
|
||||||
", Description:", ", ",
|
", Description:", ", ",
|
||||||
", Aliases:", ", ",
|
", Aliases:", ", ",
|
||||||
", UnicodeVersion:", ", ",
|
", UnicodeVersion:", ", ",
|
||||||
|
", SkinTones:", ", ",
|
||||||
)
|
)
|
||||||
|
|
||||||
var emojiRE = regexp.MustCompile(`\{Emoji:"([^"]*)"`)
|
var emojiRE = regexp.MustCompile(`\{Emoji:"([^"]*)"`)
|
||||||
|
@ -102,18 +106,20 @@ func generate() ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var re = regexp.MustCompile(`keycap|registered|copyright`)
|
var skinTones = make(map[string]string)
|
||||||
tmp := data[:0]
|
|
||||||
|
|
||||||
// filter out emoji that require greater than max unicode version
|
skinTones["\U0001f3fb"] = "Light Skin Tone"
|
||||||
|
skinTones["\U0001f3fc"] = "Medium-Light Skin Tone"
|
||||||
|
skinTones["\U0001f3fd"] = "Medium Skin Tone"
|
||||||
|
skinTones["\U0001f3fe"] = "Medium-Dark Skin Tone"
|
||||||
|
skinTones["\U0001f3ff"] = "Dark Skin Tone"
|
||||||
|
|
||||||
|
var tmp Gemoji
|
||||||
|
|
||||||
|
//filter out emoji that require greater than max unicode version
|
||||||
for i := range data {
|
for i := range data {
|
||||||
val, _ := strconv.ParseFloat(data[i].UnicodeVersion, 64)
|
val, _ := strconv.ParseFloat(data[i].UnicodeVersion, 64)
|
||||||
if int(val) <= maxUnicodeVersion {
|
if int(val) <= maxUnicodeVersion {
|
||||||
// remove these keycaps for now they really complicate matching since
|
|
||||||
// they include normal letters in them
|
|
||||||
if re.MatchString(data[i].Description) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
tmp = append(tmp, data[i])
|
tmp = append(tmp, data[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +129,6 @@ func generate() ([]byte, error) {
|
||||||
return data[i].Aliases[0] < data[j].Aliases[0]
|
return data[i].Aliases[0] < data[j].Aliases[0]
|
||||||
})
|
})
|
||||||
|
|
||||||
aliasPairs := make([]string, 0)
|
|
||||||
aliasMap := make(map[string]int, len(data))
|
aliasMap := make(map[string]int, len(data))
|
||||||
|
|
||||||
for i, e := range data {
|
for i, e := range data {
|
||||||
|
@ -135,7 +140,6 @@ func generate() ([]byte, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
aliasMap[a] = i
|
aliasMap[a] = i
|
||||||
aliasPairs = append(aliasPairs, ":"+a+":", e.Emoji)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +153,43 @@ func generate() ([]byte, error) {
|
||||||
data[i].Aliases = append(data[i].Aliases, "laugh")
|
data[i].Aliases = append(data[i].Aliases, "laugh")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write a JSON file to use with tribute (write before adding skin tones since we can't support them there yet)
|
||||||
|
file, _ := json.Marshal(data)
|
||||||
|
_ = ioutil.WriteFile("assets/emoji.json", file, 0644)
|
||||||
|
|
||||||
|
// Add skin tones to emoji that support it
|
||||||
|
var (
|
||||||
|
s []string
|
||||||
|
newEmoji string
|
||||||
|
newDescription string
|
||||||
|
newData Emoji
|
||||||
|
)
|
||||||
|
|
||||||
|
for i := range data {
|
||||||
|
if data[i].SkinTones {
|
||||||
|
for k, v := range skinTones {
|
||||||
|
s = strings.Split(data[i].Emoji, "")
|
||||||
|
|
||||||
|
if utf8.RuneCountInString(data[i].Emoji) == 1 {
|
||||||
|
s = append(s, k)
|
||||||
|
} else {
|
||||||
|
// insert into slice after first element because all emoji that support skin tones
|
||||||
|
// have that modifer placed at this spot
|
||||||
|
s = append(s, "")
|
||||||
|
copy(s[2:], s[1:])
|
||||||
|
s[1] = k
|
||||||
|
}
|
||||||
|
|
||||||
|
newEmoji = strings.Join(s, "")
|
||||||
|
newDescription = data[i].Description + ": " + v
|
||||||
|
newAlias := data[i].Aliases[0] + "_" + strings.ReplaceAll(v, " ", "_")
|
||||||
|
|
||||||
|
newData = Emoji{newEmoji, newDescription, []string{newAlias}, "12.0", false}
|
||||||
|
data = append(data, newData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add header
|
// add header
|
||||||
str := replacer.Replace(fmt.Sprintf(hdr, gemojiURL, data))
|
str := replacer.Replace(fmt.Sprintf(hdr, gemojiURL, data))
|
||||||
|
|
||||||
|
@ -162,10 +203,6 @@ func generate() ([]byte, error) {
|
||||||
return "{" + strconv.QuoteToASCII(s)
|
return "{" + strconv.QuoteToASCII(s)
|
||||||
})
|
})
|
||||||
|
|
||||||
// write a JSON file to use with tribute
|
|
||||||
file, _ := json.Marshal(data)
|
|
||||||
_ = ioutil.WriteFile("assets/emoji.json", file, 0644)
|
|
||||||
|
|
||||||
// format
|
// format
|
||||||
return format.Source([]byte(str))
|
return format.Source([]byte(str))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const imageminZopfli = require('imagemin-zopfli');
|
||||||
|
const {fabric} = require('fabric');
|
||||||
|
const {DOMParser, XMLSerializer} = require('xmldom');
|
||||||
|
const {readFile, writeFile} = require('fs').promises;
|
||||||
|
const {resolve} = require('path');
|
||||||
|
|
||||||
|
function exit(err) {
|
||||||
|
if (err) console.error(err);
|
||||||
|
process.exit(err ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSvg(svg) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
fabric.loadSVGFromString(svg, (objects, options) => {
|
||||||
|
resolve({objects, options});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generate(svg, outputFile, {size, bg, removeDetail} = {}) {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const serializer = new XMLSerializer();
|
||||||
|
const document = parser.parseFromString(svg);
|
||||||
|
|
||||||
|
if (removeDetail) {
|
||||||
|
for (const el of Array.from(document.getElementsByTagName('g') || [])) {
|
||||||
|
for (const attribute of Array.from(el.attributes || [])) {
|
||||||
|
if (attribute.name === 'class' && attribute.value === 'detail-remove') {
|
||||||
|
el.parentNode.removeChild(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg = serializer.serializeToString(document);
|
||||||
|
|
||||||
|
const {objects, options} = await loadSvg(svg);
|
||||||
|
const canvas = new fabric.Canvas();
|
||||||
|
canvas.setDimensions({width: size, height: size});
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.scale(options.width ? (size / options.width) : 1, options.height ? (size / options.height) : 1);
|
||||||
|
|
||||||
|
if (bg) {
|
||||||
|
canvas.add(new fabric.Rect({
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
height: size * (1 / (size / options.height)),
|
||||||
|
width: size * (1 / (size / options.width)),
|
||||||
|
fill: 'white',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.add(fabric.util.groupSVGElements(objects, options));
|
||||||
|
canvas.renderAll();
|
||||||
|
|
||||||
|
let png = Buffer.from([]);
|
||||||
|
for await (const chunk of canvas.createPNGStream()) {
|
||||||
|
png = Buffer.concat([png, chunk]);
|
||||||
|
}
|
||||||
|
|
||||||
|
png = await imageminZopfli({more: true})(png);
|
||||||
|
await writeFile(outputFile, png);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const svg = await readFile(resolve(__dirname, '../assets/logo.svg'), 'utf8');
|
||||||
|
await generate(svg, resolve(__dirname, '../public/img/gitea-lg.png'), {size: 880});
|
||||||
|
await generate(svg, resolve(__dirname, '../public/img/gitea-512.png'), {size: 512});
|
||||||
|
await generate(svg, resolve(__dirname, '../public/img/gitea-192.png'), {size: 192});
|
||||||
|
await generate(svg, resolve(__dirname, '../public/img/gitea-sm.png'), {size: 120});
|
||||||
|
await generate(svg, resolve(__dirname, '../public/img/avatar_default.png'), {size: 200});
|
||||||
|
await generate(svg, resolve(__dirname, '../public/img/favicon.png'), {size: 180, removeDetail: true});
|
||||||
|
await generate(svg, resolve(__dirname, '../public/img/apple-touch-icon.png'), {size: 180, bg: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
main().then(exit).catch(exit);
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const fastGlob = require('fast-glob');
|
||||||
|
const Svgo = require('svgo');
|
||||||
|
const {resolve, parse} = require('path');
|
||||||
|
const {readFile, writeFile, mkdir} = require('fs').promises;
|
||||||
|
|
||||||
|
const glob = (pattern) => fastGlob.sync(pattern, {cwd: resolve(__dirname), absolute: true});
|
||||||
|
const outputDir = resolve(__dirname, '../public/img/svg');
|
||||||
|
|
||||||
|
function exit(err) {
|
||||||
|
if (err) console.error(err);
|
||||||
|
process.exit(err ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processFile(file, {prefix = ''} = {}) {
|
||||||
|
let name = parse(file).name;
|
||||||
|
if (prefix) name = `${prefix}-${name}`;
|
||||||
|
if (prefix === 'octicon') name = name.replace(/-[0-9]+$/, ''); // chop of '-16' on octicons
|
||||||
|
|
||||||
|
const svgo = new Svgo({
|
||||||
|
plugins: [
|
||||||
|
{removeXMLNS: true},
|
||||||
|
{removeDimensions: true},
|
||||||
|
{
|
||||||
|
addClassesToSVGElement: {
|
||||||
|
classNames: [
|
||||||
|
'svg',
|
||||||
|
name,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
addAttributesToSVGElement: {
|
||||||
|
attributes: [
|
||||||
|
{'width': '16'},
|
||||||
|
{'height': '16'},
|
||||||
|
{'aria-hidden': 'true'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const {data} = await svgo.optimize(await readFile(file, 'utf8'));
|
||||||
|
await writeFile(resolve(outputDir, `${name}.svg`), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
await mkdir(outputDir);
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
for (const file of glob('../node_modules/@primer/octicons/build/svg/*-16.svg')) {
|
||||||
|
await processFile(file, {prefix: 'octicon'});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of glob('../web_src/svg/*.svg')) {
|
||||||
|
await processFile(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().then(exit).catch(exit);
|
||||||
|
|
113
cmd/doctor.go
113
cmd/doctor.go
|
@ -85,10 +85,16 @@ var checklist = []check{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Check Database Version",
|
title: "Check Database Version",
|
||||||
name: "check-db",
|
name: "check-db-version",
|
||||||
isDefault: true,
|
isDefault: true,
|
||||||
f: runDoctorCheckDBVersion,
|
f: runDoctorCheckDBVersion,
|
||||||
abortIfFailed: true,
|
abortIfFailed: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Check consistency of database",
|
||||||
|
name: "check-db-consistency",
|
||||||
|
isDefault: false,
|
||||||
|
f: runDoctorCheckDBConsistency,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Check if OpenSSH authorized_keys file is up-to-date",
|
title: "Check if OpenSSH authorized_keys file is up-to-date",
|
||||||
|
@ -114,6 +120,12 @@ var checklist = []check{
|
||||||
isDefault: false,
|
isDefault: false,
|
||||||
f: runDoctorPRMergeBase,
|
f: runDoctorPRMergeBase,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Recalculate Stars number for all user",
|
||||||
|
name: "recalculate_stars_number",
|
||||||
|
isDefault: false,
|
||||||
|
f: runDoctorUserStarNum,
|
||||||
|
},
|
||||||
// more checks please append here
|
// more checks please append here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,6 +500,10 @@ func runDoctorPRMergeBase(ctx *cli.Context) ([]string, error) {
|
||||||
return results, err
|
return results, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runDoctorUserStarNum(ctx *cli.Context) ([]string, error) {
|
||||||
|
return nil, models.DoctorUserStarNum()
|
||||||
|
}
|
||||||
|
|
||||||
func runDoctorScriptType(ctx *cli.Context) ([]string, error) {
|
func runDoctorScriptType(ctx *cli.Context) ([]string, error) {
|
||||||
path, err := exec.LookPath(setting.ScriptType)
|
path, err := exec.LookPath(setting.ScriptType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -495,3 +511,96 @@ func runDoctorScriptType(ctx *cli.Context) ([]string, error) {
|
||||||
}
|
}
|
||||||
return []string{fmt.Sprintf("ScriptType %s is on the current PATH at %s", setting.ScriptType, path)}, nil
|
return []string{fmt.Sprintf("ScriptType %s is on the current PATH at %s", setting.ScriptType, path)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runDoctorCheckDBConsistency(ctx *cli.Context) ([]string, error) {
|
||||||
|
var results []string
|
||||||
|
|
||||||
|
// make sure DB version is uptodate
|
||||||
|
if err := models.NewEngine(context.Background(), migrations.EnsureUpToDate); err != nil {
|
||||||
|
return nil, fmt.Errorf("model version on the database does not match the current Gitea version. Model consistency will not be checked until the database is upgraded")
|
||||||
|
}
|
||||||
|
|
||||||
|
//find labels without existing repo or org
|
||||||
|
count, err := models.CountOrphanedLabels()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
if ctx.Bool("fix") {
|
||||||
|
if err = models.DeleteOrphanedLabels(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("%d labels without existing repository/organisation deleted", count))
|
||||||
|
} else {
|
||||||
|
results = append(results, fmt.Sprintf("%d labels without existing repository/organisation", count))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//find issues without existing repository
|
||||||
|
count, err = models.CountOrphanedIssues()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
if ctx.Bool("fix") {
|
||||||
|
if err = models.DeleteOrphanedIssues(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("%d issues without existing repository deleted", count))
|
||||||
|
} else {
|
||||||
|
results = append(results, fmt.Sprintf("%d issues without existing repository", count))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//find pulls without existing issues
|
||||||
|
count, err = models.CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
if ctx.Bool("fix") {
|
||||||
|
if err = models.DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id"); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("%d pull requests without existing issue deleted", count))
|
||||||
|
} else {
|
||||||
|
results = append(results, fmt.Sprintf("%d pull requests without existing issue", count))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//find tracked times without existing issues/pulls
|
||||||
|
count, err = models.CountOrphanedObjects("tracked_time", "issue", "tracked_time.issue_id=issue.id")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
if ctx.Bool("fix") {
|
||||||
|
if err = models.DeleteOrphanedObjects("tracked_time", "issue", "tracked_time.issue_id=issue.id"); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("%d tracked times without existing issue deleted", count))
|
||||||
|
} else {
|
||||||
|
results = append(results, fmt.Sprintf("%d tracked times without existing issue", count))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err = models.CountNullArchivedRepository()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
if ctx.Bool("fix") {
|
||||||
|
updatedCount, err := models.FixNullArchivedRepository()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("%d repositories with null is_archived updated", updatedCount))
|
||||||
|
} else {
|
||||||
|
results = append(results, fmt.Sprintf("%d repositories with null is_archived", count))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ToDo: function to recalc all counters
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
273
cmd/dump.go
273
cmd/dump.go
|
@ -6,22 +6,120 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"github.com/unknwon/cae/zip"
|
"gitea.com/macaron/session"
|
||||||
|
archiver "github.com/mholt/archiver/v3"
|
||||||
"github.com/unknwon/com"
|
"github.com/unknwon/com"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func addFile(w archiver.Writer, filePath string, absPath string, verbose bool) error {
|
||||||
|
if verbose {
|
||||||
|
log.Info("Adding file %s\n", filePath)
|
||||||
|
}
|
||||||
|
file, err := os.Open(absPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
fileInfo, err := file.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.Write(archiver.File{
|
||||||
|
FileInfo: archiver.FileInfo{
|
||||||
|
FileInfo: fileInfo,
|
||||||
|
CustomName: filePath,
|
||||||
|
},
|
||||||
|
ReadCloser: file,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func addRecursive(w archiver.Writer, dirPath string, absPath string, verbose bool) error {
|
||||||
|
if verbose {
|
||||||
|
log.Info("Adding dir %s\n", dirPath)
|
||||||
|
}
|
||||||
|
dir, err := os.Open(absPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Could not open directory %s: %s", absPath, err)
|
||||||
|
}
|
||||||
|
files, err := dir.Readdir(0)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Unable to list files in %s: %s", absPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := addFile(w, dirPath, absPath, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fileInfo := range files {
|
||||||
|
if fileInfo.IsDir() {
|
||||||
|
err = addRecursive(w, filepath.Join(dirPath, fileInfo.Name()), filepath.Join(absPath, fileInfo.Name()), verbose)
|
||||||
|
} else {
|
||||||
|
err = addFile(w, filepath.Join(dirPath, fileInfo.Name()), filepath.Join(absPath, fileInfo.Name()), verbose)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSubdir(upper string, lower string) (bool, error) {
|
||||||
|
if relPath, err := filepath.Rel(upper, lower); err != nil {
|
||||||
|
return false, err
|
||||||
|
} else if relPath == "." || !strings.HasPrefix(relPath, ".") {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type outputType struct {
|
||||||
|
Enum []string
|
||||||
|
Default string
|
||||||
|
selected string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o outputType) Join() string {
|
||||||
|
return strings.Join(o.Enum, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *outputType) Set(value string) error {
|
||||||
|
for _, enum := range o.Enum {
|
||||||
|
if enum == value {
|
||||||
|
o.selected = value
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("allowed values are %s", o.Join())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o outputType) String() string {
|
||||||
|
if o.selected == "" {
|
||||||
|
return o.Default
|
||||||
|
}
|
||||||
|
return o.selected
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputTypeEnum = &outputType{
|
||||||
|
Enum: []string{"zip", "tar", "tar.gz", "tar.xz", "tar.bz2"},
|
||||||
|
Default: "zip",
|
||||||
|
}
|
||||||
|
|
||||||
// CmdDump represents the available dump sub-command.
|
// CmdDump represents the available dump sub-command.
|
||||||
var CmdDump = cli.Command{
|
var CmdDump = cli.Command{
|
||||||
Name: "dump",
|
Name: "dump",
|
||||||
|
@ -33,7 +131,7 @@ It can be used for backup and capture Gitea server image to send to maintainer`,
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "file, f",
|
Name: "file, f",
|
||||||
Value: fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()),
|
Value: fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()),
|
||||||
Usage: "Name of the dump file which will be created.",
|
Usage: "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "verbose, V",
|
Name: "verbose, V",
|
||||||
|
@ -56,6 +154,11 @@ It can be used for backup and capture Gitea server image to send to maintainer`,
|
||||||
Name: "skip-log, L",
|
Name: "skip-log, L",
|
||||||
Usage: "Skip the log dumping",
|
Usage: "Skip the log dumping",
|
||||||
},
|
},
|
||||||
|
cli.GenericFlag{
|
||||||
|
Name: "type",
|
||||||
|
Value: outputTypeEnum,
|
||||||
|
Usage: fmt.Sprintf("Dump output format: %s", outputTypeEnum.Join()),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +168,23 @@ func fatal(format string, args ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDump(ctx *cli.Context) error {
|
func runDump(ctx *cli.Context) error {
|
||||||
|
var file *os.File
|
||||||
|
fileName := ctx.String("file")
|
||||||
|
if fileName == "-" {
|
||||||
|
file = os.Stdout
|
||||||
|
err := log.DelLogger("console")
|
||||||
|
if err != nil {
|
||||||
|
fatal("Deleting default logger failed. Can not write to stdout: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
setting.NewContext()
|
setting.NewContext()
|
||||||
|
// make sure we are logging to the console no matter what the configuration tells us do to
|
||||||
|
if _, err := setting.Cfg.Section("log").NewKey("MODE", "console"); err != nil {
|
||||||
|
fatal("Setting logging mode to console failed: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := setting.Cfg.Section("log.console").NewKey("STDERR", "true"); err != nil {
|
||||||
|
fatal("Setting console logger to stderr failed: %v", err)
|
||||||
|
}
|
||||||
setting.NewServices() // cannot access session settings otherwise
|
setting.NewServices() // cannot access session settings otherwise
|
||||||
|
|
||||||
err := models.SetEngine()
|
err := models.SetEngine()
|
||||||
|
@ -73,45 +192,59 @@ func runDump(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpDir := ctx.String("tempdir")
|
if file == nil {
|
||||||
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
|
file, err = os.Create(fileName)
|
||||||
fatal("Path does not exist: %s", tmpDir)
|
if err != nil {
|
||||||
|
fatal("Unable to open %s: %v", fileName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
verbose := ctx.Bool("verbose")
|
||||||
|
outType := ctx.String("type")
|
||||||
|
var iface interface{}
|
||||||
|
if fileName == "-" {
|
||||||
|
iface, err = archiver.ByExtension(fmt.Sprintf(".%s", outType))
|
||||||
|
} else {
|
||||||
|
iface, err = archiver.ByExtension(fileName)
|
||||||
}
|
}
|
||||||
tmpWorkDir, err := ioutil.TempDir(tmpDir, "gitea-dump-")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal("Failed to create tmp work directory: %v", err)
|
fatal("Unable to get archiver for extension: %v", err)
|
||||||
}
|
|
||||||
log.Info("Creating tmp work dir: %s", tmpWorkDir)
|
|
||||||
|
|
||||||
// work-around #1103
|
|
||||||
if os.Getenv("TMPDIR") == "" {
|
|
||||||
os.Setenv("TMPDIR", tmpWorkDir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dbDump := path.Join(tmpWorkDir, "gitea-db.sql")
|
w, _ := iface.(archiver.Writer)
|
||||||
|
if err := w.Create(file); err != nil {
|
||||||
fileName := ctx.String("file")
|
fatal("Creating archiver.Writer failed: %v", err)
|
||||||
log.Info("Packing dump files...")
|
|
||||||
z, err := zip.Create(fileName)
|
|
||||||
if err != nil {
|
|
||||||
fatal("Failed to create %s: %v", fileName, err)
|
|
||||||
}
|
}
|
||||||
|
defer w.Close()
|
||||||
zip.Verbose = ctx.Bool("verbose")
|
|
||||||
|
|
||||||
if ctx.IsSet("skip-repository") && ctx.Bool("skip-repository") {
|
if ctx.IsSet("skip-repository") && ctx.Bool("skip-repository") {
|
||||||
log.Info("Skip dumping local repositories")
|
log.Info("Skip dumping local repositories")
|
||||||
} else {
|
} else {
|
||||||
log.Info("Dumping local repositories...%s", setting.RepoRootPath)
|
log.Info("Dumping local repositories... %s", setting.RepoRootPath)
|
||||||
reposDump := path.Join(tmpWorkDir, "gitea-repo.zip")
|
if err := addRecursive(w, "repos", setting.RepoRootPath, verbose); err != nil {
|
||||||
if err := zip.PackTo(setting.RepoRootPath, reposDump, true); err != nil {
|
fatal("Failed to include repositories: %v", err)
|
||||||
fatal("Failed to dump local repositories: %v", err)
|
|
||||||
}
|
}
|
||||||
if err := z.AddFile("gitea-repo.zip", reposDump); err != nil {
|
|
||||||
fatal("Failed to include gitea-repo.zip: %v", err)
|
if _, err := os.Stat(setting.LFS.ContentPath); !os.IsNotExist(err) {
|
||||||
|
log.Info("Dumping lfs... %s", setting.LFS.ContentPath)
|
||||||
|
if err := addRecursive(w, "lfs", setting.LFS.ContentPath, verbose); err != nil {
|
||||||
|
fatal("Failed to include lfs: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmpDir := ctx.String("tempdir")
|
||||||
|
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
|
||||||
|
fatal("Path does not exist: %s", tmpDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbDump, err := ioutil.TempFile(tmpDir, "gitea-db.sql")
|
||||||
|
if err != nil {
|
||||||
|
fatal("Failed to create tmp file: %v", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(dbDump.Name())
|
||||||
|
|
||||||
targetDBType := ctx.String("database")
|
targetDBType := ctx.String("database")
|
||||||
if len(targetDBType) > 0 && targetDBType != setting.Database.Type {
|
if len(targetDBType) > 0 && targetDBType != setting.Database.Type {
|
||||||
log.Info("Dumping database %s => %s...", setting.Database.Type, targetDBType)
|
log.Info("Dumping database %s => %s...", setting.Database.Type, targetDBType)
|
||||||
|
@ -119,25 +252,29 @@ func runDump(ctx *cli.Context) error {
|
||||||
log.Info("Dumping database...")
|
log.Info("Dumping database...")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := models.DumpDatabase(dbDump, targetDBType); err != nil {
|
if err := models.DumpDatabase(dbDump.Name(), targetDBType); err != nil {
|
||||||
fatal("Failed to dump database: %v", err)
|
fatal("Failed to dump database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := z.AddFile("gitea-db.sql", dbDump); err != nil {
|
if err := addFile(w, "gitea-db.sql", dbDump.Name(), verbose); err != nil {
|
||||||
fatal("Failed to include gitea-db.sql: %v", err)
|
fatal("Failed to include gitea-db.sql: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(setting.CustomConf) > 0 {
|
if len(setting.CustomConf) > 0 {
|
||||||
log.Info("Adding custom configuration file from %s", setting.CustomConf)
|
log.Info("Adding custom configuration file from %s", setting.CustomConf)
|
||||||
if err := z.AddFile("app.ini", setting.CustomConf); err != nil {
|
if err := addFile(w, "app.ini", setting.CustomConf, verbose); err != nil {
|
||||||
fatal("Failed to include specified app.ini: %v", err)
|
fatal("Failed to include specified app.ini: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customDir, err := os.Stat(setting.CustomPath)
|
customDir, err := os.Stat(setting.CustomPath)
|
||||||
if err == nil && customDir.IsDir() {
|
if err == nil && customDir.IsDir() {
|
||||||
if err := z.AddDir("custom", setting.CustomPath); err != nil {
|
if is, _ := isSubdir(setting.AppDataPath, setting.CustomPath); !is {
|
||||||
fatal("Failed to include custom: %v", err)
|
if err := addRecursive(w, "custom", setting.CustomPath, verbose); err != nil {
|
||||||
|
fatal("Failed to include custom: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Info("Custom dir %s is inside data dir %s, skipped", setting.CustomPath, setting.AppDataPath)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Info("Custom dir %s doesn't exist, skipped", setting.CustomPath)
|
log.Info("Custom dir %s doesn't exist, skipped", setting.CustomPath)
|
||||||
|
@ -146,11 +283,19 @@ func runDump(ctx *cli.Context) error {
|
||||||
if com.IsExist(setting.AppDataPath) {
|
if com.IsExist(setting.AppDataPath) {
|
||||||
log.Info("Packing data directory...%s", setting.AppDataPath)
|
log.Info("Packing data directory...%s", setting.AppDataPath)
|
||||||
|
|
||||||
var sessionAbsPath string
|
var excludes []string
|
||||||
if setting.SessionConfig.Provider == "file" {
|
if setting.Cfg.Section("session").Key("PROVIDER").Value() == "file" {
|
||||||
sessionAbsPath = setting.SessionConfig.ProviderConfig
|
var opts session.Options
|
||||||
|
if err = json.Unmarshal([]byte(setting.SessionConfig.ProviderConfig), &opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
excludes = append(excludes, opts.ProviderConfig)
|
||||||
}
|
}
|
||||||
if err := zipAddDirectoryExclude(z, "data", setting.AppDataPath, sessionAbsPath); err != nil {
|
|
||||||
|
excludes = append(excludes, setting.RepoRootPath)
|
||||||
|
excludes = append(excludes, setting.LFS.ContentPath)
|
||||||
|
excludes = append(excludes, setting.LogRootPath)
|
||||||
|
if err := addRecursiveExclude(w, "data", setting.AppDataPath, excludes, verbose); err != nil {
|
||||||
fatal("Failed to include data directory: %v", err)
|
fatal("Failed to include data directory: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,32 +306,42 @@ func runDump(ctx *cli.Context) error {
|
||||||
if ctx.IsSet("skip-log") && ctx.Bool("skip-log") {
|
if ctx.IsSet("skip-log") && ctx.Bool("skip-log") {
|
||||||
log.Info("Skip dumping log files")
|
log.Info("Skip dumping log files")
|
||||||
} else if com.IsExist(setting.LogRootPath) {
|
} else if com.IsExist(setting.LogRootPath) {
|
||||||
if err := z.AddDir("log", setting.LogRootPath); err != nil {
|
if err := addRecursive(w, "log", setting.LogRootPath, verbose); err != nil {
|
||||||
fatal("Failed to include log: %v", err)
|
fatal("Failed to include log: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = z.Close(); err != nil {
|
if fileName != "-" {
|
||||||
_ = os.Remove(fileName)
|
if err = w.Close(); err != nil {
|
||||||
fatal("Failed to save %s: %v", fileName, err)
|
_ = os.Remove(fileName)
|
||||||
|
fatal("Failed to save %s: %v", fileName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Chmod(fileName, 0600); err != nil {
|
||||||
|
log.Info("Can't change file access permissions mask to 0600: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Chmod(fileName, 0600); err != nil {
|
if fileName != "-" {
|
||||||
log.Info("Can't change file access permissions mask to 0600: %v", err)
|
log.Info("Finish dumping in file %s", fileName)
|
||||||
|
} else {
|
||||||
|
log.Info("Finish dumping to stdout")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Removing tmp work dir: %s", tmpWorkDir)
|
|
||||||
|
|
||||||
if err := os.RemoveAll(tmpWorkDir); err != nil {
|
|
||||||
fatal("Failed to remove %s: %v", tmpWorkDir, err)
|
|
||||||
}
|
|
||||||
log.Info("Finish dumping in file %s", fileName)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// zipAddDirectoryExclude zips absPath to specified zipPath inside z excluding excludeAbsPath
|
func contains(slice []string, s string) bool {
|
||||||
func zipAddDirectoryExclude(zip *zip.ZipArchive, zipPath, absPath string, excludeAbsPath string) error {
|
for _, v := range slice {
|
||||||
|
if v == s {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// addRecursiveExclude zips absPath to specified insidePath inside writer excluding excludeAbsPath
|
||||||
|
func addRecursiveExclude(w archiver.Writer, insidePath, absPath string, excludeAbsPath []string, verbose bool) error {
|
||||||
absPath, err := filepath.Abs(absPath)
|
absPath, err := filepath.Abs(absPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -197,24 +352,24 @@ func zipAddDirectoryExclude(zip *zip.ZipArchive, zipPath, absPath string, exclud
|
||||||
}
|
}
|
||||||
defer dir.Close()
|
defer dir.Close()
|
||||||
|
|
||||||
zip.AddEmptyDir(zipPath)
|
|
||||||
|
|
||||||
files, err := dir.Readdir(0)
|
files, err := dir.Readdir(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
currentAbsPath := path.Join(absPath, file.Name())
|
currentAbsPath := path.Join(absPath, file.Name())
|
||||||
currentZipPath := path.Join(zipPath, file.Name())
|
currentInsidePath := path.Join(insidePath, file.Name())
|
||||||
if file.IsDir() {
|
if file.IsDir() {
|
||||||
if currentAbsPath != excludeAbsPath {
|
if !contains(excludeAbsPath, currentAbsPath) {
|
||||||
if err = zipAddDirectoryExclude(zip, currentZipPath, currentAbsPath, excludeAbsPath); err != nil {
|
if err := addFile(w, currentInsidePath, currentAbsPath, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = addRecursiveExclude(w, currentInsidePath, currentAbsPath, excludeAbsPath, verbose); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if err = zip.AddFile(currentZipPath, currentAbsPath); err != nil {
|
if err = addFile(w, currentInsidePath, currentAbsPath, verbose); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,11 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/generate"
|
"code.gitea.io/gitea/modules/generate"
|
||||||
|
|
||||||
|
"github.com/mattn/go-isatty"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -59,7 +61,12 @@ func runGenerateInternalToken(c *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%s\n", internalToken)
|
fmt.Printf("%s", internalToken)
|
||||||
|
|
||||||
|
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +76,12 @@ func runGenerateLfsJwtSecret(c *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%s\n", JWTSecretBase64)
|
fmt.Printf("%s", JWTSecretBase64)
|
||||||
|
|
||||||
|
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +91,11 @@ func runGenerateSecretKey(c *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%s\n", secretKey)
|
fmt.Printf("%s", secretKey)
|
||||||
|
|
||||||
|
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||||
|
fmt.Printf("\n")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
19
cmd/hook.go
19
cmd/hook.go
|
@ -46,18 +46,33 @@ var (
|
||||||
Usage: "Delegate pre-receive Git hook",
|
Usage: "Delegate pre-receive Git hook",
|
||||||
Description: "This command should only be called by Git",
|
Description: "This command should only be called by Git",
|
||||||
Action: runHookPreReceive,
|
Action: runHookPreReceive,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
subcmdHookUpdate = cli.Command{
|
subcmdHookUpdate = cli.Command{
|
||||||
Name: "update",
|
Name: "update",
|
||||||
Usage: "Delegate update Git hook",
|
Usage: "Delegate update Git hook",
|
||||||
Description: "This command should only be called by Git",
|
Description: "This command should only be called by Git",
|
||||||
Action: runHookUpdate,
|
Action: runHookUpdate,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
subcmdHookPostReceive = cli.Command{
|
subcmdHookPostReceive = cli.Command{
|
||||||
Name: "post-receive",
|
Name: "post-receive",
|
||||||
Usage: "Delegate post-receive Git hook",
|
Usage: "Delegate post-receive Git hook",
|
||||||
Description: "This command should only be called by Git",
|
Description: "This command should only be called by Git",
|
||||||
Action: runHookPostReceive,
|
Action: runHookPostReceive,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -138,7 +153,7 @@ func runHookPreReceive(c *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
setup("hooks/pre-receive.log", false)
|
setup("hooks/pre-receive.log", c.Bool("debug"))
|
||||||
|
|
||||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||||
|
@ -273,7 +288,7 @@ func runHookPostReceive(c *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
setup("hooks/post-receive.log", false)
|
setup("hooks/post-receive.log", c.Bool("debug"))
|
||||||
|
|
||||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||||
|
|
380
cmd/manager.go
380
cmd/manager.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/private"
|
"code.gitea.io/gitea/modules/private"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
@ -25,16 +26,27 @@ var (
|
||||||
subcmdShutdown,
|
subcmdShutdown,
|
||||||
subcmdRestart,
|
subcmdRestart,
|
||||||
subcmdFlushQueues,
|
subcmdFlushQueues,
|
||||||
|
subcmdLogging,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
subcmdShutdown = cli.Command{
|
subcmdShutdown = cli.Command{
|
||||||
Name: "shutdown",
|
Name: "shutdown",
|
||||||
Usage: "Gracefully shutdown the running process",
|
Usage: "Gracefully shutdown the running process",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
Action: runShutdown,
|
Action: runShutdown,
|
||||||
}
|
}
|
||||||
subcmdRestart = cli.Command{
|
subcmdRestart = cli.Command{
|
||||||
Name: "restart",
|
Name: "restart",
|
||||||
Usage: "Gracefully restart the running process - (not implemented for windows servers)",
|
Usage: "Gracefully restart the running process - (not implemented for windows servers)",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
Action: runRestart,
|
Action: runRestart,
|
||||||
}
|
}
|
||||||
subcmdFlushQueues = cli.Command{
|
subcmdFlushQueues = cli.Command{
|
||||||
|
@ -46,17 +58,331 @@ var (
|
||||||
Name: "timeout",
|
Name: "timeout",
|
||||||
Value: 60 * time.Second,
|
Value: 60 * time.Second,
|
||||||
Usage: "Timeout for the flushing process",
|
Usage: "Timeout for the flushing process",
|
||||||
},
|
}, cli.BoolFlag{
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "non-blocking",
|
Name: "non-blocking",
|
||||||
Usage: "Set to true to not wait for flush to complete before returning",
|
Usage: "Set to true to not wait for flush to complete before returning",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
defaultLoggingFlags = []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "group, g",
|
||||||
|
Usage: "Group to add logger to - will default to \"default\"",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "name, n",
|
||||||
|
Usage: "Name of the new logger - will default to mode",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "level, l",
|
||||||
|
Usage: "Logging level for the new logger",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "stacktrace-level, L",
|
||||||
|
Usage: "Stacktrace logging level",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "flags, F",
|
||||||
|
Usage: "Flags for the logger",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "expression, e",
|
||||||
|
Usage: "Matching expression for the logger",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "prefix, p",
|
||||||
|
Usage: "Prefix for the logger",
|
||||||
|
}, cli.BoolFlag{
|
||||||
|
Name: "color",
|
||||||
|
Usage: "Use color in the logs",
|
||||||
|
}, cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
subcmdLogging = cli.Command{
|
||||||
|
Name: "logging",
|
||||||
|
Usage: "Adjust logging commands",
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
{
|
||||||
|
Name: "pause",
|
||||||
|
Usage: "Pause logging (Gitea will buffer logs up to a certain point and will drop them after that point)",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: runPauseLogging,
|
||||||
|
}, {
|
||||||
|
Name: "resume",
|
||||||
|
Usage: "Resume logging",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: runResumeLogging,
|
||||||
|
}, {
|
||||||
|
Name: "release-and-reopen",
|
||||||
|
Usage: "Cause Gitea to release and re-open files used for logging",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: runReleaseReopenLogging,
|
||||||
|
}, {
|
||||||
|
Name: "remove",
|
||||||
|
Usage: "Remove a logger",
|
||||||
|
ArgsUsage: "[name] Name of logger to remove",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "group, g",
|
||||||
|
Usage: "Group to add logger to - will default to \"default\"",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: runRemoveLogger,
|
||||||
|
}, {
|
||||||
|
Name: "add",
|
||||||
|
Usage: "Add a logger",
|
||||||
|
Subcommands: []cli.Command{
|
||||||
|
{
|
||||||
|
Name: "console",
|
||||||
|
Usage: "Add a console logger",
|
||||||
|
Flags: append(defaultLoggingFlags,
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "stderr",
|
||||||
|
Usage: "Output console logs to stderr - only relevant for console",
|
||||||
|
}),
|
||||||
|
Action: runAddConsoleLogger,
|
||||||
|
}, {
|
||||||
|
Name: "file",
|
||||||
|
Usage: "Add a file logger",
|
||||||
|
Flags: append(defaultLoggingFlags, []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "filename, f",
|
||||||
|
Usage: "Filename for the logger - this must be set.",
|
||||||
|
}, cli.BoolTFlag{
|
||||||
|
Name: "rotate, r",
|
||||||
|
Usage: "Rotate logs",
|
||||||
|
}, cli.Int64Flag{
|
||||||
|
Name: "max-size, s",
|
||||||
|
Usage: "Maximum size in bytes before rotation",
|
||||||
|
}, cli.BoolTFlag{
|
||||||
|
Name: "daily, d",
|
||||||
|
Usage: "Rotate logs daily",
|
||||||
|
}, cli.IntFlag{
|
||||||
|
Name: "max-days, D",
|
||||||
|
Usage: "Maximum number of daily logs to keep",
|
||||||
|
}, cli.BoolTFlag{
|
||||||
|
Name: "compress, z",
|
||||||
|
Usage: "Compress rotated logs",
|
||||||
|
}, cli.IntFlag{
|
||||||
|
Name: "compression-level, Z",
|
||||||
|
Usage: "Compression level to use",
|
||||||
|
},
|
||||||
|
}...),
|
||||||
|
Action: runAddFileLogger,
|
||||||
|
}, {
|
||||||
|
Name: "conn",
|
||||||
|
Usage: "Add a net conn logger",
|
||||||
|
Flags: append(defaultLoggingFlags, []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "reconnect-on-message, R",
|
||||||
|
Usage: "Reconnect to host for every message",
|
||||||
|
}, cli.BoolFlag{
|
||||||
|
Name: "reconnect, r",
|
||||||
|
Usage: "Reconnect to host when connection is dropped",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "protocol, P",
|
||||||
|
Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "address, a",
|
||||||
|
Usage: "Host address and port to connect to (defaults to :7020)",
|
||||||
|
},
|
||||||
|
}...),
|
||||||
|
Action: runAddConnLogger,
|
||||||
|
}, {
|
||||||
|
Name: "smtp",
|
||||||
|
Usage: "Add an SMTP logger",
|
||||||
|
Flags: append(defaultLoggingFlags, []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "username, u",
|
||||||
|
Usage: "Mail server username",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "password, P",
|
||||||
|
Usage: "Mail server password",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "host, H",
|
||||||
|
Usage: "Mail server host (defaults to: 127.0.0.1:25)",
|
||||||
|
}, cli.StringSliceFlag{
|
||||||
|
Name: "send-to, s",
|
||||||
|
Usage: "Email address(es) to send to",
|
||||||
|
}, cli.StringFlag{
|
||||||
|
Name: "subject, S",
|
||||||
|
Usage: "Subject header of sent emails",
|
||||||
|
},
|
||||||
|
}...),
|
||||||
|
Action: runAddSMTPLogger,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func runRemoveLogger(c *cli.Context) error {
|
||||||
|
setup("manager", c.Bool("debug"))
|
||||||
|
group := c.String("group")
|
||||||
|
if len(group) == 0 {
|
||||||
|
group = log.DEFAULT
|
||||||
|
}
|
||||||
|
name := c.Args().First()
|
||||||
|
statusCode, msg := private.RemoveLogger(group, name)
|
||||||
|
switch statusCode {
|
||||||
|
case http.StatusInternalServerError:
|
||||||
|
fail("InternalServerError", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAddSMTPLogger(c *cli.Context) error {
|
||||||
|
setup("manager", c.Bool("debug"))
|
||||||
|
vals := map[string]interface{}{}
|
||||||
|
mode := "smtp"
|
||||||
|
if c.IsSet("host") {
|
||||||
|
vals["host"] = c.String("host")
|
||||||
|
} else {
|
||||||
|
vals["host"] = "127.0.0.1:25"
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("username") {
|
||||||
|
vals["username"] = c.String("username")
|
||||||
|
}
|
||||||
|
if c.IsSet("password") {
|
||||||
|
vals["password"] = c.String("password")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.IsSet("send-to") {
|
||||||
|
return fmt.Errorf("Some recipients must be provided")
|
||||||
|
}
|
||||||
|
vals["sendTos"] = c.StringSlice("send-to")
|
||||||
|
|
||||||
|
if c.IsSet("subject") {
|
||||||
|
vals["subject"] = c.String("subject")
|
||||||
|
} else {
|
||||||
|
vals["subject"] = "Diagnostic message from Gitea"
|
||||||
|
}
|
||||||
|
|
||||||
|
return commonAddLogger(c, mode, vals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAddConnLogger(c *cli.Context) error {
|
||||||
|
setup("manager", c.Bool("debug"))
|
||||||
|
vals := map[string]interface{}{}
|
||||||
|
mode := "conn"
|
||||||
|
vals["net"] = "tcp"
|
||||||
|
if c.IsSet("protocol") {
|
||||||
|
switch c.String("protocol") {
|
||||||
|
case "udp":
|
||||||
|
vals["net"] = "udp"
|
||||||
|
case "unix":
|
||||||
|
vals["net"] = "unix"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.IsSet("address") {
|
||||||
|
vals["address"] = c.String("address")
|
||||||
|
} else {
|
||||||
|
vals["address"] = ":7020"
|
||||||
|
}
|
||||||
|
if c.IsSet("reconnect") {
|
||||||
|
vals["reconnect"] = c.Bool("reconnect")
|
||||||
|
}
|
||||||
|
if c.IsSet("reconnect-on-message") {
|
||||||
|
vals["reconnectOnMsg"] = c.Bool("reconnect-on-message")
|
||||||
|
}
|
||||||
|
return commonAddLogger(c, mode, vals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAddFileLogger(c *cli.Context) error {
|
||||||
|
setup("manager", c.Bool("debug"))
|
||||||
|
vals := map[string]interface{}{}
|
||||||
|
mode := "file"
|
||||||
|
if c.IsSet("filename") {
|
||||||
|
vals["filename"] = c.String("filename")
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("filename must be set when creating a file logger")
|
||||||
|
}
|
||||||
|
if c.IsSet("rotate") {
|
||||||
|
vals["rotate"] = c.Bool("rotate")
|
||||||
|
}
|
||||||
|
if c.IsSet("max-size") {
|
||||||
|
vals["maxsize"] = c.Int64("max-size")
|
||||||
|
}
|
||||||
|
if c.IsSet("daily") {
|
||||||
|
vals["daily"] = c.Bool("daily")
|
||||||
|
}
|
||||||
|
if c.IsSet("max-days") {
|
||||||
|
vals["maxdays"] = c.Int("max-days")
|
||||||
|
}
|
||||||
|
if c.IsSet("compress") {
|
||||||
|
vals["compress"] = c.Bool("compress")
|
||||||
|
}
|
||||||
|
if c.IsSet("compression-level") {
|
||||||
|
vals["compressionLevel"] = c.Int("compression-level")
|
||||||
|
}
|
||||||
|
return commonAddLogger(c, mode, vals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAddConsoleLogger(c *cli.Context) error {
|
||||||
|
setup("manager", c.Bool("debug"))
|
||||||
|
vals := map[string]interface{}{}
|
||||||
|
mode := "console"
|
||||||
|
if c.IsSet("stderr") && c.Bool("stderr") {
|
||||||
|
vals["stderr"] = c.Bool("stderr")
|
||||||
|
}
|
||||||
|
return commonAddLogger(c, mode, vals)
|
||||||
|
}
|
||||||
|
|
||||||
|
func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) error {
|
||||||
|
if len(c.String("level")) > 0 {
|
||||||
|
vals["level"] = log.FromString(c.String("level")).String()
|
||||||
|
}
|
||||||
|
if len(c.String("stacktrace-level")) > 0 {
|
||||||
|
vals["stacktraceLevel"] = log.FromString(c.String("stacktrace-level")).String()
|
||||||
|
}
|
||||||
|
if len(c.String("expression")) > 0 {
|
||||||
|
vals["expression"] = c.String("expression")
|
||||||
|
}
|
||||||
|
if len(c.String("prefix")) > 0 {
|
||||||
|
vals["prefix"] = c.String("prefix")
|
||||||
|
}
|
||||||
|
if len(c.String("flags")) > 0 {
|
||||||
|
vals["flags"] = log.FlagsFromString(c.String("flags"))
|
||||||
|
}
|
||||||
|
if c.IsSet("color") {
|
||||||
|
vals["colorize"] = c.Bool("color")
|
||||||
|
}
|
||||||
|
group := "default"
|
||||||
|
if c.IsSet("group") {
|
||||||
|
group = c.String("group")
|
||||||
|
}
|
||||||
|
name := mode
|
||||||
|
if c.IsSet("name") {
|
||||||
|
name = c.String("name")
|
||||||
|
}
|
||||||
|
statusCode, msg := private.AddLogger(group, name, mode, vals)
|
||||||
|
switch statusCode {
|
||||||
|
case http.StatusInternalServerError:
|
||||||
|
fail("InternalServerError", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func runShutdown(c *cli.Context) error {
|
func runShutdown(c *cli.Context) error {
|
||||||
setup("manager", false)
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.Shutdown()
|
statusCode, msg := private.Shutdown()
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
|
@ -68,7 +394,7 @@ func runShutdown(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRestart(c *cli.Context) error {
|
func runRestart(c *cli.Context) error {
|
||||||
setup("manager", false)
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.Restart()
|
statusCode, msg := private.Restart()
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
|
@ -80,7 +406,7 @@ func runRestart(c *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runFlushQueues(c *cli.Context) error {
|
func runFlushQueues(c *cli.Context) error {
|
||||||
setup("manager", false)
|
setup("manager", c.Bool("debug"))
|
||||||
statusCode, msg := private.FlushQueues(c.Duration("timeout"), c.Bool("non-blocking"))
|
statusCode, msg := private.FlushQueues(c.Duration("timeout"), c.Bool("non-blocking"))
|
||||||
switch statusCode {
|
switch statusCode {
|
||||||
case http.StatusInternalServerError:
|
case http.StatusInternalServerError:
|
||||||
|
@ -90,3 +416,39 @@ func runFlushQueues(c *cli.Context) error {
|
||||||
fmt.Fprintln(os.Stdout, msg)
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runPauseLogging(c *cli.Context) error {
|
||||||
|
setup("manager", c.Bool("debug"))
|
||||||
|
statusCode, msg := private.PauseLogging()
|
||||||
|
switch statusCode {
|
||||||
|
case http.StatusInternalServerError:
|
||||||
|
fail("InternalServerError", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runResumeLogging(c *cli.Context) error {
|
||||||
|
setup("manager", c.Bool("debug"))
|
||||||
|
statusCode, msg := private.ResumeLogging()
|
||||||
|
switch statusCode {
|
||||||
|
case http.StatusInternalServerError:
|
||||||
|
fail("InternalServerError", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runReleaseReopenLogging(c *cli.Context) error {
|
||||||
|
setup("manager", c.Bool("debug"))
|
||||||
|
statusCode, msg := private.ReleaseReopenLogging()
|
||||||
|
switch statusCode {
|
||||||
|
case http.StatusInternalServerError:
|
||||||
|
fail("InternalServerError", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(os.Stdout, msg)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ package cmd
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
|
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
|
||||||
"os"
|
"os"
|
||||||
|
@ -156,7 +157,7 @@ func runWeb(ctx *cli.Context) error {
|
||||||
|
|
||||||
listenAddr := setting.HTTPAddr
|
listenAddr := setting.HTTPAddr
|
||||||
if setting.Protocol != setting.UnixSocket && setting.Protocol != setting.FCGIUnix {
|
if setting.Protocol != setting.UnixSocket && setting.Protocol != setting.FCGIUnix {
|
||||||
listenAddr += ":" + setting.HTTPPort
|
listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort)
|
||||||
}
|
}
|
||||||
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
|
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<body>
|
<body>
|
||||||
<h1>Privacy Policy</h1>
|
<h1>Privacy Policy</h1>
|
||||||
|
|
||||||
<h4>Last updated: December 28, 2019</h4>
|
<h4>Last updated: January 29, 2020</h4>
|
||||||
|
|
||||||
<h2>Who We Are?</h2>
|
<h2>Who We Are?</h2>
|
||||||
|
|
||||||
|
@ -191,6 +191,6 @@
|
||||||
|
|
||||||
<h2>COPYING</h2>
|
<h2>COPYING</h2>
|
||||||
|
|
||||||
<p>This document is licensed under <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0 Public Domain license</a>.</p>
|
<p>This document is licensed under CC0 Public Domain License. See <a href="https://creativecommons.org/publicdomain/zero/1.0/legalcode">full legal code here</a>.</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<body>
|
<body>
|
||||||
<h1>Terms of Service</h1>
|
<h1>Terms of Service</h1>
|
||||||
|
|
||||||
<h4>Last updated: December 31, 2019</h4>
|
<h4>Last updated: January 29, 2020</h4>
|
||||||
|
|
||||||
<p>Thank you for choosing Your Gitea Instance! Before you use it, please read this Terms of Service agreement carefully, which contains important contract between us and our users.</p>
|
<p>Thank you for choosing Your Gitea Instance! Before you use it, please read this Terms of Service agreement carefully, which contains important contract between us and our users.</p>
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
|
|
||||||
<p>If you'd like to use our trademarks, you must follow all of our trademark guidelines.</p>
|
<p>If you'd like to use our trademarks, you must follow all of our trademark guidelines.</p>
|
||||||
|
|
||||||
<p>This Agreement is licensed under <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO Public Domain License</a>.</p>
|
<p>This Agreement is licensed under <a href="https://creativecommons.org/publicdomain/zero/1.0/legalcode">CCO Public Domain License</a>.</p>
|
||||||
|
|
||||||
<h2>API Terms</h2>
|
<h2>API Terms</h2>
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ import (
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
context2 "github.com/gorilla/context"
|
context2 "github.com/gorilla/context"
|
||||||
"github.com/unknwon/com"
|
"github.com/unknwon/com"
|
||||||
"gopkg.in/testfixtures.v2"
|
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -96,14 +95,12 @@ func runPR() {
|
||||||
setting.Database.LogSQL = true
|
setting.Database.LogSQL = true
|
||||||
//x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
//x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
||||||
|
|
||||||
var helper testfixtures.Helper = &testfixtures.SQLite{}
|
|
||||||
models.NewEngine(context.Background(), func(_ *xorm.Engine) error {
|
models.NewEngine(context.Background(), func(_ *xorm.Engine) error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
models.HasEngine = true
|
models.HasEngine = true
|
||||||
//x.ShowSQL(true)
|
//x.ShowSQL(true)
|
||||||
err = models.InitFixtures(
|
err = models.InitFixtures(
|
||||||
helper,
|
|
||||||
path.Join(curDir, "models/fixtures/"),
|
path.Join(curDir, "models/fixtures/"),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -14,7 +14,12 @@ RUN_MODE = dev
|
||||||
[repository]
|
[repository]
|
||||||
ROOT =
|
ROOT =
|
||||||
SCRIPT_TYPE = bash
|
SCRIPT_TYPE = bash
|
||||||
; Default ANSI charset
|
; DETECTED_CHARSETS_ORDER tie-break order for detected charsets.
|
||||||
|
; If the charsets have equal confidence, tie-breaking will be done by order in this list
|
||||||
|
; with charsets earlier in the list chosen in preference to those later.
|
||||||
|
; Adding "defaults" will place the unused charsets at that position.
|
||||||
|
DETECTED_CHARSETS_ORDER=UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE, ISO-8859, windows-1252, ISO-8859, windows-1250, ISO-8859, ISO-8859, ISO-8859, windows-1253, ISO-8859, windows-1255, ISO-8859, windows-1251, windows-1256, KOI8-R, ISO-8859, windows-1254, Shift_JIS, GB18030, EUC-JP, EUC-KR, Big5, ISO-2022, ISO-2022, ISO-2022, IBM424_rtl, IBM424_ltr, IBM420_rtl, IBM420_ltr
|
||||||
|
; Default ANSI charset to override non-UTF-8 charsets to
|
||||||
ANSI_CHARSET =
|
ANSI_CHARSET =
|
||||||
; Force every new repository to be private
|
; Force every new repository to be private
|
||||||
FORCE_PRIVATE = false
|
FORCE_PRIVATE = false
|
||||||
|
@ -50,6 +55,10 @@ DISABLED_REPO_UNITS =
|
||||||
DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki
|
DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki
|
||||||
; Prefix archive files by placing them in a directory named after the repository
|
; Prefix archive files by placing them in a directory named after the repository
|
||||||
PREFIX_ARCHIVE_FILES = true
|
PREFIX_ARCHIVE_FILES = true
|
||||||
|
; Disable the creation of new mirrors. Pre-existing mirrors remain valid.
|
||||||
|
DISABLE_MIRRORS = false
|
||||||
|
; The default branch name of new repositories
|
||||||
|
DEFAULT_BRANCH=master
|
||||||
|
|
||||||
[repository.editor]
|
[repository.editor]
|
||||||
; List of file extensions for which lines should be wrapped in the Monaco editor
|
; List of file extensions for which lines should be wrapped in the Monaco editor
|
||||||
|
@ -209,14 +218,17 @@ MIN_TIMEOUT = 10s
|
||||||
MAX_TIMEOUT = 60s
|
MAX_TIMEOUT = 60s
|
||||||
TIMEOUT_STEP = 10s
|
TIMEOUT_STEP = 10s
|
||||||
; This setting determines how often the db is queried to get the latest notification counts.
|
; This setting determines how often the db is queried to get the latest notification counts.
|
||||||
; If the browser client supports EventSource, it will be used in preference to polling notification.
|
; If the browser client supports EventSource and SharedWorker, a SharedWorker will be used in preference to polling notification. Set to -1 to disable the EventSource
|
||||||
EVENT_SOURCE_UPDATE_TIME = 10s
|
EVENT_SOURCE_UPDATE_TIME = 10s
|
||||||
|
|
||||||
[markdown]
|
[markdown]
|
||||||
; Render soft line breaks as hard line breaks, which means a single newline character between
|
; Render soft line breaks as hard line breaks, which means a single newline character between
|
||||||
; paragraphs will cause a line break and adding trailing whitespace to paragraphs is not
|
; paragraphs will cause a line break and adding trailing whitespace to paragraphs is not
|
||||||
; necessary to force a line break.
|
; necessary to force a line break.
|
||||||
ENABLE_HARD_LINE_BREAK = true
|
; Render soft line breaks as hard line breaks for comments
|
||||||
|
ENABLE_HARD_LINE_BREAK_IN_COMMENTS = true
|
||||||
|
; Render soft line breaks as hard line breaks for markdown documents
|
||||||
|
ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS = false
|
||||||
; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown
|
; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown
|
||||||
; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes)
|
; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes)
|
||||||
; URLs starting with http and https are always displayed, whatever is put in this entry.
|
; URLs starting with http and https are always displayed, whatever is put in this entry.
|
||||||
|
@ -363,9 +375,9 @@ SCHEMA =
|
||||||
; For Postgres, either "disable" (default), "require", or "verify-full"
|
; For Postgres, either "disable" (default), "require", or "verify-full"
|
||||||
; For MySQL, either "false" (default), "true", or "skip-verify"
|
; For MySQL, either "false" (default), "true", or "skip-verify"
|
||||||
SSL_MODE = disable
|
SSL_MODE = disable
|
||||||
; For MySQL only, either "utf8" or "utf8mb4", default is "utf8".
|
; For MySQL only, either "utf8" or "utf8mb4", default is "utf8mb4".
|
||||||
; NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
|
; NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
|
||||||
CHARSET = utf8
|
CHARSET = utf8mb4
|
||||||
; For "sqlite3" and "tidb", use an absolute path when you start gitea as service
|
; For "sqlite3" and "tidb", use an absolute path when you start gitea as service
|
||||||
PATH = data/gitea.db
|
PATH = data/gitea.db
|
||||||
; For "sqlite3" only. Query timeout
|
; For "sqlite3" only. Query timeout
|
||||||
|
@ -624,23 +636,26 @@ SUBJECT_PREFIX =
|
||||||
; Mail server
|
; Mail server
|
||||||
; Gmail: smtp.gmail.com:587
|
; Gmail: smtp.gmail.com:587
|
||||||
; QQ: smtp.qq.com:465
|
; QQ: smtp.qq.com:465
|
||||||
; Note, if the port ends with "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409. If the server supports STARTTLS it will always be used.
|
; Using STARTTLS on port 587 is recommended per RFC 6409.
|
||||||
|
; Note, if the port ends with "465", SMTPS will be used.
|
||||||
HOST =
|
HOST =
|
||||||
; Disable HELO operation when hostnames are different.
|
; Disable HELO operation when hostnames are different.
|
||||||
DISABLE_HELO =
|
DISABLE_HELO =
|
||||||
; Custom hostname for HELO operation, if no value is provided, one is retrieved from system.
|
; Custom hostname for HELO operation, if no value is provided, one is retrieved from system.
|
||||||
HELO_HOSTNAME =
|
HELO_HOSTNAME =
|
||||||
; Do not verify the certificate of the server. Only use this for self-signed certificates
|
; Whether or not to skip verification of certificates; `true` to disable verification. This option is unsafe. Consider adding the certificate to the system trust store instead.
|
||||||
SKIP_VERIFY =
|
SKIP_VERIFY = false
|
||||||
; Use client certificate
|
; Use client certificate
|
||||||
USE_CERTIFICATE = false
|
USE_CERTIFICATE = false
|
||||||
CERT_FILE = custom/mailer/cert.pem
|
CERT_FILE = custom/mailer/cert.pem
|
||||||
KEY_FILE = custom/mailer/key.pem
|
KEY_FILE = custom/mailer/key.pem
|
||||||
; Should SMTP connection use TLS
|
; Should SMTP connect with TLS, (if port ends with 465 TLS will always be used.)
|
||||||
|
; If this is false but STARTTLS is supported the connection will be upgraded to TLS opportunistically.
|
||||||
IS_TLS_ENABLED = false
|
IS_TLS_ENABLED = false
|
||||||
; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
|
; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
|
||||||
FROM =
|
FROM =
|
||||||
; Mailer user name and password
|
; Mailer user name and password
|
||||||
|
; Please Note: Authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via STARTTLS) or `HOST=localhost`.
|
||||||
USER =
|
USER =
|
||||||
; Use PASSWD = `your password` for quoting if you use special characters in the password.
|
; Use PASSWD = `your password` for quoting if you use special characters in the password.
|
||||||
PASSWD =
|
PASSWD =
|
||||||
|
@ -934,33 +949,8 @@ JWT_SECRET=Bk0yK7Y9g_p56v86KaHqjSbxvNvu3SbKoOdOt2ZcXvU
|
||||||
MAX_TOKEN_LENGTH=32767
|
MAX_TOKEN_LENGTH=32767
|
||||||
|
|
||||||
[i18n]
|
[i18n]
|
||||||
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
|
LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
|
||||||
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
|
NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
|
||||||
|
|
||||||
; Used for datetimepicker
|
|
||||||
[i18n.datelang]
|
|
||||||
en-US = en
|
|
||||||
zh-CN = zh
|
|
||||||
zh-HK = zh-HK
|
|
||||||
zh-TW = zh-TW
|
|
||||||
de-DE = de
|
|
||||||
fr-FR = fr
|
|
||||||
nl-NL = nl
|
|
||||||
lv-LV = lv
|
|
||||||
ru-RU = ru
|
|
||||||
uk-UA = uk
|
|
||||||
ja-JP = ja
|
|
||||||
es-ES = es
|
|
||||||
pt-BR = pt-BR
|
|
||||||
pl-PL = pl
|
|
||||||
bg-BG = bg
|
|
||||||
it-IT = it
|
|
||||||
fi-FI = fi
|
|
||||||
tr-TR = tr
|
|
||||||
cs-CZ = cs-CZ
|
|
||||||
sr-SP = sr
|
|
||||||
sv-SE = sv
|
|
||||||
ko-KR = ko
|
|
||||||
|
|
||||||
[U2F]
|
[U2F]
|
||||||
; NOTE: THE DEFAULT VALUES HERE WILL NEED TO BE CHANGED
|
; NOTE: THE DEFAULT VALUES HERE WILL NEED TO BE CHANGED
|
|
@ -1,14 +0,0 @@
|
||||||
#Makefile related to docker
|
|
||||||
|
|
||||||
DOCKER_IMAGE ?= gitea/gitea
|
|
||||||
DOCKER_TAG ?= latest
|
|
||||||
DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
|
|
||||||
|
|
||||||
.PHONY: docker
|
|
||||||
docker:
|
|
||||||
docker build --disable-content-trust=false -t $(DOCKER_REF) .
|
|
||||||
# support also build args docker build --build-arg GITEA_VERSION=v1.2.3 --build-arg TAGS="bindata sqlite sqlite_unlock_notify" .
|
|
||||||
|
|
||||||
.PHONY: docker-build
|
|
||||||
docker-build:
|
|
||||||
docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" LDFLAGS="$(LDFLAGS)" webhippie/golang:edge make clean build
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Gitea - Docker
|
||||||
|
|
||||||
|
Dockerfile is found in root of repository.
|
||||||
|
|
||||||
|
Docker image can be found on [docker hub](https://hub.docker.com/r/gitea/gitea)
|
||||||
|
|
||||||
|
Documentation on using docker image can be found on [Gitea Docs site](https://docs.gitea.io/en-us/install-with-docker/)
|
|
@ -21,6 +21,10 @@ server: $(THEME)
|
||||||
build: $(THEME)
|
build: $(THEME)
|
||||||
hugo --cleanDestinationDir
|
hugo --cleanDestinationDir
|
||||||
|
|
||||||
|
.PHONY: build-offline
|
||||||
|
build-offline: $(THEME)
|
||||||
|
hugo --baseURL="/" --cleanDestinationDir
|
||||||
|
|
||||||
.PHONY: update
|
.PHONY: update
|
||||||
update: $(THEME)
|
update: $(THEME)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ 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.11.5
|
version: 1.12.2
|
||||||
minGoVersion: 1.12
|
minGoVersion: 1.12
|
||||||
goVersion: 1.14
|
goVersion: 1.14
|
||||||
minNodeVersion: 10.13
|
minNodeVersion: 10.13
|
||||||
|
@ -312,3 +312,50 @@ languages:
|
||||||
url: https://discourse.gitea.io/
|
url: https://discourse.gitea.io/
|
||||||
weight: 80
|
weight: 80
|
||||||
pre: group
|
pre: group
|
||||||
|
|
||||||
|
pt-pt:
|
||||||
|
weight: 6
|
||||||
|
languageName: Português de Portugal
|
||||||
|
menu:
|
||||||
|
page:
|
||||||
|
- name: Página inicial
|
||||||
|
url: https://gitea.io/pt-pt/
|
||||||
|
weight: 10
|
||||||
|
pre: home
|
||||||
|
- name: Documentação
|
||||||
|
url: /pt-pt/
|
||||||
|
weight: 20
|
||||||
|
pre: question
|
||||||
|
post: active
|
||||||
|
- name: API
|
||||||
|
url: https://try.gitea.io/api/swagger
|
||||||
|
weight: 45
|
||||||
|
pre: plug
|
||||||
|
- name: Blog
|
||||||
|
url: https://blog.gitea.io/
|
||||||
|
weight: 30
|
||||||
|
pre: rss
|
||||||
|
- name: Código-fonte
|
||||||
|
url: https://code.gitea.io/
|
||||||
|
weight: 40
|
||||||
|
pre: code
|
||||||
|
- name: Tradução
|
||||||
|
url: https://crowdin.com/project/gitea
|
||||||
|
weight: 41
|
||||||
|
pre: language
|
||||||
|
- name: Descarregamentos
|
||||||
|
url: https://dl.gitea.io/
|
||||||
|
weight: 50
|
||||||
|
pre: download
|
||||||
|
- name: GitHub
|
||||||
|
url: https://github.com/go-gitea/
|
||||||
|
weight: 60
|
||||||
|
pre: github
|
||||||
|
- name: Discussão no Discord
|
||||||
|
url: https://discord.gg/Gitea
|
||||||
|
weight: 70
|
||||||
|
pre: comment
|
||||||
|
- name: Fórum
|
||||||
|
url: https://discourse.gitea.io/
|
||||||
|
weight: 80
|
||||||
|
pre: group
|
||||||
|
|
|
@ -23,7 +23,7 @@ or any corresponding location. When installing from a distribution, this will
|
||||||
typically be found at `/etc/gitea/conf/app.ini`.
|
typically be found at `/etc/gitea/conf/app.ini`.
|
||||||
|
|
||||||
The defaults provided here are best-effort (not built automatically). They are
|
The defaults provided here are best-effort (not built automatically). They are
|
||||||
accurately recorded in [app.ini.sample](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample)
|
accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
|
||||||
(s/master/\<tag|release\>). Any string in the format `%(X)s` is a feature powered
|
(s/master/\<tag|release\>). Any string in the format `%(X)s` is a feature powered
|
||||||
by [ini](https://github.com/go-ini/ini/#recursive-values), for reading values recursively.
|
by [ini](https://github.com/go-ini/ini/#recursive-values), for reading values recursively.
|
||||||
|
|
||||||
|
@ -46,7 +46,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
an absolute path.
|
an absolute path.
|
||||||
- `SCRIPT_TYPE`: **bash**: The script type this server supports. Usually this is `bash`,
|
- `SCRIPT_TYPE`: **bash**: The script type this server supports. Usually this is `bash`,
|
||||||
but some users report that only `sh` is available.
|
but some users report that only `sh` is available.
|
||||||
- `ANSI_CHARSET`: **\<empty\>**: The default charset for an unrecognized charset.
|
- `DETECTED_CHARSETS_ORDER`: **UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE, ISO-8859, windows-1252, ISO-8859, windows-1250, ISO-8859, ISO-8859, ISO-8859, windows-1253, ISO-8859, windows-1255, ISO-8859, windows-1251, windows-1256, KOI8-R, ISO-8859, windows-1254, Shift_JIS, GB18030, EUC-JP, EUC-KR, Big5, ISO-2022, ISO-2022, ISO-2022, IBM424_rtl, IBM424_ltr, IBM420_rtl, IBM420_ltr**: Tie-break order of detected charsets - if the detected charsets have equal confidence, charsets earlier in the list will be chosen in preference to those later. Adding `defaults` will place the unnamed charsets at that point.
|
||||||
|
- `ANSI_CHARSET`: **\<empty\>**: Default ANSI charset to override non-UTF-8 charsets to.
|
||||||
- `FORCE_PRIVATE`: **false**: Force every new repository to be private.
|
- `FORCE_PRIVATE`: **false**: Force every new repository to be private.
|
||||||
- `DEFAULT_PRIVATE`: **last**: Default private when creating a new repository.
|
- `DEFAULT_PRIVATE`: **last**: Default private when creating a new repository.
|
||||||
\[last, private, public\]
|
\[last, private, public\]
|
||||||
|
@ -69,6 +70,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- `ENABLE_PUSH_CREATE_USER`: **false**: Allow users to push local repositories to Gitea and have them automatically created for a user.
|
- `ENABLE_PUSH_CREATE_USER`: **false**: Allow users to push local repositories to Gitea and have them automatically created for a user.
|
||||||
- `ENABLE_PUSH_CREATE_ORG`: **false**: Allow users to push local repositories to Gitea and have them automatically created for an org.
|
- `ENABLE_PUSH_CREATE_ORG`: **false**: Allow users to push local repositories to Gitea and have them automatically created for an org.
|
||||||
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
||||||
|
- `DISABLE_MIRRORS`: **false**: Disable the creation of **new** mirrors. Pre-existing mirrors remain valid.
|
||||||
|
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
|
||||||
|
|
||||||
### Repository - Pull Request (`repository.pull-request`)
|
### Repository - Pull Request (`repository.pull-request`)
|
||||||
|
|
||||||
|
@ -147,12 +150,14 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- `MIN_TIMEOUT`: **10s**: These options control how often notification endpoint is polled to update the notification count. On page load the notification count will be checked after `MIN_TIMEOUT`. The timeout will increase to `MAX_TIMEOUT` by `TIMEOUT_STEP` if the notification count is unchanged. Set MIN_TIMEOUT to 0 to turn off.
|
- `MIN_TIMEOUT`: **10s**: These options control how often notification endpoint is polled to update the notification count. On page load the notification count will be checked after `MIN_TIMEOUT`. The timeout will increase to `MAX_TIMEOUT` by `TIMEOUT_STEP` if the notification count is unchanged. Set MIN_TIMEOUT to 0 to turn off.
|
||||||
- `MAX_TIMEOUT`: **60s**.
|
- `MAX_TIMEOUT`: **60s**.
|
||||||
- `TIMEOUT_STEP`: **10s**.
|
- `TIMEOUT_STEP`: **10s**.
|
||||||
- `EVENT_SOURCE_UPDATE_TIME`: **10s**: This setting determines how often the database is queried to update notification counts. If the browser client supports `EventSource`, it will be used in preference to polling notification endpoint.
|
- `EVENT_SOURCE_UPDATE_TIME`: **10s**: This setting determines how often the database is queried to update notification counts. If the browser client supports `EventSource` and `SharedWorker`, a `SharedWorker` will be used in preference to polling notification endpoint. Set to **-1** to disable the `EventSource`.
|
||||||
|
|
||||||
|
|
||||||
## Markdown (`markdown`)
|
## Markdown (`markdown`)
|
||||||
|
|
||||||
- `ENABLE_HARD_LINE_BREAK`: **true**: Render soft line breaks as hard line breaks, which
|
- `ENABLE_HARD_LINE_BREAK_IN_COMMENTS`: **true**: Render soft line breaks as hard line breaks in comments, which
|
||||||
|
means a single newline character between paragraphs will cause a line break and adding
|
||||||
|
trailing whitespace to paragraphs is not necessary to force a line break.
|
||||||
|
- `ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS`: **false**: Render soft line breaks as hard line breaks in documents, which
|
||||||
means a single newline character between paragraphs will cause a line break and adding
|
means a single newline character between paragraphs will cause a line break and adding
|
||||||
trailing whitespace to paragraphs is not necessary to force a line break.
|
trailing whitespace to paragraphs is not necessary to force a line break.
|
||||||
- `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional
|
- `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional
|
||||||
|
@ -239,7 +244,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- `require`: Enable TLS without any verifications.
|
- `require`: Enable TLS without any verifications.
|
||||||
- `verify-ca`: Enable TLS with verification of the database server certificate against its root certificate.
|
- `verify-ca`: Enable TLS with verification of the database server certificate against its root certificate.
|
||||||
- `verify-full`: Enable TLS and verify the database server name matches the given certificate in either the `Common Name` or `Subject Alternative Name` fields.
|
- `verify-full`: Enable TLS and verify the database server name matches the given certificate in either the `Common Name` or `Subject Alternative Name` fields.
|
||||||
- `CHARSET`: **utf8**: For MySQL only, either "utf8" or "utf8mb4", default is "utf8". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
|
- `CHARSET`: **utf8mb4**: For MySQL only, either "utf8" or "utf8mb4". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
|
||||||
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
|
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
|
||||||
- `LOG_SQL`: **true**: Log the executed SQL.
|
- `LOG_SQL`: **true**: Log the executed SQL.
|
||||||
- `DB_RETRIES`: **10**: How many ORM init / DB connect attempts allowed.
|
- `DB_RETRIES`: **10**: How many ORM init / DB connect attempts allowed.
|
||||||
|
@ -394,11 +399,17 @@ set name for unique queues. Individual queues will default to
|
||||||
- `DISABLE_HELO`: **\<empty\>**: Disable HELO operation.
|
- `DISABLE_HELO`: **\<empty\>**: Disable HELO operation.
|
||||||
- `HELO_HOSTNAME`: **\<empty\>**: Custom hostname for HELO operation.
|
- `HELO_HOSTNAME`: **\<empty\>**: Custom hostname for HELO operation.
|
||||||
- `HOST`: **\<empty\>**: SMTP mail host address and port (example: smtp.gitea.io:587).
|
- `HOST`: **\<empty\>**: SMTP mail host address and port (example: smtp.gitea.io:587).
|
||||||
|
- Using opportunistic TLS via STARTTLS on port 587 is recommended per RFC 6409.
|
||||||
|
- `IS_TLS_ENABLED` : **false** : Forcibly use TLS to connect even if not on a default SMTPS port.
|
||||||
|
- Note, if the port ends with `465` SMTPS/SMTP over TLS will be used despite this setting.
|
||||||
|
- Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`.
|
||||||
- `FROM`: **\<empty\>**: Mail from address, RFC 5322. This can be just an email address, or
|
- `FROM`: **\<empty\>**: Mail from address, RFC 5322. This can be just an email address, or
|
||||||
the "Name" \<email@example.com\> format.
|
the "Name" \<email@example.com\> format.
|
||||||
- `USER`: **\<empty\>**: Username of mailing user (usually the sender's e-mail address).
|
- `USER`: **\<empty\>**: Username of mailing user (usually the sender's e-mail address).
|
||||||
- `PASSWD`: **\<empty\>**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password.
|
- `PASSWD`: **\<empty\>**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password.
|
||||||
- `SKIP_VERIFY`: **\<empty\>**: Do not verify the self-signed certificates.
|
- Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or `HOST=localhost`. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information.
|
||||||
|
- `SKIP_VERIFY`: **false**: Whether or not to skip verification of certificates; `true` to disable verification.
|
||||||
|
- **Warning:** This option is unsafe. Consider adding the certificate to the system trust store instead.
|
||||||
- **Note:** Gitea only supports SMTP with STARTTLS.
|
- **Note:** Gitea only supports SMTP with STARTTLS.
|
||||||
- `SUBJECT_PREFIX`: **\<empty\>**: Prefix to be placed before e-mail subject lines.
|
- `SUBJECT_PREFIX`: **\<empty\>**: Prefix to be placed before e-mail subject lines.
|
||||||
- `MAILER_TYPE`: **smtp**: \[smtp, sendmail, dummy\]
|
- `MAILER_TYPE`: **smtp**: \[smtp, sendmail, dummy\]
|
||||||
|
@ -412,7 +423,6 @@ set name for unique queues. Individual queues will default to
|
||||||
- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be
|
- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be
|
||||||
command or full path).
|
command or full path).
|
||||||
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
|
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
|
||||||
- ``IS_TLS_ENABLED`` : **false** : Decide if SMTP connections should use TLS.
|
|
||||||
|
|
||||||
## Cache (`cache`)
|
## Cache (`cache`)
|
||||||
|
|
||||||
|
@ -460,7 +470,7 @@ set name for unique queues. Individual queues will default to
|
||||||
|
|
||||||
- `ENABLED`: **true**: Enable this to allow uploading attachments.
|
- `ENABLED`: **true**: Enable this to allow uploading attachments.
|
||||||
- `PATH`: **data/attachments**: Path to store attachments.
|
- `PATH`: **data/attachments**: Path to store attachments.
|
||||||
- `ALLOWED_TYPES`: **see app.ini.sample**: Allowed MIME types, e.g. `image/jpeg|image/png`.
|
- `ALLOWED_TYPES`: **see app.example.ini**: Allowed MIME types, e.g. `image/jpeg|image/png`.
|
||||||
Use `*/*` for all types.
|
Use `*/*` for all types.
|
||||||
- `MAX_SIZE`: **4**: Maximum size (MB).
|
- `MAX_SIZE`: **4**: Maximum size (MB).
|
||||||
- `MAX_FILES`: **5**: Maximum number of attachments that can be uploaded at once.
|
- `MAX_FILES`: **5**: Maximum number of attachments that can be uploaded at once.
|
||||||
|
@ -602,33 +612,8 @@ NB: You must `REDIRECT_MACARON_LOG` and have `DISABLE_ROUTER_LOG` set to `false`
|
||||||
|
|
||||||
## i18n (`i18n`)
|
## i18n (`i18n`)
|
||||||
|
|
||||||
- `LANGS`: **en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR**: List of locales shown in language selector
|
- `LANGS`: **en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR**: List of locales shown in language selector
|
||||||
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어**: Visible names corresponding to the locales
|
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어**: Visible names corresponding to the locales
|
||||||
|
|
||||||
### i18n - Datepicker Language (`i18n.datelang`)
|
|
||||||
Maps locales to the languages used by the datepicker plugin
|
|
||||||
|
|
||||||
- `en-US`: **en**
|
|
||||||
- `zh-CN`: **zh**
|
|
||||||
- `zh-HK`: **zh-HK**
|
|
||||||
- `zh-TW`: **zh-TW**
|
|
||||||
- `de-DE`: **de**
|
|
||||||
- `fr-FR`: **fr**
|
|
||||||
- `nl-NL`: **nl**
|
|
||||||
- `lv-LV`: **lv**
|
|
||||||
- `ru-RU`: **ru**
|
|
||||||
- `ja-JP`: **ja**
|
|
||||||
- `es-ES`: **es**
|
|
||||||
- `pt-BR`: **pt-BR**
|
|
||||||
- `pl-PL`: **pl**
|
|
||||||
- `bg-BG`: **bg**
|
|
||||||
- `it-IT`: **it**
|
|
||||||
- `fi-FI`: **fi**
|
|
||||||
- `tr-TR`: **tr**
|
|
||||||
- `cs-CZ`: **cs-CZ**
|
|
||||||
- `sr-SP`: **sr**
|
|
||||||
- `sv-SE`: **sv**
|
|
||||||
- `ko-KR`: **ko**
|
|
||||||
|
|
||||||
## U2F (`U2F`)
|
## U2F (`U2F`)
|
||||||
- `APP_ID`: **`ROOT_URL`**: Declares the facet of the application. Requires HTTPS.
|
- `APP_ID`: **`ROOT_URL`**: Declares the facet of the application. Requires HTTPS.
|
||||||
|
|
|
@ -15,7 +15,7 @@ menu:
|
||||||
|
|
||||||
# 配置说明
|
# 配置说明
|
||||||
|
|
||||||
这是针对Gitea配置文件的说明,你可以了解Gitea的强大配置。需要说明的是,你的所有改变请修改 `custom/conf/app.ini` 文件而不是源文件。所有默认值可以通过 [app.ini.sample](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample) 查看到。如果你发现 `%(X)s` 这样的内容,请查看 [ini](https://github.com/go-ini/ini/#recursive-values) 这里的说明。标注了 :exclamation: 的配置项表明除非你真的理解这个配置项的意义,否则最好使用默认值。
|
这是针对Gitea配置文件的说明,你可以了解Gitea的强大配置。需要说明的是,你的所有改变请修改 `custom/conf/app.ini` 文件而不是源文件。所有默认值可以通过 [app.example.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini) 查看到。如果你发现 `%(X)s` 这样的内容,请查看 [ini](https://github.com/go-ini/ini/#recursive-values) 这里的说明。标注了 :exclamation: 的配置项表明除非你真的理解这个配置项的意义,否则最好使用默认值。
|
||||||
|
|
||||||
## Overall (`DEFAULT`)
|
## Overall (`DEFAULT`)
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ menu:
|
||||||
- `USER`: 数据库用户名。
|
- `USER`: 数据库用户名。
|
||||||
- `PASSWD`: 数据库用户密码。
|
- `PASSWD`: 数据库用户密码。
|
||||||
- `SSL_MODE`: MySQL 或 PostgreSQL数据库是否启用SSL模式。
|
- `SSL_MODE`: MySQL 或 PostgreSQL数据库是否启用SSL模式。
|
||||||
- `CHARSET`: **utf8**: 仅当数据库为 MySQL 时有效, 可以为 "utf8" 或 "utf8mb4"。注意:如果使用 "utf8mb4",你的 MySQL InnoDB 版本必须在 5.6 以上。
|
- `CHARSET`: **utf8mb4**: 仅当数据库为 MySQL 时有效, 可以为 "utf8" 或 "utf8mb4"。注意:如果使用 "utf8mb4",你的 MySQL InnoDB 版本必须在 5.6 以上。
|
||||||
- `PATH`: Tidb 或者 SQLite3 数据文件存放路径。
|
- `PATH`: Tidb 或者 SQLite3 数据文件存放路径。
|
||||||
- `LOG_SQL`: **true**: 显示生成的SQL,默认为真。
|
- `LOG_SQL`: **true**: 显示生成的SQL,默认为真。
|
||||||
- `MAX_IDLE_CONNS` **0**: 最大空闲数据库连接
|
- `MAX_IDLE_CONNS` **0**: 最大空闲数据库连接
|
||||||
|
|
|
@ -35,7 +35,7 @@ Again `gitea help` will allow you review this variable and you can override it u
|
||||||
`--config` option on the `gitea` binary.
|
`--config` option on the `gitea` binary.
|
||||||
|
|
||||||
- [Quick Cheat Sheet](https://docs.gitea.io/en-us/config-cheat-sheet/)
|
- [Quick Cheat Sheet](https://docs.gitea.io/en-us/config-cheat-sheet/)
|
||||||
- [Complete List](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample)
|
- [Complete List](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
|
||||||
|
|
||||||
If the `CustomPath` folder can't be found despite checking `gitea help`, check the `GITEA_CUSTOM`
|
If the `CustomPath` folder can't be found despite checking `gitea help`, check the `GITEA_CUSTOM`
|
||||||
environment variable; this can be used to override the default path to something else.
|
environment variable; this can be used to override the default path to something else.
|
||||||
|
@ -108,45 +108,6 @@ Apart from `extra_links.tmpl` and `extra_tabs.tmpl`, there are other useful temp
|
||||||
- `body_outer_post.tmpl`, before the bottom `<footer>` element.
|
- `body_outer_post.tmpl`, before the bottom `<footer>` element.
|
||||||
- `footer.tmpl`, right before the end of the `<body>` tag, a good place for additional Javascript.
|
- `footer.tmpl`, right before the end of the `<body>` tag, a good place for additional Javascript.
|
||||||
|
|
||||||
#### Example: Mermaid.js
|
|
||||||
|
|
||||||
If you would like to add [mermaid.js](https://mermaid-js.github.io/mermaid) support to Gitea's markdown you simply add:
|
|
||||||
|
|
||||||
```html
|
|
||||||
{{if .RequireHighlightJS}}
|
|
||||||
<script src="https://unpkg.com/mermaid@8.4.5/dist/mermaid.min.js"></script>
|
|
||||||
<!-- or wherever you have placed it -->
|
|
||||||
<script>mermaid.init(".language-mermaid")</script>
|
|
||||||
{{end}}
|
|
||||||
```
|
|
||||||
|
|
||||||
to `custom/footer.tmpl`. You then can add blocks
|
|
||||||
like below to your markdown:
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
stateDiagram
|
|
||||||
[*] --> Active
|
|
||||||
|
|
||||||
state Active {
|
|
||||||
[*] --> NumLockOff
|
|
||||||
NumLockOff --> NumLockOn : EvNumLockPressed
|
|
||||||
NumLockOn --> NumLockOff : EvNumLockPressed
|
|
||||||
--
|
|
||||||
[*] --> CapsLockOff
|
|
||||||
CapsLockOff --> CapsLockOn : EvCapsLockPressed
|
|
||||||
CapsLockOn --> CapsLockOff : EvCapsLockPressed
|
|
||||||
--
|
|
||||||
[*] --> ScrollLockOff
|
|
||||||
ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
|
|
||||||
ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to use Mermaid.js outside of markdown, e.g. in other templates or HTML files,
|
|
||||||
you would need to remove `{{if .RequireHighlightJS}}` and `{{end}}`.
|
|
||||||
|
|
||||||
Mermaid will detect and use tags with `class="language-mermaid"`.
|
|
||||||
|
|
||||||
#### Example: PlantUML
|
#### Example: PlantUML
|
||||||
|
|
||||||
You can add [PlantUML](https://plantuml.com/) support to Gitea's markdown by using a PlantUML server.
|
You can add [PlantUML](https://plantuml.com/) support to Gitea's markdown by using a PlantUML server.
|
||||||
|
|
|
@ -22,7 +22,7 @@ Gitea 引用 `custom` 目录中的自定义配置文件来覆盖配置、模板
|
||||||
`custom/conf/app.ini` 当中。在发行版中可能会以 `/etc/gitea/` 的形式为 `custom` 设置一个符号链接,查看配置详情请移步:
|
`custom/conf/app.ini` 当中。在发行版中可能会以 `/etc/gitea/` 的形式为 `custom` 设置一个符号链接,查看配置详情请移步:
|
||||||
|
|
||||||
- [快速备忘单](https://docs.gitea.io/en-us/config-cheat-sheet/)
|
- [快速备忘单](https://docs.gitea.io/en-us/config-cheat-sheet/)
|
||||||
- [完整配置清单](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample)
|
- [完整配置清单](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
|
||||||
|
|
||||||
如果您在 binary 同目录下无法找到 `custom` 文件夹,请检查您的 `GITEA_CUSTOM`
|
如果您在 binary 同目录下无法找到 `custom` 文件夹,请检查您的 `GITEA_CUSTOM`
|
||||||
环境变量配置, 因为它可能被配置到了其他地方(可能被一些启动脚本设置指定了目录)。
|
环境变量配置, 因为它可能被配置到了其他地方(可能被一些启动脚本设置指定了目录)。
|
||||||
|
|
|
@ -91,7 +91,23 @@ The simplest recommended way to build from source is:
|
||||||
TAGS="bindata sqlite sqlite_unlock_notify" make build
|
TAGS="bindata sqlite sqlite_unlock_notify" make build
|
||||||
```
|
```
|
||||||
|
|
||||||
See `make help` for all available `make` tasks. Also see [`.drone.yml`](https://github.com/go-gitea/gitea/blob/master/.drone.yml) to see how our continuous integration works.
|
The `build` target will execute both `frontend` and `backend` sub-targets. If the `bindata` tag is present, the frontend files will be compiled into the binary. It is recommended to leave out the tag when doing frontend development so that changes will be reflected.
|
||||||
|
|
||||||
|
See `make help` for all available `make` targets. Also see [`.drone.yml`](https://github.com/go-gitea/gitea/blob/master/.drone.yml) to see how our continuous integration works.
|
||||||
|
|
||||||
|
## Building continuously
|
||||||
|
|
||||||
|
Both the `frontend` and `backend` targets can be ran continuously when source files change:
|
||||||
|
|
||||||
|
````bash
|
||||||
|
# in your first terminal
|
||||||
|
make watch-backend
|
||||||
|
|
||||||
|
# in your second terminal
|
||||||
|
make watch-frontend
|
||||||
|
````
|
||||||
|
|
||||||
|
On macOS, watching all backend source files may hit the default open files limit which can be increased via `ulimit -n 12288` for the current shell or in your shell startup file for all future shells.
|
||||||
|
|
||||||
### Formatting, code analysis and spell check
|
### Formatting, code analysis and spell check
|
||||||
|
|
||||||
|
@ -123,26 +139,12 @@ make revive vet misspell-check
|
||||||
|
|
||||||
### Working on JS and CSS
|
### Working on JS and CSS
|
||||||
|
|
||||||
For simple changes, edit files in `web_src`, run the build and start the server to test:
|
Either use the `watch-frontend` target mentioned above or just build once:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make build && ./gitea
|
make build && ./gitea
|
||||||
```
|
```
|
||||||
|
|
||||||
`make build` runs both `make frontend` and `make backend` which can be run individually as well as long as the `bindata` tag is not used (which compiles frontend files into the binary).
|
|
||||||
|
|
||||||
For more involved changes use the `watch-frontend` task to continuously rebuild files when their sources change. The `bindata` tag must be absent. First, build and run the backend:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make backend && ./gitea
|
|
||||||
```
|
|
||||||
|
|
||||||
With the backend running, open another terminal and run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make watch-frontend
|
|
||||||
```
|
|
||||||
|
|
||||||
Before committing, make sure the linters pass:
|
Before committing, make sure the linters pass:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -151,10 +153,13 @@ make lint-frontend
|
||||||
|
|
||||||
Note: When working on frontend code, set `USE_SERVICE_WORKER` to `false` in `app.ini` to prevent undesirable caching of frontend assets.
|
Note: When working on frontend code, set `USE_SERVICE_WORKER` to `false` in `app.ini` to prevent undesirable caching of frontend assets.
|
||||||
|
|
||||||
### Building Images
|
### Building and adding SVGs
|
||||||
|
|
||||||
To build the images, ImageMagick, `inkscape` and `zopflipng` binaries must be available in
|
SVG icons are built using the `make svg` target which compiles the icon sources defined in `build/generate-svg.js` into the output directory `public/img/svg`. Custom icons can be added in the `web_src/svg` directory.
|
||||||
your `PATH` to run `make generate-images`.
|
|
||||||
|
### Building the Logo
|
||||||
|
|
||||||
|
The PNG versions of the logo are built from a single SVG source file `assets/logo.svg` using the `make generate-images` target. To run it, Node.js and npm must be available. The same process can also be used to generate a custom logo PNGs from a SVG source file. It's possible to remove parts of the SVG logo for the favicon build by adding a `detail-remove` class to the SVG nodes to be removed.
|
||||||
|
|
||||||
### Updating the API
|
### Updating the API
|
||||||
|
|
||||||
|
|
|
@ -316,6 +316,28 @@ COLORIZE = true # Or false if your windows terminal cannot color
|
||||||
|
|
||||||
This is equivalent to sending all logs to the console, with default go log being sent to the console log too.
|
This is equivalent to sending all logs to the console, with default go log being sent to the console log too.
|
||||||
|
|
||||||
|
## Releasing-and-Reopening, Pausing and Resuming logging
|
||||||
|
|
||||||
|
If you are running on Unix you may wish to release-and-reopen logs in order to use `logrotate` or other tools.
|
||||||
|
It is possible force gitea to release and reopen it's logging files and connections by sending `SIGUSR1` to the
|
||||||
|
running process, or running `gitea manager logging release-and-reopen`.
|
||||||
|
|
||||||
|
Alternatively, you may wish to pause and resume logging - this can be accomplished through the use of the
|
||||||
|
`gitea manager logging pause` and `gitea manager logging resume` commands. Please note that whilst logging
|
||||||
|
is paused log events below INFO level will not be stored and only a limited number of events will be stored.
|
||||||
|
Logging may block, albeit temporarily, slowing gitea considerably whilst paused - therefore it is
|
||||||
|
recommended that pausing only done for a very short period of time.
|
||||||
|
|
||||||
|
## Adding and removing logging whilst Gitea is running
|
||||||
|
|
||||||
|
It is possible to add and remove logging whilst Gitea is running using the `gitea manager logging add` and `remove` subcommands.
|
||||||
|
This functionality can only adjust running log systems and cannot be used to start the access, macaron or router loggers if they
|
||||||
|
were not already initialised. If you wish to start these systems you are advised to adjust the app.ini and (gracefully) restart
|
||||||
|
the Gitea service.
|
||||||
|
|
||||||
|
The main intention of these commands is to easily add a temporary logger to investigate problems on running systems where a restart
|
||||||
|
may cause the issue to disappear.
|
||||||
|
|
||||||
## Log colorization
|
## Log colorization
|
||||||
|
|
||||||
Logs to the console will be colorized by default when not running on
|
Logs to the console will be colorized by default when not running on
|
||||||
|
@ -399,3 +421,14 @@ func newNewoneLogService() {
|
||||||
|
|
||||||
You should then add `newOneLogService` to `NewServices()` in
|
You should then add `newOneLogService` to `NewServices()` in
|
||||||
`modules/setting/setting.go`
|
`modules/setting/setting.go`
|
||||||
|
|
||||||
|
## Using `logrotate` instead of built-in log rotation
|
||||||
|
|
||||||
|
Gitea includes built-in log rotation, which should be enough for most deployments. However, if you instead want to use the `logrotate` utility:
|
||||||
|
|
||||||
|
- Disable built-in log rotation by setting `LOG_ROTATE` to `false` in your `app.ini`.
|
||||||
|
- Install `logrotate`.
|
||||||
|
- Configure `logrotate` to match your deployment requirements, see `man 8 logrotate` for configuration syntax details. In the `postrotate/endscript` block send Gitea a `USR1` signal via `kill -USR1` or `kill -10`, or run `gitea manager logging release-and-reopen` (with the appropriate environment). Ensure that your configurations apply to all files emitted by Gitea loggers as described in the above sections.
|
||||||
|
- Always do `logrotate /etc/logrotate.conf --debug` to test your configurations.
|
||||||
|
|
||||||
|
The next `logrotate` jobs will include your configurations, so no restart is needed. You can also immediately reload `logrotate` with `logrotate /etc/logrotate.conf --force`.
|
||||||
|
|
|
@ -96,7 +96,7 @@ Both the LDAP via BindDN and the simple auth LDAP share the following fields:
|
||||||
the LDAP server. The default period is every 24 hours but that can be
|
the LDAP server. The default period is every 24 hours but that can be
|
||||||
changed in the app.ini file. See the *cron.sync_external_users* section in
|
changed in the app.ini file. See the *cron.sync_external_users* section in
|
||||||
the [sample
|
the [sample
|
||||||
app.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample)
|
app.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
|
||||||
for detailed comments about that section. The *User Search Base* and *User
|
for detailed comments about that section. The *User Search Base* and *User
|
||||||
Filter* settings described above will limit which users can use Gitea and
|
Filter* settings described above will limit which users can use Gitea and
|
||||||
which users will be synchronized. When initially run the task will create
|
which users will be synchronized. When initially run the task will create
|
||||||
|
@ -238,9 +238,9 @@ Before activating SSPI single sign-on authentication (SSO) you have to prepare y
|
||||||
|
|
||||||
- Sign in to a client computer in the same domain with any domain user (client computer, different from the server running `gitea.exe`)
|
- Sign in to a client computer in the same domain with any domain user (client computer, different from the server running `gitea.exe`)
|
||||||
|
|
||||||
- If you are using Chrome, Edge or Internet Explorer, add the URL of the web app to the Local intranet sites (`Internet Options -> Security -> Local intranet -> Sites`)
|
- If you are using Chrome or Edge, add the URL of the web app to the Local intranet sites (`Internet Options -> Security -> Local intranet -> Sites`)
|
||||||
|
|
||||||
- Start Chrome, Edge or Internet Explorer and navigate to the FQDN URL of gitea (eg. `http://host.domain.local:3000`)
|
- Start Chrome or Edge and navigate to the FQDN URL of gitea (eg. `http://host.domain.local:3000`)
|
||||||
|
|
||||||
- Click the `Sign In` button on the dashboard and choose SSPI to be automatically logged in with the same user that is currently logged on to the computer
|
- Click the `Sign In` button on the dashboard and choose SSPI to be automatically logged in with the same user that is currently logged on to the computer
|
||||||
|
|
||||||
|
|
|
@ -38,10 +38,13 @@ config is found in **/etc/gitea/app.ini**
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
There are no published packages for Windows. This page will change when packages are published,
|
There is a [Gitea](https://chocolatey.org/packages/gitea) package for Windows by [Chocolatey](https://chocolatey.org/).
|
||||||
in the form of `MSI` installers or via [Chocolatey](https://chocolatey.org/). In the meantime, follow
|
|
||||||
the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide.
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
choco install gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
Or follow the [deployment from binary]({{< relref "from-binary.en-us.md" >}}) guide.
|
||||||
## macOS
|
## macOS
|
||||||
|
|
||||||
Currently, the only supported method of installation on MacOS is [Homebrew](http://brew.sh/).
|
Currently, the only supported method of installation on MacOS is [Homebrew](http://brew.sh/).
|
||||||
|
@ -78,14 +81,14 @@ To enable Gitea to run as a service, run `sysrc gitea_enable=YES` and start it w
|
||||||
|
|
||||||
## Cloudron
|
## Cloudron
|
||||||
|
|
||||||
Gitea is available as a 1-click install on [Cloudron](https://cloudron.io). For those unaware,
|
Gitea is available as a 1-click install on [Cloudron](https://cloudron.io).
|
||||||
Cloudron makes it easy to run apps like Gitea on your server and keep them up-to-date and secure.
|
Cloudron makes it easy to run apps like Gitea on your server and keep them up-to-date and secure.
|
||||||
|
|
||||||
[](https://cloudron.io/button.html?app=io.gitea.cloudronapp)
|
[](https://cloudron.io/button.html?app=io.gitea.cloudronapp)
|
||||||
|
|
||||||
The Gitea package is maintained [here](https://git.cloudron.io/cloudron/gitea-app).
|
The Gitea package is maintained [here](https://git.cloudron.io/cloudron/gitea-app).
|
||||||
|
|
||||||
There is a [demo instance](https://my-demo.cloudron.me) (username: cloudron password: cloudron) where
|
There is a [demo instance](https://my.demo.cloudron.io) (username: cloudron password: cloudron) where
|
||||||
you can experiment with running Gitea.
|
you can experiment with running Gitea.
|
||||||
|
|
||||||
## Third-party
|
## Third-party
|
||||||
|
|
|
@ -21,7 +21,13 @@ menu:
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
目前尚未發佈任何 Windows 套件,如果我們發佈了,會直接更新此網頁。我們計畫使用 `MSI`,或 [Chocolatey](https://chocolatey.org/) 來製作套件。在這之前請先參考[執行檔安裝]({{< relref "from-binary.zh-tw.md" >}})方式。
|
在 Windows 作業系統你可以透過 [Chocolatey](https://chocolatey.org/) 套件管理器安裝 [Gitea](https://chocolatey.org/packages/gitea) 套件:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
choco install gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
也可以參考[執行檔安裝]({{< relref "from-binary.zh-tw.md" >}})方式。
|
||||||
|
|
||||||
## macOS
|
## macOS
|
||||||
|
|
||||||
|
|
|
@ -98,8 +98,10 @@ Depending on requirements, the following build tags can be included.
|
||||||
be used to authenticate local users or extend authentication to methods
|
be used to authenticate local users or extend authentication to methods
|
||||||
available to PAM.
|
available to PAM.
|
||||||
|
|
||||||
Bundling assets into the binary using the `bindata` build tag can make
|
Bundling assets into the binary using the `bindata` build tag is recommended for
|
||||||
development and testing easier, but is not ideal for a production deployment.
|
production deployments. It is possible to serve the static assets directly via a reverse proxy,
|
||||||
|
but in most cases it is not necessary, and assets should still be bundled in the binary.
|
||||||
|
You may want to exclude bindata while developing/testing Gitea.
|
||||||
To include assets, add the `bindata` tag:
|
To include assets, add the `bindata` tag:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
@ -318,3 +318,85 @@ var checklist = []check{
|
||||||
```
|
```
|
||||||
|
|
||||||
This function will receive a command line context and return a list of details about the problems or error.
|
This function will receive a command line context and return a list of details about the problems or error.
|
||||||
|
|
||||||
|
#### manager
|
||||||
|
|
||||||
|
Manage running server operations:
|
||||||
|
|
||||||
|
- Commands:
|
||||||
|
- `shutdown`: Gracefully shutdown the running process
|
||||||
|
- `restart`: Gracefully restart the running process - (not implemented for windows servers)
|
||||||
|
- `flush-queues`: Flush queues in the running process
|
||||||
|
- Options:
|
||||||
|
- `--timeout value`: Timeout for the flushing process (default: 1m0s)
|
||||||
|
- `--non-blocking`: Set to true to not wait for flush to complete before returning
|
||||||
|
- `logging`: Adjust logging commands
|
||||||
|
- Commands:
|
||||||
|
- `pause`: Pause logging
|
||||||
|
- Notes:
|
||||||
|
- The logging level will be raised to INFO temporarily if it is below this level.
|
||||||
|
- Gitea will buffer logs up to a certain point and will drop them after that point.
|
||||||
|
- `resume`: Resume logging
|
||||||
|
- `release-and-reopen`: Cause Gitea to release and re-open files and connections used for logging (Equivalent to sending SIGUSR1 to Gitea.)
|
||||||
|
- `remove name`: Remove the named logger
|
||||||
|
- Options:
|
||||||
|
- `--group group`, `-g group`: Set the group to remove the sublogger from. (defaults to `default`)
|
||||||
|
- `add`: Add a logger
|
||||||
|
- Commands:
|
||||||
|
- `console`: Add a console logger
|
||||||
|
- Options:
|
||||||
|
- `--group value`, `-g value`: Group to add logger to - will default to "default"
|
||||||
|
- `--name value`, `-n value`: Name of the new logger - will default to mode
|
||||||
|
- `--level value`, `-l value`: Logging level for the new logger
|
||||||
|
- `--stacktrace-level value`, `-L value`: Stacktrace logging level
|
||||||
|
- `--flags value`, `-F value`: Flags for the logger
|
||||||
|
- `--expression value`, `-e value`: Matching expression for the logger
|
||||||
|
- `--prefix value`, `-p value`: Prefix for the logger
|
||||||
|
- `--color`: Use color in the logs
|
||||||
|
- `--stderr`: Output console logs to stderr - only relevant for console
|
||||||
|
- `file`: Add a file logger
|
||||||
|
- Options:
|
||||||
|
- `--group value`, `-g value`: Group to add logger to - will default to "default"
|
||||||
|
- `--name value`, `-n value`: Name of the new logger - will default to mode
|
||||||
|
- `--level value`, `-l value`: Logging level for the new logger
|
||||||
|
- `--stacktrace-level value`, `-L value`: Stacktrace logging level
|
||||||
|
- `--flags value`, `-F value`: Flags for the logger
|
||||||
|
- `--expression value`, `-e value`: Matching expression for the logger
|
||||||
|
- `--prefix value`, `-p value`: Prefix for the logger
|
||||||
|
- `--color`: Use color in the logs
|
||||||
|
- `--filename value`, `-f value`: Filename for the logger -
|
||||||
|
- `--rotate`, `-r`: Rotate logs
|
||||||
|
- `--max-size value`, `-s value`: Maximum size in bytes before rotation
|
||||||
|
- `--daily`, `-d`: Rotate logs daily
|
||||||
|
- `--max-days value`, `-D value`: Maximum number of daily logs to keep
|
||||||
|
- `--compress`, `-z`: Compress rotated logs
|
||||||
|
- `--compression-level value`, `-Z value`: Compression level to use
|
||||||
|
- `conn`: Add a network connection logger
|
||||||
|
- Options:
|
||||||
|
- `--group value`, `-g value`: Group to add logger to - will default to "default"
|
||||||
|
- `--name value`, `-n value`: Name of the new logger - will default to mode
|
||||||
|
- `--level value`, `-l value`: Logging level for the new logger
|
||||||
|
- `--stacktrace-level value`, `-L value`: Stacktrace logging level
|
||||||
|
- `--flags value`, `-F value`: Flags for the logger
|
||||||
|
- `--expression value`, `-e value`: Matching expression for the logger
|
||||||
|
- `--prefix value`, `-p value`: Prefix for the logger
|
||||||
|
- `--color`: Use color in the logs
|
||||||
|
- `--reconnect-on-message`, `-R`: Reconnect to host for every message
|
||||||
|
- `--reconnect`, `-r`: Reconnect to host when connection is dropped
|
||||||
|
- `--protocol value`, `-P value`: Set protocol to use: tcp, unix, or udp (defaults to tcp)
|
||||||
|
- `--address value`, `-a value`: Host address and port to connect to (defaults to :7020)
|
||||||
|
- `smtp`: Add an SMTP logger
|
||||||
|
- Options:
|
||||||
|
- `--group value`, `-g value`: Group to add logger to - will default to "default"
|
||||||
|
- `--name value`, `-n value`: Name of the new logger - will default to mode
|
||||||
|
- `--level value`, `-l value`: Logging level for the new logger
|
||||||
|
- `--stacktrace-level value`, `-L value`: Stacktrace logging level
|
||||||
|
- `--flags value`, `-F value`: Flags for the logger
|
||||||
|
- `--expression value`, `-e value`: Matching expression for the logger
|
||||||
|
- `--prefix value`, `-p value`: Prefix for the logger
|
||||||
|
- `--color`: Use color in the logs
|
||||||
|
- `--username value`, `-u value`: Mail server username
|
||||||
|
- `--password value`, `-P value`: Mail server password
|
||||||
|
- `--host value`, `-H value`: Mail server host (defaults to: 127.0.0.1:25)
|
||||||
|
- `--send-to value`, `-s value`: Email address(es) to send to
|
||||||
|
- `--subject value`, `-S value`: Subject header of sent emails
|
||||||
|
|
|
@ -46,6 +46,12 @@ PASSWD = `password`
|
||||||
|
|
||||||
For the full list of options check the [Config Cheat Sheet]({{< relref "doc/advanced/config-cheat-sheet.en-us.md" >}})
|
For the full list of options check the [Config Cheat Sheet]({{< relref "doc/advanced/config-cheat-sheet.en-us.md" >}})
|
||||||
|
|
||||||
|
- Please note: authentication is only supported when the SMTP server communication is encrypted with TLS or `HOST=localhost`. TLS encryption can be through:
|
||||||
|
- Via the server supporting TLS through STARTTLS - usually provided on port 587. (Also known as Opportunistic TLS.)
|
||||||
|
- SMTPS connection (SMTP over transport layer security) via the default port 465.
|
||||||
|
- Forced SMTPS connection with `IS_TLS_ENABLED=true`. (These are both known as Implicit TLS.)
|
||||||
|
- This is due to protections imposed by the Go internal libraries against STRIPTLS attacks.
|
||||||
|
|
||||||
### Gmail
|
### Gmail
|
||||||
|
|
||||||
The following configuration should work with GMail's SMTP server:
|
The following configuration should work with GMail's SMTP server:
|
||||||
|
|
|
@ -55,7 +55,7 @@ Nginx is optimized for serving static content, while the proxying of large respo
|
||||||
(see https://serverfault.com/q/587386).
|
(see https://serverfault.com/q/587386).
|
||||||
|
|
||||||
Download a snapshot of the Gitea source repository to `/path/to/gitea/`.
|
Download a snapshot of the Gitea source repository to `/path/to/gitea/`.
|
||||||
After this, run `make webpack` in the repository directory to generate the static resources. We are only interested in the `public/` directory for this task, so you can delete the rest.
|
After this, run `make frontend` in the repository directory to generate the static resources. We are only interested in the `public/` directory for this task, so you can delete the rest.
|
||||||
(You will need to have [Node with npm](https://nodejs.org/en/download/) and `make` installed to generate the static resources)
|
(You will need to have [Node with npm](https://nodejs.org/en/download/) and `make` installed to generate the static resources)
|
||||||
|
|
||||||
Depending on the scale of your user base, you might want to split the traffic to two distinct servers,
|
Depending on the scale of your user base, you might want to split the traffic to two distinct servers,
|
||||||
|
@ -159,7 +159,15 @@ If you want Caddy to serve your Gitea instance, you can add the following server
|
||||||
|
|
||||||
```
|
```
|
||||||
git.example.com {
|
git.example.com {
|
||||||
proxy / http://localhost:3000
|
reverse_proxy localhost:3000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you still use Caddy v1, use:
|
||||||
|
|
||||||
|
```
|
||||||
|
git.example.com {
|
||||||
|
proxy / localhost:3000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -169,7 +177,18 @@ In case you already have a site, and you want Gitea to share the domain name, yo
|
||||||
|
|
||||||
```
|
```
|
||||||
git.example.com {
|
git.example.com {
|
||||||
proxy /git/ http://localhost:3000 # Note: Trailing Slash after /git/
|
route /git/* {
|
||||||
|
uri strip_prefix /git
|
||||||
|
reverse_proxy localhost:3000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, for Caddy v1:
|
||||||
|
|
||||||
|
```
|
||||||
|
git.example.com {
|
||||||
|
proxy /git/ localhost:3000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others.
|
||||||
- MSSQL
|
- MSSQL
|
||||||
- TiDB (experimental, not recommended)
|
- TiDB (experimental, not recommended)
|
||||||
- Configuration file
|
- Configuration file
|
||||||
- [app.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample)
|
- [app.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
|
||||||
- Admin panel
|
- Admin panel
|
||||||
- Statistics
|
- Statistics
|
||||||
- Actions
|
- Actions
|
||||||
|
@ -128,6 +128,7 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others.
|
||||||
- Environment variables
|
- Environment variables
|
||||||
- Command line options
|
- Command line options
|
||||||
- Multi-language support ([21 languages](https://github.com/go-gitea/gitea/tree/master/options/locale))
|
- Multi-language support ([21 languages](https://github.com/go-gitea/gitea/tree/master/options/locale))
|
||||||
|
- [Mermaid](https://mermaidjs.github.io/) Diagram support
|
||||||
- Mail service
|
- Mail service
|
||||||
- Notifications
|
- Notifications
|
||||||
- Registration confirmation
|
- Registration confirmation
|
||||||
|
@ -261,7 +262,8 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others.
|
||||||
|
|
||||||
## Browser Support
|
## Browser Support
|
||||||
|
|
||||||
- Please see [Semantic UI](https://github.com/Semantic-Org/Semantic-UI#browser-support) for specific versions of supported browsers.
|
- Last 2 versions of Chrome, Firefox, Safari, Edge (EdgeHTML) and Edge (Chromium)
|
||||||
|
- Firefox ESR
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
|
@ -275,7 +277,6 @@ Windows, on architectures like amd64, i386, ARM, PowerPC, and others.
|
||||||
* [Highlight](https://highlightjs.org/)
|
* [Highlight](https://highlightjs.org/)
|
||||||
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
||||||
* [CodeMirror](https://codemirror.net/)
|
* [CodeMirror](https://codemirror.net/)
|
||||||
* [jQuery Date Time Picker](https://github.com/xdan/datetimepicker)
|
|
||||||
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
||||||
* Database drivers:
|
* Database drivers:
|
||||||
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
||||||
|
|
|
@ -70,7 +70,7 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide
|
||||||
- MSSQL
|
- MSSQL
|
||||||
- [TiDB](https://github.com/pingcap/tidb) (expérimental)
|
- [TiDB](https://github.com/pingcap/tidb) (expérimental)
|
||||||
- Fichier de configuration
|
- Fichier de configuration
|
||||||
- Voir [ici](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.ini.sample)
|
- Voir [ici](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
|
||||||
- Panel d'administration
|
- Panel d'administration
|
||||||
- Statistiques
|
- Statistiques
|
||||||
- Actions
|
- Actions
|
||||||
|
@ -264,7 +264,6 @@ Le but de ce projet est de fournir de la manière la plus simple, la plus rapide
|
||||||
* [Highlight](https://highlightjs.org/)
|
* [Highlight](https://highlightjs.org/)
|
||||||
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
||||||
* [CodeMirror](https://codemirror.net/)
|
* [CodeMirror](https://codemirror.net/)
|
||||||
* [jQuery Date Time Picker](https://github.com/xdan/datetimepicker)
|
|
||||||
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
||||||
* Connecteurs de base de données :
|
* Connecteurs de base de données :
|
||||||
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
||||||
|
|
|
@ -57,7 +57,6 @@ Gitea的首要目标是创建一个极易安装,运行非常快速,安装和
|
||||||
* [Highlight](https://highlightjs.org/)
|
* [Highlight](https://highlightjs.org/)
|
||||||
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
||||||
* [CodeMirror](https://codemirror.net/)
|
* [CodeMirror](https://codemirror.net/)
|
||||||
* [jQuery Date Time Picker](https://github.com/xdan/datetimepicker)
|
|
||||||
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
||||||
* 数据库驱动:
|
* 数据库驱动:
|
||||||
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
||||||
|
|
|
@ -57,7 +57,6 @@ Gitea 的首要目標是建立一個容易安裝,運行快速,安装和使
|
||||||
* [Highlight](https://highlightjs.org/)
|
* [Highlight](https://highlightjs.org/)
|
||||||
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
* [Clipboard](https://zenorocha.github.io/clipboard.js/)
|
||||||
* [CodeMirror](https://codemirror.net/)
|
* [CodeMirror](https://codemirror.net/)
|
||||||
* [jQuery Date Time Picker](https://github.com/xdan/datetimepicker)
|
|
||||||
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
* [jQuery MiniColors](https://github.com/claviska/jquery-minicolors)
|
||||||
* 資料庫:
|
* 資料庫:
|
||||||
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
* [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
||||||
|
|
36
go.mod
36
go.mod
|
@ -18,8 +18,9 @@ require (
|
||||||
gitea.com/macaron/session v0.0.0-20191207215012-613cebf0674d
|
gitea.com/macaron/session v0.0.0-20191207215012-613cebf0674d
|
||||||
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7
|
gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/PuerkitoBio/goquery v1.5.0
|
github.com/PuerkitoBio/goquery v1.5.1
|
||||||
github.com/RoaringBitmap/roaring v0.4.23 // indirect
|
github.com/RoaringBitmap/roaring v0.4.23 // indirect
|
||||||
|
github.com/alecthomas/chroma v0.8.0
|
||||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||||
github.com/blevesearch/bleve v1.0.7
|
github.com/blevesearch/bleve v1.0.7
|
||||||
github.com/couchbase/gomemcached v0.0.0-20191004160342-7b5da2ec40b2 // indirect
|
github.com/couchbase/gomemcached v0.0.0-20191004160342-7b5da2ec40b2 // indirect
|
||||||
|
@ -37,18 +38,20 @@ require (
|
||||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
|
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
|
||||||
github.com/gliderlabs/ssh v0.2.2
|
github.com/gliderlabs/ssh v0.2.2
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a // indirect
|
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a // indirect
|
||||||
github.com/go-enry/go-enry/v2 v2.3.0
|
github.com/go-enry/go-enry/v2 v2.5.2
|
||||||
github.com/go-git/go-billy/v5 v5.0.0
|
github.com/go-git/go-billy/v5 v5.0.0
|
||||||
github.com/go-git/go-git/v5 v5.0.0
|
github.com/go-git/go-git/v5 v5.1.0
|
||||||
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
github.com/go-openapi/jsonreference v0.19.3 // indirect
|
||||||
github.com/go-redis/redis v6.15.2+incompatible
|
github.com/go-redis/redis v6.15.2+incompatible
|
||||||
github.com/go-sql-driver/mysql v1.4.1
|
github.com/go-sql-driver/mysql v1.5.0
|
||||||
github.com/go-swagger/go-swagger v0.21.0
|
github.com/go-swagger/go-swagger v0.21.0
|
||||||
|
github.com/go-testfixtures/testfixtures/v3 v3.2.0
|
||||||
github.com/gobwas/glob v0.2.3
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
|
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
|
||||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||||
github.com/golang/protobuf v1.4.1 // indirect
|
github.com/golang/protobuf v1.4.1 // indirect
|
||||||
github.com/google/go-github/v24 v24.0.1
|
github.com/google/go-github/v24 v24.0.1
|
||||||
|
github.com/google/uuid v1.1.1
|
||||||
github.com/gorilla/context v1.1.1
|
github.com/gorilla/context v1.1.1
|
||||||
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
|
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
|
||||||
github.com/huandu/xstrings v1.3.0
|
github.com/huandu/xstrings v1.3.0
|
||||||
|
@ -56,21 +59,20 @@ require (
|
||||||
github.com/issue9/identicon v1.0.1
|
github.com/issue9/identicon v1.0.1
|
||||||
github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d
|
github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d
|
||||||
github.com/jmhodges/levigo v1.0.0 // indirect
|
github.com/jmhodges/levigo v1.0.0 // indirect
|
||||||
github.com/joho/godotenv v1.3.0 // indirect
|
|
||||||
github.com/kballard/go-shellquote v0.0.0-20170619183022-cd60e84ee657
|
github.com/kballard/go-shellquote v0.0.0-20170619183022-cd60e84ee657
|
||||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
||||||
github.com/klauspost/compress v1.10.2
|
github.com/klauspost/compress v1.10.2
|
||||||
github.com/lafriks/xormstore v1.3.2
|
github.com/lafriks/xormstore v1.3.2
|
||||||
github.com/lib/pq v1.2.0
|
github.com/lib/pq v1.7.0
|
||||||
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
|
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
|
||||||
github.com/mailru/easyjson v0.7.0 // indirect
|
github.com/mailru/easyjson v0.7.0 // indirect
|
||||||
github.com/markbates/goth v1.61.2
|
github.com/markbates/goth v1.61.2
|
||||||
github.com/mattn/go-isatty v0.0.11
|
github.com/mattn/go-isatty v0.0.12
|
||||||
github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d // indirect
|
github.com/mattn/go-sqlite3 v2.0.2+incompatible
|
||||||
github.com/mattn/go-sqlite3 v1.11.0
|
|
||||||
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75
|
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75
|
||||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81
|
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81
|
||||||
github.com/mgechev/revive v1.0.2
|
github.com/mgechev/revive v1.0.2
|
||||||
|
github.com/mholt/archiver/v3 v3.3.0
|
||||||
github.com/microcosm-cc/bluemonday v1.0.3-0.20191119130333-0a75d7616912
|
github.com/microcosm-cc/bluemonday v1.0.3-0.20191119130333-0a75d7616912
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc
|
github.com/msteinert/pam v0.0.0-20151204160544-02ccfbfaf0cc
|
||||||
|
@ -85,7 +87,6 @@ require (
|
||||||
github.com/prometheus/procfs v0.0.4 // indirect
|
github.com/prometheus/procfs v0.0.4 // indirect
|
||||||
github.com/quasoft/websspi v1.0.0
|
github.com/quasoft/websspi v1.0.0
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
|
||||||
github.com/satori/go.uuid v1.2.0
|
|
||||||
github.com/sergi/go-diff v1.1.0
|
github.com/sergi/go-diff v1.1.0
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect
|
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect
|
||||||
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
|
||||||
|
@ -93,19 +94,19 @@ require (
|
||||||
github.com/tecbot/gorocksdb v0.0.0-20181010114359-8752a9433481 // indirect
|
github.com/tecbot/gorocksdb v0.0.0-20181010114359-8752a9433481 // indirect
|
||||||
github.com/tinylib/msgp v1.1.2 // indirect
|
github.com/tinylib/msgp v1.1.2 // indirect
|
||||||
github.com/tstranex/u2f v1.0.0
|
github.com/tstranex/u2f v1.0.0
|
||||||
github.com/unknwon/cae v1.0.0
|
|
||||||
github.com/unknwon/com v1.0.1
|
github.com/unknwon/com v1.0.1
|
||||||
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
|
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
|
||||||
github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141
|
github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141
|
||||||
github.com/urfave/cli v1.20.0
|
github.com/urfave/cli v1.20.0
|
||||||
github.com/xanzy/go-gitlab v0.31.0
|
github.com/xanzy/go-gitlab v0.31.0
|
||||||
github.com/yohcop/openid-go v1.0.0
|
github.com/yohcop/openid-go v1.0.0
|
||||||
github.com/yuin/goldmark v1.1.25
|
github.com/yuin/goldmark v1.1.32
|
||||||
|
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
|
||||||
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60
|
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60
|
||||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1
|
||||||
golang.org/x/text v0.3.2
|
golang.org/x/text v0.3.2
|
||||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
|
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
|
||||||
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224
|
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224
|
||||||
|
@ -115,10 +116,9 @@ require (
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/ini.v1 v1.52.0
|
gopkg.in/ini.v1 v1.52.0
|
||||||
gopkg.in/ldap.v3 v3.0.2
|
gopkg.in/ldap.v3 v3.0.2
|
||||||
gopkg.in/testfixtures.v2 v2.5.0
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
gopkg.in/yaml.v2 v2.2.8
|
|
||||||
mvdan.cc/xurls/v2 v2.1.0
|
mvdan.cc/xurls/v2 v2.1.0
|
||||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||||
xorm.io/builder v0.3.7
|
xorm.io/builder v0.3.7
|
||||||
xorm.io/xorm v1.0.1
|
xorm.io/xorm v1.0.4-0.20200718080127-318102c9ff87
|
||||||
)
|
)
|
||||||
|
|
133
go.sum
133
go.sum
|
@ -46,9 +46,11 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0p
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
||||||
|
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk=
|
github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE=
|
||||||
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
|
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
|
@ -61,12 +63,28 @@ github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06
|
||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68=
|
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68=
|
||||||
|
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||||
|
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
|
||||||
|
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
|
||||||
|
github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a/go.mod h1:fv5SzZPFJbwp2NXJWpFIX7DZS4HgV1K4ew4Pc2OZD9s=
|
||||||
|
github.com/alecthomas/chroma v0.8.0 h1:HS+HE97sgcqjQGu5uVr8jIE55Mmh5UeQ7kckAhHg2pY=
|
||||||
|
github.com/alecthomas/chroma v0.8.0/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM=
|
||||||
|
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
|
||||||
|
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
|
||||||
|
github.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
|
||||||
|
github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
|
||||||
|
github.com/alecthomas/kong v0.2.4/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
|
||||||
|
github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MRgZdU3vrFd05IQ89AxUZ0aYdF39BYoNFa324SodPCA=
|
||||||
|
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
|
||||||
|
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
|
github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6 h1:bZ28Hqta7TFAK3Q08CMvv8y3/8ATaEqv2nGoc6yff6c=
|
||||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6/go.mod h1:+lx6/Aqd1kLJ1GQfkvOnaZ1WGmLpMpbprPuIOOZX30U=
|
||||||
|
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
|
||||||
|
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
|
@ -141,19 +159,29 @@ github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1v
|
||||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||||
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537 h1:MZRmHqDBd0vxNwenEbKSQqRVT24d3C05ft8kduSwlqM=
|
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537 h1:MZRmHqDBd0vxNwenEbKSQqRVT24d3C05ft8kduSwlqM=
|
||||||
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
|
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
|
||||||
|
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||||
|
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
||||||
|
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538 h1:bpWCJ5MddHsv4Xtl3azkK89mZzd/vvut32mvAnKbyUA=
|
github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538 h1:bpWCJ5MddHsv4Xtl3azkK89mZzd/vvut32mvAnKbyUA=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
|
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
|
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
|
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
||||||
|
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
|
github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
|
||||||
|
github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
|
||||||
|
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
|
@ -193,18 +221,18 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a h1:FQqo
|
||||||
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
|
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
|
||||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||||
github.com/go-enry/go-enry/v2 v2.3.0 h1:o8KwgY6uSplysrIpj+Y42J/xGPp90ogVpxE2Z3s8Unk=
|
github.com/go-enry/go-enry/v2 v2.5.2 h1:3f3PFAO6JitWkPi1GQ5/m6Xu4gNL1U5soJ8QaYqJ0YQ=
|
||||||
github.com/go-enry/go-enry/v2 v2.3.0/go.mod h1:+xFJwbqWi15bvqFHb2ELUWVRKFQtwB61+sDrkvvxxGI=
|
github.com/go-enry/go-enry/v2 v2.5.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
|
||||||
github.com/go-enry/go-oniguruma v1.2.0 h1:oBO9XC1IDT9+AoWW5oFsa/7gFeOPacEqDbyXZKWXuDs=
|
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
||||||
github.com/go-enry/go-oniguruma v1.2.0/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
||||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
|
github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||||
github.com/go-git/go-git/v5 v5.0.0 h1:k5RWPm4iJwYtfWoxIJy4wJX9ON7ihPeZZYC1fLYDnpg=
|
github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk=
|
||||||
github.com/go-git/go-git/v5 v5.0.0/go.mod h1:oYD8y9kWsGINPFJoLdaScGCN6dlKg23blmClfZwtUVA=
|
github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
@ -267,12 +295,16 @@ github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDA
|
||||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||||
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-swagger/go-swagger v0.21.0 h1:AX9mdfzp6eJtUe92nFrWmbK7ocRgkCDPJs0FsSSTDlA=
|
github.com/go-swagger/go-swagger v0.21.0 h1:AX9mdfzp6eJtUe92nFrWmbK7ocRgkCDPJs0FsSSTDlA=
|
||||||
github.com/go-swagger/go-swagger v0.21.0/go.mod h1:tDb8PdDVFcaE8EPXkMOsuxpL3UEPiwu1UDZar9Z/1RY=
|
github.com/go-swagger/go-swagger v0.21.0/go.mod h1:tDb8PdDVFcaE8EPXkMOsuxpL3UEPiwu1UDZar9Z/1RY=
|
||||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
|
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
|
||||||
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
|
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
|
||||||
|
github.com/go-testfixtures/testfixtures/v3 v3.2.0 h1:FGAW3z5UzmrZGjR/dZp1u3Tbld0SDmirLO4RrR5++7Q=
|
||||||
|
github.com/go-testfixtures/testfixtures/v3 v3.2.0/go.mod h1:RZctY24ixituGC73XlAV1gkCwYMVwiSwPm26MNlQIhE=
|
||||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
|
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
|
||||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
||||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||||
|
@ -286,6 +318,8 @@ github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQ
|
||||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
|
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
|
github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 h1:KRMr9A3qfbVM7iV/WcLY/rL5LICqwMHLhwRXKu99fXw=
|
||||||
|
github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
@ -338,12 +372,16 @@ github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKp
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
||||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||||
|
github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
|
||||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||||
|
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||||
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
|
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
|
||||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||||
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
|
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
|
||||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||||
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5oVvhMjDyLhmA1LG86oSo+IqY=
|
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5oVvhMjDyLhmA1LG86oSo+IqY=
|
||||||
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=
|
||||||
|
@ -371,6 +409,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/huandu/xstrings v1.3.0 h1:gvV6jG9dTgFEncxo+AF7PH6MZXi/vZl25owA/8Dg8Wo=
|
github.com/huandu/xstrings v1.3.0 h1:gvV6jG9dTgFEncxo+AF7PH6MZXi/vZl25owA/8Dg8Wo=
|
||||||
github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
|
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||||
|
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
||||||
github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=
|
github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=
|
||||||
|
@ -405,10 +445,14 @@ github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+
|
||||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
|
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY=
|
github.com/klauspost/compress v1.9.2 h1:LfVyl+ZlLlLDeQ/d2AqfGIIH4qEDu0Ed2S5GyhCWIWY=
|
||||||
github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
github.com/klauspost/compress v1.10.2 h1:Znfn6hXZAHaLPNnlqUYRrBSReFHYybslgv4PTiyz6P0=
|
github.com/klauspost/compress v1.10.2 h1:Znfn6hXZAHaLPNnlqUYRrBSReFHYybslgv4PTiyz6P0=
|
||||||
github.com/klauspost/compress v1.10.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
|
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
|
||||||
|
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
|
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
|
@ -426,6 +470,9 @@ github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/Y
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
|
||||||
|
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY=
|
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY=
|
||||||
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:mmIfjCSQlGYXmJ95jFN84AkQFnVABtKuJL8IrzwvUKQ=
|
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:mmIfjCSQlGYXmJ95jFN84AkQFnVABtKuJL8IrzwvUKQ=
|
||||||
github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk=
|
github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk=
|
||||||
|
@ -444,18 +491,25 @@ github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7
|
||||||
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
|
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
|
||||||
github.com/markbates/goth v1.61.2 h1:jDowrUH5qw8KGuQdKwFhLzkXkTYCIPfz3LHADJsiPIs=
|
github.com/markbates/goth v1.61.2 h1:jDowrUH5qw8KGuQdKwFhLzkXkTYCIPfz3LHADJsiPIs=
|
||||||
github.com/markbates/goth v1.61.2/go.mod h1:qh2QfwZoWRucQ+DR5KVKC6dUGkNCToWh4vS45GIzFsY=
|
github.com/markbates/goth v1.61.2/go.mod h1:qh2QfwZoWRucQ+DR5KVKC6dUGkNCToWh4vS45GIzFsY=
|
||||||
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
|
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||||
|
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
|
||||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||||
github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d h1:m+dSK37rFf2fqppZhg15yI2IwC9BtucBiRwSDm9VL8g=
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
|
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
|
||||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||||
|
github.com/mattn/go-sqlite3 v2.0.2+incompatible h1:qzw9c2GNT8UFrgWNDhCTqRqYUSmu/Dav/9Z58LGpk7U=
|
||||||
|
github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 h1:Pijfgr7ZuvX7QIQiEwLdRVr3RoMG+i0SbBO1Qu+7yVk=
|
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 h1:Pijfgr7ZuvX7QIQiEwLdRVr3RoMG+i0SbBO1Qu+7yVk=
|
||||||
|
@ -464,6 +518,8 @@ github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc8
|
||||||
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
||||||
github.com/mgechev/revive v1.0.2 h1:v0NxxQ7fSFz/u1NQydPo6EGdq7va0J1BtsZmae6kzUg=
|
github.com/mgechev/revive v1.0.2 h1:v0NxxQ7fSFz/u1NQydPo6EGdq7va0J1BtsZmae6kzUg=
|
||||||
github.com/mgechev/revive v1.0.2/go.mod h1:rb0dQy1LVAxW9SWy5R3LPUjevzUbUS316U5MFySA2lo=
|
github.com/mgechev/revive v1.0.2/go.mod h1:rb0dQy1LVAxW9SWy5R3LPUjevzUbUS316U5MFySA2lo=
|
||||||
|
github.com/mholt/archiver/v3 v3.3.0 h1:vWjhY8SQp5yzM9P6OJ/eZEkmi3UAbRrxCq48MxjAzig=
|
||||||
|
github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08Ebtr1Mqao=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.3-0.20191119130333-0a75d7616912 h1:hJde9rA24hlTcAYSwJoXpDUyGtfKQ/jsofw+WaDqGrI=
|
github.com/microcosm-cc/bluemonday v1.0.3-0.20191119130333-0a75d7616912 h1:hJde9rA24hlTcAYSwJoXpDUyGtfKQ/jsofw+WaDqGrI=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.3-0.20191119130333-0a75d7616912/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w=
|
github.com/microcosm-cc/bluemonday v1.0.3-0.20191119130333-0a75d7616912/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
|
@ -489,6 +545,9 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/niklasfasching/go-org v0.1.9 h1:Toz8WMIt+qJb52uYEk1YD/muLuOOmRt1CfkV+bKVMkI=
|
github.com/niklasfasching/go-org v0.1.9 h1:Toz8WMIt+qJb52uYEk1YD/muLuOOmRt1CfkV+bKVMkI=
|
||||||
github.com/niklasfasching/go-org v0.1.9/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
github.com/niklasfasching/go-org v0.1.9/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
|
||||||
|
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
|
||||||
|
github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs=
|
||||||
|
github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
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/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
||||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||||
|
@ -511,6 +570,7 @@ github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfS
|
||||||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||||
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
|
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
|
||||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||||
|
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
|
@ -556,8 +616,7 @@ 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/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
|
||||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
||||||
|
@ -592,6 +651,8 @@ github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmq
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
|
||||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
|
@ -616,16 +677,14 @@ github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW
|
||||||
github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ=
|
github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ=
|
||||||
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/toqueteos/trie v1.0.0 h1:8i6pXxNUXNRAqP246iibb7w/pSFquNTQ+uNfriG7vlk=
|
|
||||||
github.com/toqueteos/trie v1.0.0/go.mod h1:Ywk48QhEqhU1+DwhMkJ2x7eeGxDHiGkAdc9+0DYcbsM=
|
|
||||||
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
|
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
|
||||||
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
|
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
|
||||||
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
|
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
|
||||||
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
|
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/unknwon/cae v1.0.0 h1:i39lOFaBXZxhGjQOy/RNbi8uzettCs6OQxpR0xXohGU=
|
github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
|
||||||
github.com/unknwon/cae v1.0.0/go.mod h1:QaSeRctcea9fK6piJpAMCCPKxzJ01+xFcr2k1m3WRPU=
|
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||||
github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
|
github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
|
||||||
github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
|
github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
|
||||||
github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
|
github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
|
||||||
|
@ -636,19 +695,28 @@ github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141 h1:Z79lyIznnziKA
|
||||||
github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0=
|
github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0=
|
||||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||||
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
|
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
|
||||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
github.com/xanzy/go-gitlab v0.31.0 h1:+nHztQuCXGSMluKe5Q9IRaPdz6tO8O0gMkQ0vqGpiBk=
|
github.com/xanzy/go-gitlab v0.31.0 h1:+nHztQuCXGSMluKe5Q9IRaPdz6tO8O0gMkQ0vqGpiBk=
|
||||||
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
|
||||||
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/yohcop/openid-go v1.0.0 h1:EciJ7ZLETHR3wOtxBvKXx9RV6eyHZpCaSZ1inbBaUXE=
|
github.com/yohcop/openid-go v1.0.0 h1:EciJ7ZLETHR3wOtxBvKXx9RV6eyHZpCaSZ1inbBaUXE=
|
||||||
github.com/yohcop/openid-go v1.0.0/go.mod h1:/408xiwkeItSPJZSTPF7+VtZxPkPrRRpRNK2vjGh6yI=
|
github.com/yohcop/openid-go v1.0.0/go.mod h1:/408xiwkeItSPJZSTPF7+VtZxPkPrRRpRNK2vjGh6yI=
|
||||||
github.com/yuin/goldmark v1.1.7/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.7/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.1.25 h1:isv+Q6HQAmmL2Ofcmg8QauBmDPlUUnSoNhEcC940Rds=
|
github.com/yuin/goldmark v1.1.25 h1:isv+Q6HQAmmL2Ofcmg8QauBmDPlUUnSoNhEcC940Rds=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/yuin/goldmark v1.1.32 h1:5tjfNdR2ki3yYQ842+eX2sQHeiwpKJ0RnHO4IYOc4V8=
|
||||||
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio=
|
||||||
|
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
|
||||||
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60 h1:gZucqLjL1eDzVWrXj4uiWeMbAopJlBR2mKQAsTGdPwo=
|
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60 h1:gZucqLjL1eDzVWrXj4uiWeMbAopJlBR2mKQAsTGdPwo=
|
||||||
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60/go.mod h1:i9VhcIHN2PxXMbQrKqXNueok6QNONoPjNMoj9MygVL0=
|
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60/go.mod h1:i9VhcIHN2PxXMbQrKqXNueok6QNONoPjNMoj9MygVL0=
|
||||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||||
|
@ -683,8 +751,8 @@ golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8U
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
||||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
|
@ -720,11 +788,13 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||||
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/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-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-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y=
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||||
|
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
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-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
@ -746,6 +816,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -766,13 +837,16 @@ golang.org/x/sys v0.0.0-20190907184412-d223b2b6db03/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f h1:mOhmO9WsBaJCNmaZHPtHs9wOcdqdKCjF6OPJlmDM3KI=
|
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||||
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
@ -872,12 +946,8 @@ gopkg.in/ldap.v3 v3.0.2 h1:R6RBtabK6e1GO0eQKtkyOFbAHO73QesLzI2w2DZ6b9w=
|
||||||
gopkg.in/ldap.v3 v3.0.2/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
|
gopkg.in/ldap.v3 v3.0.2/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
gopkg.in/testfixtures.v2 v2.5.0 h1:N08B7l2GzFQenyYbzqthDnKAA+cmb17iAZhhFxr7JHw=
|
|
||||||
gopkg.in/testfixtures.v2 v2.5.0/go.mod h1:vyAq+MYCgNpR29qitQdLZhdbLFf4mR/2MFJRFoQZZ2M=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/toqueteos/substring.v1 v1.0.2 h1:urLqCeMm6x/eTuQa1oZerNw8N1KNOIp5hD5kGL7lFsE=
|
|
||||||
gopkg.in/toqueteos/substring.v1 v1.0.2/go.mod h1:Eb2Z1UYehlVK8LYW2WBVR2rwbujsz3aX8XDrM1vbNew=
|
|
||||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
@ -886,8 +956,11 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
@ -906,5 +979,5 @@ xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=
|
||||||
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
||||||
xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM=
|
xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM=
|
||||||
xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY=
|
xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY=
|
||||||
xorm.io/xorm v1.0.1 h1:/lITxpJtkZauNpdzj+L9CN/3OQxZaABrbergMcJu+Cw=
|
xorm.io/xorm v1.0.4-0.20200718080127-318102c9ff87 h1:vgc2F0wjD0cyrNrSKiIdWu123wuKkPQI84DZUKvJ6ns=
|
||||||
xorm.io/xorm v1.0.1/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY=
|
xorm.io/xorm v1.0.4-0.20200718080127-318102c9ff87/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
||||||
|
|
|
@ -70,3 +70,25 @@ For other databases(replace MSSQL to MYSQL, MYSQL8, PGSQL):
|
||||||
```
|
```
|
||||||
TEST_MSSQL_HOST=localhost:1433 TEST_MSSQL_DBNAME=test TEST_MSSQL_USERNAME=sa TEST_MSSQL_PASSWORD=MwantsaSecurePassword1 make test-mssql#GPG
|
TEST_MSSQL_HOST=localhost:1433 TEST_MSSQL_DBNAME=test TEST_MSSQL_USERNAME=sa TEST_MSSQL_PASSWORD=MwantsaSecurePassword1 make test-mssql#GPG
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Setting timeouts for declaring long-tests and long-flushes
|
||||||
|
|
||||||
|
We appreciate that some testing machines may not be very powerful and
|
||||||
|
the default timeouts for declaring a slow test or a slow clean-up flush
|
||||||
|
may not be appropriate.
|
||||||
|
|
||||||
|
You can either:
|
||||||
|
|
||||||
|
* Within the test ini file set the following section:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[integration-tests]
|
||||||
|
SLOW_TEST = 10s ; 10s is the default value
|
||||||
|
SLOW_FLUSH = 5S ; 5s is the default value
|
||||||
|
```
|
||||||
|
|
||||||
|
* Set the following environment variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GITEA_SLOW_TEST_TIME="10s" GITEA_SLOW_FLUSH_TIME="5s" make test-sqlite
|
||||||
|
```
|
||||||
|
|
|
@ -6,6 +6,7 @@ package integrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
@ -100,6 +101,72 @@ func TestAPIGetBranch(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPICreateBranch(t *testing.T) {
|
||||||
|
onGiteaRun(t, testAPICreateBranches)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAPICreateBranches(t *testing.T, giteaURL *url.URL) {
|
||||||
|
|
||||||
|
username := "user2"
|
||||||
|
ctx := NewAPITestContext(t, username, "my-noo-repo")
|
||||||
|
giteaURL.Path = ctx.GitPath()
|
||||||
|
|
||||||
|
t.Run("CreateRepo", doAPICreateRepository(ctx, false))
|
||||||
|
tests := []struct {
|
||||||
|
OldBranch string
|
||||||
|
NewBranch string
|
||||||
|
ExpectedHTTPStatus int
|
||||||
|
}{
|
||||||
|
// Creating branch from default branch
|
||||||
|
{
|
||||||
|
OldBranch: "",
|
||||||
|
NewBranch: "new_branch_from_default_branch",
|
||||||
|
ExpectedHTTPStatus: http.StatusCreated,
|
||||||
|
},
|
||||||
|
// Creating branch from master
|
||||||
|
{
|
||||||
|
OldBranch: "master",
|
||||||
|
NewBranch: "new_branch_from_master_1",
|
||||||
|
ExpectedHTTPStatus: http.StatusCreated,
|
||||||
|
},
|
||||||
|
// Trying to create from master but already exists
|
||||||
|
{
|
||||||
|
OldBranch: "master",
|
||||||
|
NewBranch: "new_branch_from_master_1",
|
||||||
|
ExpectedHTTPStatus: http.StatusConflict,
|
||||||
|
},
|
||||||
|
// Trying to create from other branch (not default branch)
|
||||||
|
{
|
||||||
|
OldBranch: "new_branch_from_master_1",
|
||||||
|
NewBranch: "branch_2",
|
||||||
|
ExpectedHTTPStatus: http.StatusCreated,
|
||||||
|
},
|
||||||
|
// Trying to create from a branch which does not exist
|
||||||
|
{
|
||||||
|
OldBranch: "does_not_exist",
|
||||||
|
NewBranch: "new_branch_from_non_existent",
|
||||||
|
ExpectedHTTPStatus: http.StatusNotFound,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
defer resetFixtures(t)
|
||||||
|
session := ctx.Session
|
||||||
|
token := getTokenForLoggedInUser(t, session)
|
||||||
|
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/my-noo-repo/branches?token="+token, &api.CreateBranchRepoOption{
|
||||||
|
BranchName: test.NewBranch,
|
||||||
|
OldBranchName: test.OldBranch,
|
||||||
|
})
|
||||||
|
resp := session.MakeRequest(t, req, test.ExpectedHTTPStatus)
|
||||||
|
|
||||||
|
var branch api.Branch
|
||||||
|
DecodeJSON(t, resp, &branch)
|
||||||
|
|
||||||
|
if test.ExpectedHTTPStatus == http.StatusCreated {
|
||||||
|
assert.EqualValues(t, test.NewBranch, branch.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPIBranchProtection(t *testing.T) {
|
func TestAPIBranchProtection(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
defer prepareTestEnv(t)()
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ func TestGPGKeys(t *testing.T) {
|
||||||
results: []int{http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized},
|
results: []int{http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized},
|
||||||
},
|
},
|
||||||
{name: "LoggedAsUser2", makeRequest: session.MakeRequest, token: token,
|
{name: "LoggedAsUser2", makeRequest: session.MakeRequest, token: token,
|
||||||
results: []int{http.StatusOK, http.StatusOK, http.StatusNotFound, http.StatusNoContent, http.StatusInternalServerError, http.StatusInternalServerError, http.StatusCreated, http.StatusCreated}},
|
results: []int{http.StatusOK, http.StatusOK, http.StatusNotFound, http.StatusNoContent, http.StatusUnprocessableEntity, http.StatusNotFound, http.StatusCreated, http.StatusCreated}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tt {
|
for _, tc := range tt {
|
||||||
|
|
|
@ -44,4 +44,29 @@ func TestAPIIssuesMilestone(t *testing.T) {
|
||||||
var apiMilestone2 structs.Milestone
|
var apiMilestone2 structs.Milestone
|
||||||
DecodeJSON(t, resp, &apiMilestone2)
|
DecodeJSON(t, resp, &apiMilestone2)
|
||||||
assert.EqualValues(t, "closed", apiMilestone2.State)
|
assert.EqualValues(t, "closed", apiMilestone2.State)
|
||||||
|
|
||||||
|
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?token=%s", owner.Name, repo.Name, token), structs.CreateMilestoneOption{
|
||||||
|
Title: "wow",
|
||||||
|
Description: "closed one",
|
||||||
|
State: "closed",
|
||||||
|
})
|
||||||
|
resp = session.MakeRequest(t, req, http.StatusCreated)
|
||||||
|
DecodeJSON(t, resp, &apiMilestone)
|
||||||
|
assert.Equal(t, "wow", apiMilestone.Title)
|
||||||
|
assert.Equal(t, structs.StateClosed, apiMilestone.State)
|
||||||
|
|
||||||
|
var apiMilestones []structs.Milestone
|
||||||
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&token=%s", owner.Name, repo.Name, "all", token))
|
||||||
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
DecodeJSON(t, resp, &apiMilestones)
|
||||||
|
assert.Len(t, apiMilestones, 4)
|
||||||
|
|
||||||
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&name=%s&token=%s", owner.Name, repo.Name, "all", "milestone2", token))
|
||||||
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
DecodeJSON(t, resp, &apiMilestones)
|
||||||
|
assert.Len(t, apiMilestones, 1)
|
||||||
|
assert.Equal(t, int64(2), apiMilestones[0].ID)
|
||||||
|
|
||||||
|
req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%d?token=%s", owner.Name, repo.Name, apiMilestone.ID, token))
|
||||||
|
resp = session.MakeRequest(t, req, http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,25 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestAPIAllowedReactions(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
|
||||||
|
a := new(api.GeneralUISettings)
|
||||||
|
|
||||||
|
req := NewRequest(t, "GET", "/api/v1/settings/ui")
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
DecodeJSON(t, resp, &a)
|
||||||
|
assert.Len(t, a.AllowedReactions, len(setting.UI.Reactions))
|
||||||
|
assert.ElementsMatch(t, setting.UI.Reactions, a.AllowedReactions)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPIIssuesReactions(t *testing.T) {
|
func TestAPIIssuesReactions(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
defer prepareTestEnv(t)()
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ func TestAPINotification(t *testing.T) {
|
||||||
assert.EqualValues(t, false, apiNL[2].Pinned)
|
assert.EqualValues(t, false, apiNL[2].Pinned)
|
||||||
|
|
||||||
// -- GET /repos/{owner}/{repo}/notifications --
|
// -- GET /repos/{owner}/{repo}/notifications --
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?token=%s", user2.Name, repo1.Name, token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread&token=%s", user2.Name, repo1.Name, token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ func TestAPINotification(t *testing.T) {
|
||||||
assert.True(t, new.New > 0)
|
assert.True(t, new.New > 0)
|
||||||
|
|
||||||
// -- mark notifications as read --
|
// -- mark notifications as read --
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
assert.Len(t, apiNL, 2)
|
assert.Len(t, apiNL, 2)
|
||||||
|
@ -101,7 +101,7 @@ func TestAPINotification(t *testing.T) {
|
||||||
req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token))
|
req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusResetContent)
|
resp = session.MakeRequest(t, req, http.StatusResetContent)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
assert.Len(t, apiNL, 1)
|
assert.Len(t, apiNL, 1)
|
||||||
|
|
|
@ -86,6 +86,11 @@ func TestAPIPullReview(t *testing.T) {
|
||||||
Body: "first old line",
|
Body: "first old line",
|
||||||
OldLineNum: 1,
|
OldLineNum: 1,
|
||||||
NewLineNum: 0,
|
NewLineNum: 0,
|
||||||
|
}, {
|
||||||
|
Path: "iso-8859-1.txt",
|
||||||
|
Body: "this line contains a non-utf-8 character",
|
||||||
|
OldLineNum: 0,
|
||||||
|
NewLineNum: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -93,7 +98,7 @@ func TestAPIPullReview(t *testing.T) {
|
||||||
DecodeJSON(t, resp, &review)
|
DecodeJSON(t, resp, &review)
|
||||||
assert.EqualValues(t, 6, review.ID)
|
assert.EqualValues(t, 6, review.ID)
|
||||||
assert.EqualValues(t, "PENDING", review.State)
|
assert.EqualValues(t, "PENDING", review.State)
|
||||||
assert.EqualValues(t, 2, review.CodeCommentsCount)
|
assert.EqualValues(t, 3, review.CodeCommentsCount)
|
||||||
|
|
||||||
// test SubmitPullReview
|
// test SubmitPullReview
|
||||||
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, review.ID, token), &api.SubmitPullReviewOptions{
|
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, review.ID, token), &api.SubmitPullReviewOptions{
|
||||||
|
@ -104,7 +109,7 @@ func TestAPIPullReview(t *testing.T) {
|
||||||
DecodeJSON(t, resp, &review)
|
DecodeJSON(t, resp, &review)
|
||||||
assert.EqualValues(t, 6, review.ID)
|
assert.EqualValues(t, 6, review.ID)
|
||||||
assert.EqualValues(t, "APPROVED", review.State)
|
assert.EqualValues(t, "APPROVED", review.State)
|
||||||
assert.EqualValues(t, 2, review.CodeCommentsCount)
|
assert.EqualValues(t, 3, review.CodeCommentsCount)
|
||||||
|
|
||||||
// test DeletePullReview
|
// test DeletePullReview
|
||||||
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{
|
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{
|
||||||
|
|
|
@ -58,7 +58,7 @@ func TestAPIMergePullWIP(t *testing.T) {
|
||||||
session.MakeRequest(t, req, http.StatusMethodNotAllowed)
|
session.MakeRequest(t, req, http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPICreatePullSuccess1(t *testing.T) {
|
func TestAPICreatePullSuccess(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
defer prepareTestEnv(t)()
|
||||||
repo10 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 10}).(*models.Repository)
|
repo10 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 10}).(*models.Repository)
|
||||||
// repo10 have code, pulls units.
|
// repo10 have code, pulls units.
|
||||||
|
@ -78,7 +78,7 @@ func TestAPICreatePullSuccess1(t *testing.T) {
|
||||||
session.MakeRequest(t, req, 201)
|
session.MakeRequest(t, req, 201)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPICreatePullSuccess2(t *testing.T) {
|
func TestAPIEditPull(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
defer prepareTestEnv(t)()
|
||||||
repo10 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 10}).(*models.Repository)
|
repo10 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 10}).(*models.Repository)
|
||||||
owner10 := models.AssertExistsAndLoadBean(t, &models.User{ID: repo10.OwnerID}).(*models.User)
|
owner10 := models.AssertExistsAndLoadBean(t, &models.User{ID: repo10.OwnerID}).(*models.User)
|
||||||
|
@ -90,6 +90,21 @@ func TestAPICreatePullSuccess2(t *testing.T) {
|
||||||
Base: "master",
|
Base: "master",
|
||||||
Title: "create a success pr",
|
Title: "create a success pr",
|
||||||
})
|
})
|
||||||
|
pull := new(api.PullRequest)
|
||||||
|
resp := session.MakeRequest(t, req, 201)
|
||||||
|
DecodeJSON(t, resp, pull)
|
||||||
|
assert.EqualValues(t, "master", pull.Base.Name)
|
||||||
|
|
||||||
session.MakeRequest(t, req, 201)
|
req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d?token=%s", owner10.Name, repo10.Name, pull.Index, token), &api.EditPullRequestOption{
|
||||||
|
Base: "feature/1",
|
||||||
|
Title: "edit a this pr",
|
||||||
|
})
|
||||||
|
resp = session.MakeRequest(t, req, 201)
|
||||||
|
DecodeJSON(t, resp, pull)
|
||||||
|
assert.EqualValues(t, "feature/1", pull.Base.Name)
|
||||||
|
|
||||||
|
req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d?token=%s", owner10.Name, repo10.Name, pull.Index, token), &api.EditPullRequestOption{
|
||||||
|
Base: "not-exist",
|
||||||
|
})
|
||||||
|
session.MakeRequest(t, req, 404)
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,7 @@ func TestAPICreateFile(t *testing.T) {
|
||||||
treePath = "README.md"
|
treePath = "README.md"
|
||||||
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
|
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
|
||||||
req = NewRequestWithJSON(t, "POST", url, &createFileOptions)
|
req = NewRequestWithJSON(t, "POST", url, &createFileOptions)
|
||||||
resp = session.MakeRequest(t, req, http.StatusInternalServerError)
|
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||||
expectedAPIError := context.APIError{
|
expectedAPIError := context.APIError{
|
||||||
Message: "repository file already exists [path: " + treePath + "]",
|
Message: "repository file already exists [path: " + treePath + "]",
|
||||||
URL: setting.API.SwaggerURL,
|
URL: setting.API.SwaggerURL,
|
||||||
|
|
|
@ -208,7 +208,7 @@ func TestAPIUpdateFile(t *testing.T) {
|
||||||
updateFileOptions.SHA = "badsha"
|
updateFileOptions.SHA = "badsha"
|
||||||
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
|
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2)
|
||||||
req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions)
|
req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions)
|
||||||
resp = session.MakeRequest(t, req, http.StatusInternalServerError)
|
resp = session.MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||||
expectedAPIError := context.APIError{
|
expectedAPIError := context.APIError{
|
||||||
Message: "sha does not match [given: " + updateFileOptions.SHA + ", expected: " + correctSHA + "]",
|
Message: "sha does not match [given: " + updateFileOptions.SHA + ", expected: " + correctSHA + "]",
|
||||||
URL: setting.API.SwaggerURL,
|
URL: setting.API.SwaggerURL,
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright 2020 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 integrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRepoLanguages(t *testing.T) {
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
session := loginUser(t, "user2")
|
||||||
|
|
||||||
|
// Request editor page
|
||||||
|
req := NewRequest(t, "GET", "/user2/repo1/_new/master/")
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
doc := NewHTMLParser(t, resp.Body)
|
||||||
|
lastCommit := doc.GetInputValueByName("last_commit")
|
||||||
|
assert.NotEmpty(t, lastCommit)
|
||||||
|
|
||||||
|
// Save new file to master branch
|
||||||
|
req = NewRequestWithValues(t, "POST", "/user2/repo1/_new/master/", map[string]string{
|
||||||
|
"_csrf": doc.GetCSRF(),
|
||||||
|
"last_commit": lastCommit,
|
||||||
|
"tree_path": "test.go",
|
||||||
|
"content": "package main",
|
||||||
|
"commit_choice": "direct",
|
||||||
|
})
|
||||||
|
session.MakeRequest(t, req, http.StatusFound)
|
||||||
|
|
||||||
|
// let gitea calculate language stats
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
// Save new file to master branch
|
||||||
|
req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/languages")
|
||||||
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
var languages map[string]int64
|
||||||
|
DecodeJSON(t, resp, &languages)
|
||||||
|
|
||||||
|
assert.InDeltaMapValues(t, map[string]int64{"Go": 12}, languages, 0)
|
||||||
|
})
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -57,6 +58,12 @@ func TestAPISearchRepo(t *testing.T) {
|
||||||
user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 20}).(*models.User)
|
user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 20}).(*models.User)
|
||||||
orgUser := models.AssertExistsAndLoadBean(t, &models.User{ID: 17}).(*models.User)
|
orgUser := models.AssertExistsAndLoadBean(t, &models.User{ID: 17}).(*models.User)
|
||||||
|
|
||||||
|
oldAPIDefaultNum := setting.API.DefaultPagingNum
|
||||||
|
defer func() {
|
||||||
|
setting.API.DefaultPagingNum = oldAPIDefaultNum
|
||||||
|
}()
|
||||||
|
setting.API.DefaultPagingNum = 10
|
||||||
|
|
||||||
// Map of expected results, where key is user for login
|
// Map of expected results, where key is user for login
|
||||||
type expectedResults map[*models.User]struct {
|
type expectedResults map[*models.User]struct {
|
||||||
count int
|
count int
|
||||||
|
@ -79,7 +86,7 @@ func TestAPISearchRepo(t *testing.T) {
|
||||||
user: {count: 10},
|
user: {count: 10},
|
||||||
user2: {count: 10}},
|
user2: {count: 10}},
|
||||||
},
|
},
|
||||||
{name: "RepositoriesDefaultMax10", requestURL: "/api/v1/repos/search?default&private=false", expectedResults: expectedResults{
|
{name: "RepositoriesDefault", requestURL: "/api/v1/repos/search?default&private=false", expectedResults: expectedResults{
|
||||||
nil: {count: 10},
|
nil: {count: 10},
|
||||||
user: {count: 10},
|
user: {count: 10},
|
||||||
user2: {count: 10}},
|
user2: {count: 10}},
|
||||||
|
@ -297,11 +304,11 @@ func TestAPIRepoMigrate(t *testing.T) {
|
||||||
cloneURL, repoName string
|
cloneURL, repoName string
|
||||||
expectedStatus int
|
expectedStatus int
|
||||||
}{
|
}{
|
||||||
{ctxUserID: 1, userID: 2, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-admin", expectedStatus: http.StatusCreated},
|
{ctxUserID: 1, userID: 2, cloneURL: "https://github.com/go-gitea/test_repo.git", repoName: "git-admin", expectedStatus: http.StatusCreated},
|
||||||
{ctxUserID: 2, userID: 2, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-own", expectedStatus: http.StatusCreated},
|
{ctxUserID: 2, userID: 2, cloneURL: "https://github.com/go-gitea/test_repo.git", repoName: "git-own", expectedStatus: http.StatusCreated},
|
||||||
{ctxUserID: 2, userID: 1, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-bad", expectedStatus: http.StatusForbidden},
|
{ctxUserID: 2, userID: 1, cloneURL: "https://github.com/go-gitea/test_repo.git", repoName: "git-bad", expectedStatus: http.StatusForbidden},
|
||||||
{ctxUserID: 2, userID: 3, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-org", expectedStatus: http.StatusCreated},
|
{ctxUserID: 2, userID: 3, cloneURL: "https://github.com/go-gitea/test_repo.git", repoName: "git-org", expectedStatus: http.StatusCreated},
|
||||||
{ctxUserID: 2, userID: 6, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-bad-org", expectedStatus: http.StatusForbidden},
|
{ctxUserID: 2, userID: 6, cloneURL: "https://github.com/go-gitea/test_repo.git", repoName: "git-bad-org", expectedStatus: http.StatusForbidden},
|
||||||
}
|
}
|
||||||
|
|
||||||
defer prepareTestEnv(t)()
|
defer prepareTestEnv(t)()
|
||||||
|
@ -341,7 +348,7 @@ func testAPIRepoMigrateConflict(t *testing.T, u *url.URL) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
userID := user.ID
|
userID := user.ID
|
||||||
|
|
||||||
cloneURL := "https://github.com/go-gitea/git.git"
|
cloneURL := "https://github.com/go-gitea/test_repo.git"
|
||||||
|
|
||||||
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+httpContext.Token,
|
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+httpContext.Token,
|
||||||
&api.MigrateRepoOption{
|
&api.MigrateRepoOption{
|
||||||
|
|
|
@ -32,14 +32,14 @@ func TestDeleteBranch(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUndoDeleteBranch(t *testing.T) {
|
func TestUndoDeleteBranch(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
deleteBranch(t)
|
||||||
deleteBranch(t)
|
htmlDoc, name := branchAction(t, ".undo-button")
|
||||||
htmlDoc, name := branchAction(t, ".undo-button")
|
assert.Contains(t,
|
||||||
assert.Contains(t,
|
htmlDoc.doc.Find(".ui.positive.message").Text(),
|
||||||
htmlDoc.doc.Find(".ui.positive.message").Text(),
|
i18n.Tr("en", "repo.branch.restore_success", name),
|
||||||
i18n.Tr("en", "repo.branch.restore_success", name),
|
)
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteBranch(t *testing.T) {
|
func deleteBranch(t *testing.T) {
|
||||||
|
|
|
@ -59,7 +59,7 @@ func TestEventSourceManagerRun(t *testing.T) {
|
||||||
var apiNL []api.NotificationThread
|
var apiNL []api.NotificationThread
|
||||||
|
|
||||||
// -- mark notifications as read --
|
// -- mark notifications as read --
|
||||||
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token))
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
|
@ -69,7 +69,7 @@ func TestEventSourceManagerRun(t *testing.T) {
|
||||||
req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token))
|
req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusResetContent)
|
resp = session.MakeRequest(t, req, http.StatusResetContent)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s&status-types=unread", token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiNL)
|
DecodeJSON(t, resp, &apiNL)
|
||||||
assert.Len(t, apiNL, 1)
|
assert.Len(t, apiNL, 1)
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
xe<>±NÄ0D©#åæŽ4
|
||||||
|
JÄAÅ5”޳—,—xÑzsVþ<56>‚5„DåÑØ»ž7ý,=®®o.áEå<45>¢áq5J=éˆý<CB86>È rÄ=>4§ú
O!óŠý<C5A0>ã´ðÐ6ms˜8ƒ¾&\Ea¾tÍT„´I¢z”‰Ô…! ¢dso@a›Ú&ÌK5üB)›r4–”Q¦`YèLÚ¯²b ›<>¾o`Ûaä3¹@(<C5A0>ÒeýÔ5
ô<>ÂH—\sÔHÿ9Ÿ9Rª3)Îë@ŽSùã_"§‘4sE0”Rºñ§¤.‘U|/€m¦Û¿]U÷ÌzÀ
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
4a357436d925b5c974181ff12a994538ddc5a269
|
5f22f7d0d95d614d25a5b68592adb345a4b5c7fd
|
||||||
|
|
|
@ -22,10 +22,12 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"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/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
|
"code.gitea.io/gitea/modules/queue"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/routers"
|
"code.gitea.io/gitea/routers"
|
||||||
"code.gitea.io/gitea/routers/routes"
|
"code.gitea.io/gitea/routers/routes"
|
||||||
|
@ -34,7 +36,6 @@ import (
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/unknwon/com"
|
"github.com/unknwon/com"
|
||||||
"gopkg.in/testfixtures.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var mac *macaron.Macaron
|
var mac *macaron.Macaron
|
||||||
|
@ -65,22 +66,28 @@ func TestMain(m *testing.M) {
|
||||||
mac = routes.NewMacaron()
|
mac = routes.NewMacaron()
|
||||||
routes.RegisterRoutes(mac)
|
routes.RegisterRoutes(mac)
|
||||||
|
|
||||||
var helper testfixtures.Helper
|
// integration test settings...
|
||||||
if setting.Database.UseMySQL {
|
if setting.Cfg != nil {
|
||||||
helper = &testfixtures.MySQL{}
|
testingCfg := setting.Cfg.Section("integration-tests")
|
||||||
} else if setting.Database.UsePostgreSQL {
|
slowTest = testingCfg.Key("SLOW_TEST").MustDuration(slowTest)
|
||||||
helper = &testfixtures.PostgreSQL{}
|
slowFlush = testingCfg.Key("SLOW_FLUSH").MustDuration(slowFlush)
|
||||||
} else if setting.Database.UseSQLite3 {
|
}
|
||||||
helper = &testfixtures.SQLite{}
|
|
||||||
} else if setting.Database.UseMSSQL {
|
if os.Getenv("GITEA_SLOW_TEST_TIME") != "" {
|
||||||
helper = &testfixtures.SQLServer{}
|
duration, err := time.ParseDuration(os.Getenv("GITEA_SLOW_TEST_TIME"))
|
||||||
} else {
|
if err == nil {
|
||||||
fmt.Println("Unsupported RDBMS for integration tests")
|
slowTest = duration
|
||||||
os.Exit(1)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("GITEA_SLOW_FLUSH_TIME") != "" {
|
||||||
|
duration, err := time.ParseDuration(os.Getenv("GITEA_SLOW_FLUSH_TIME"))
|
||||||
|
if err == nil {
|
||||||
|
slowFlush = duration
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := models.InitFixtures(
|
err := models.InitFixtures(
|
||||||
helper,
|
|
||||||
path.Join(filepath.Dir(setting.AppPath), "models/fixtures/"),
|
path.Join(filepath.Dir(setting.AppPath), "models/fixtures/"),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -459,3 +466,14 @@ func GetCSRF(t testing.TB, session *TestSession, urlStr string) string {
|
||||||
doc := NewHTMLParser(t, resp.Body)
|
doc := NewHTMLParser(t, resp.Body)
|
||||||
return doc.GetCSRF()
|
return doc.GetCSRF()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resetFixtures flushes queues, reloads fixtures and resets test repositories within a single test.
|
||||||
|
// Most tests should call defer prepareTestEnv(t)() (or have onGiteaRun do that for them) but sometimes
|
||||||
|
// within a single test this is required
|
||||||
|
func resetFixtures(t *testing.T) {
|
||||||
|
assert.NoError(t, queue.GetManager().FlushAll(context.Background(), -1))
|
||||||
|
assert.NoError(t, models.LoadFixtures())
|
||||||
|
assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
|
||||||
|
assert.NoError(t, com.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"),
|
||||||
|
setting.RepoRootPath))
|
||||||
|
}
|
||||||
|
|
|
@ -33,8 +33,6 @@ func TestLinksNoLogin(t *testing.T) {
|
||||||
"/user/forgot_password",
|
"/user/forgot_password",
|
||||||
"/api/swagger",
|
"/api/swagger",
|
||||||
"/api/v1/swagger",
|
"/api/v1/swagger",
|
||||||
// TODO: follow this page and test every link
|
|
||||||
"/vendor/librejs.html",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, link := range links {
|
for _, link := range links {
|
||||||
|
|
|
@ -33,12 +33,15 @@ SSH_LISTEN_HOST = localhost
|
||||||
SSH_PORT = 2201
|
SSH_PORT = 2201
|
||||||
START_SSH_SERVER = true
|
START_SSH_SERVER = true
|
||||||
LFS_START_SERVER = true
|
LFS_START_SERVER = true
|
||||||
LFS_CONTENT_PATH = data/lfs-mssql
|
LFS_CONTENT_PATH = integrations/gitea-integration-mssql/data/lfs-mssql
|
||||||
OFFLINE_MODE = false
|
OFFLINE_MODE = false
|
||||||
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
|
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
|
||||||
APP_DATA_PATH = integrations/gitea-integration-mssql/data
|
APP_DATA_PATH = integrations/gitea-integration-mssql/data
|
||||||
BUILTIN_SSH_SERVER_USER = git
|
BUILTIN_SSH_SERVER_USER = git
|
||||||
|
|
||||||
|
[attachment]
|
||||||
|
PATH = integrations/gitea-integration-mssql/data
|
||||||
|
|
||||||
[mailer]
|
[mailer]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
MAILER_TYPE = dummy
|
MAILER_TYPE = dummy
|
||||||
|
@ -56,12 +59,14 @@ NO_REPLY_ADDRESS = noreply.example.org
|
||||||
ENABLE_NOTIFY_MAIL = true
|
ENABLE_NOTIFY_MAIL = true
|
||||||
|
|
||||||
[picture]
|
[picture]
|
||||||
DISABLE_GRAVATAR = false
|
DISABLE_GRAVATAR = false
|
||||||
ENABLE_FEDERATED_AVATAR = false
|
ENABLE_FEDERATED_AVATAR = false
|
||||||
|
AVATAR_UPLOAD_PATH = integrations/gitea-integration-mssql/data/avatars
|
||||||
|
REPOSITORY_AVATAR_UPLOAD_PATH = integrations/gitea-integration-mssql/data/repo-avatars
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
PROVIDER = file
|
PROVIDER = file
|
||||||
PROVIDER_CONFIG = data/sessions-mssql
|
PROVIDER_CONFIG = integrations/gitea-integration-mssql/data/sessions
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
MODE = test,file
|
MODE = test,file
|
||||||
|
|
|
@ -35,12 +35,15 @@ SSH_LISTEN_HOST = localhost
|
||||||
SSH_PORT = 2201
|
SSH_PORT = 2201
|
||||||
START_SSH_SERVER = true
|
START_SSH_SERVER = true
|
||||||
LFS_START_SERVER = true
|
LFS_START_SERVER = true
|
||||||
LFS_CONTENT_PATH = data/lfs-mysql
|
LFS_CONTENT_PATH = integrations/gitea-integration-mysql/datalfs-mysql
|
||||||
OFFLINE_MODE = false
|
OFFLINE_MODE = false
|
||||||
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
|
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
|
||||||
APP_DATA_PATH = integrations/gitea-integration-mysql/data
|
APP_DATA_PATH = integrations/gitea-integration-mysql/data
|
||||||
BUILTIN_SSH_SERVER_USER = git
|
BUILTIN_SSH_SERVER_USER = git
|
||||||
|
|
||||||
|
[attachment]
|
||||||
|
PATH = integrations/gitea-integration-mysql/data
|
||||||
|
|
||||||
[mailer]
|
[mailer]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
MAILER_TYPE = dummy
|
MAILER_TYPE = dummy
|
||||||
|
@ -58,12 +61,14 @@ NO_REPLY_ADDRESS = noreply.example.org
|
||||||
ENABLE_NOTIFY_MAIL = true
|
ENABLE_NOTIFY_MAIL = true
|
||||||
|
|
||||||
[picture]
|
[picture]
|
||||||
DISABLE_GRAVATAR = false
|
DISABLE_GRAVATAR = false
|
||||||
ENABLE_FEDERATED_AVATAR = false
|
ENABLE_FEDERATED_AVATAR = false
|
||||||
|
AVATAR_UPLOAD_PATH = integrations/gitea-integration-mysql/data/avatars
|
||||||
|
REPOSITORY_AVATAR_UPLOAD_PATH = integrations/gitea-integration-mysql/data/repo-avatars
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
PROVIDER = file
|
PROVIDER = file
|
||||||
PROVIDER_CONFIG = data/sessions-mysql
|
PROVIDER_CONFIG = integrations/gitea-integration-mysql/data/sessions
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
MODE = test,file
|
MODE = test,file
|
||||||
|
|
|
@ -34,12 +34,15 @@ SSH_LISTEN_HOST = localhost
|
||||||
SSH_PORT = 2202
|
SSH_PORT = 2202
|
||||||
START_SSH_SERVER = true
|
START_SSH_SERVER = true
|
||||||
LFS_START_SERVER = true
|
LFS_START_SERVER = true
|
||||||
LFS_CONTENT_PATH = data/lfs-pgsql
|
LFS_CONTENT_PATH = integrations/gitea-integration-pgsql/data/lfs-pgsql
|
||||||
OFFLINE_MODE = false
|
OFFLINE_MODE = false
|
||||||
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
|
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
|
||||||
APP_DATA_PATH = integrations/gitea-integration-pgsql/data
|
APP_DATA_PATH = integrations/gitea-integration-pgsql/data
|
||||||
BUILTIN_SSH_SERVER_USER = git
|
BUILTIN_SSH_SERVER_USER = git
|
||||||
|
|
||||||
|
[attachment]
|
||||||
|
PATH = integrations/gitea-integration-pgsql/data
|
||||||
|
|
||||||
[mailer]
|
[mailer]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
MAILER_TYPE = dummy
|
MAILER_TYPE = dummy
|
||||||
|
@ -57,12 +60,14 @@ NO_REPLY_ADDRESS = noreply.example.org
|
||||||
ENABLE_NOTIFY_MAIL = true
|
ENABLE_NOTIFY_MAIL = true
|
||||||
|
|
||||||
[picture]
|
[picture]
|
||||||
DISABLE_GRAVATAR = false
|
DISABLE_GRAVATAR = false
|
||||||
ENABLE_FEDERATED_AVATAR = false
|
ENABLE_FEDERATED_AVATAR = false
|
||||||
|
AVATAR_UPLOAD_PATH = integrations/gitea-integration-pgsql/data/avatars
|
||||||
|
REPOSITORY_AVATAR_UPLOAD_PATH = integrations/gitea-integration-pgsql/data/repo-avatars
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
PROVIDER = file
|
PROVIDER = file
|
||||||
PROVIDER_CONFIG = data/sessions-pgsql
|
PROVIDER_CONFIG = integrations/gitea-integration-pgsql/data/sessions
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
MODE = test,file
|
MODE = test,file
|
||||||
|
|
|
@ -76,6 +76,53 @@ nARUPZ9SqaUmRm+KGsSyoYnvN9apiDk5KVQoyfrmweNN7DCIIcoh/B9Ax8nmouKz
|
||||||
yBB2fjCM/bJNtN/AsgYbZIScuYK/xqTkwNtbe5WdCyD/QJOHTsPJzx59hgSVo6gf
|
yBB2fjCM/bJNtN/AsgYbZIScuYK/xqTkwNtbe5WdCyD/QJOHTsPJzx59hgSVo6gf
|
||||||
Fe8VBnxHtrY8gPSUU3gkhYLvLzyVX+YLNzRcffobd8gJbfumwFJUkz91oGvYz7xg
|
Fe8VBnxHtrY8gPSUU3gkhYLvLzyVX+YLNzRcffobd8gJbfumwFJUkz91oGvYz7xg
|
||||||
XN2qmsgBNCbTIzWZMpRDMAbY+n2QFImGf+EJZlMdj6gOrIYq8N4+nMW1FwJivsOb
|
XN2qmsgBNCbTIzWZMpRDMAbY+n2QFImGf+EJZlMdj6gOrIYq8N4+nMW1FwJivsOb
|
||||||
muqySyjZnD2AYjEA6OYPXfCVhaB5fTfhQXbIrZbgsEh4ob/eIdM=
|
muqySyjZnD2AYjEA6OYPXfCVhaB5fTfhQXbIrZbgsEh4ob/eIdOdBVgEXta5egEM
|
||||||
=oSDR
|
AMYlmZ47NqBMBeaN0o/ahYMe8eIMaroWkufMfC9VRBSMAkpbDl34oNp0cflmnMYo
|
||||||
|
AFAl8ucRMFTiUnjiWpo27q14tjSyDVsn/CqwbnrgJgCFNV/MGsYsToEkb4JwDIRC
|
||||||
|
bky+1BvqvI8RMlO3MlwzrlIaMrlQfx5NtUb9TyO7S4xZTz864+Ty5p3HhRwbdZMe
|
||||||
|
Ko8sfXFhCcCHFXosI0mX83EyzsrXlbkGRawId7jvrdOAUg/cYP8f/XmV6z1NHHH9
|
||||||
|
cvz+3oLOGuVxUdG0KuS/jigHrLWdRuKM3xfEeesp870yZU3AbyFdoHnGXROJePTl
|
||||||
|
FV8j2P5Ahf/yuVhjdyJSKdZC2h6+HtLG9RiGgLviLLYhtlZG2H6pYyKY5Ud3php+
|
||||||
|
qw1aYL1xtdxrHYkQlAa0vLY/mwpuPfMke9I+rtnrwlLRMCstdiN34ybZ4sRD+gL1
|
||||||
|
w5VIZ/aM6/Gsczd3s/T8psIi09TKPfEU2gWLMGvlDsgz+aSDdVP7XYQpNglaEPet
|
||||||
|
PwARAQABAAv8CHg6+hnV2pblTwGTlTU7V8DO3gwMfn/QhQ/8ju66G5a7J6p/ZreQ
|
||||||
|
nfCJnqYq4AgoW0SuqVSBbbTENF6YjixNmiSlb9iHMZ+ilms24xG0Y3lOMBYYCY3Y
|
||||||
|
nTSNf6nXyconz31TW7jLmTdG9hpykKEKO9WFgt5UpgWe+2CAgtUoBDZyaLrVBZ2h
|
||||||
|
te99WmziDbPQZeZPm7UQ0aX0iRBclxy4+dxjcnrcmi1mdQAM/glgs2sHbEjN7JnV
|
||||||
|
dTOvUSN7/8ixj6I719Wx6MN6jE+BNd0ytZOun6tcDl0vamfT5fBpqbQoJMib2ggo
|
||||||
|
+FGg9VFnzEMLqyI47LfOKUjCIhwVsxS4q9HXa2FtpO8UfRMPjDKgDZQzRTRJScrP
|
||||||
|
s1NJ9HiM/eCHS1YjRmgroo60HygxkoLVCHp+Rz/hi0tG/ptv4q6mdnm8Mwb5JJtV
|
||||||
|
48EvmZoNTWl9xOez1wmQn6caVHipc0qDqn/veoe8N5wdc+3hoMEXbSXqU+kx2KUa
|
||||||
|
cVxCCVoUeURhBgDUGWtx34j1y17zE92BYhtVJTCU89dDe4wOEqGPyCGvRtgTmZ+1
|
||||||
|
KwWr66pij91MV9mlY+7Ue2QHUSmgav2EFGIjVes956p4/F/CJ6qaYoekirMSnmX5
|
||||||
|
jhRt4p6RW7m4omha3LAQ+gN4Fqa4acZUywENBvv1x3v+IWbjGJGn3eBnRrP3o9P+
|
||||||
|
QUAtyMifiRm0ZN8J767o+bzUVmscXrkh7Qml47lQfDToyRI1UZZQmP2izpwHcwbZ
|
||||||
|
NtfkgRUdeEq4GJUGAO8o4Oebbt0ALZ54E2LHhk8xi4ofKkFBDCkUFjcqS3bJJNck
|
||||||
|
rkhfqEkMLETNhPbiC4TRNiunI5PXOinwNPkKI8P/hfp4S49WdIvnARazCoxjZNtl
|
||||||
|
0Cbo+F1wtOH9FZaaWzNlU2lCQ2JJ3MCpLHz+nEmdYWOIWGQu2/s7smLODVEFbYKR
|
||||||
|
50VWVRL7mB83v1XdfMFvExdQ7i5MOX4hFvmwi/WJIKClJfhNwTrHp6Jrm9jA66RL
|
||||||
|
+dNyPKfwcFcYrqt1gwYAruZzP7QgTYVL+cmvGtCaHY4KoR8hanbpqR4YbzzyEXwS
|
||||||
|
ll2FUCaVSokuRAdH3+/CHF9bqog3Zvn6HYcCS/A/rHVGIU9a+7s5IbRe0Ysc2FAN
|
||||||
|
Nm9AsC5YnuyoAjW3cJGaZLYxp2WOZcMEXZeLPFYrNz22R1nRoxnUIPRpsKICXcK0
|
||||||
|
aC4rSMk479jc/8WprWx4d45EVG+6Gsh1AT8LVhDL9yHFrh50ss2jCe1Fnftet6DI
|
||||||
|
V5zHcxBx4sCs91aPxxe12UiJA2wEGAEKACAWIQQ4G/p4KVUOUEVu5g5R68KXFICq
|
||||||
|
DwUCXta5egIbAgHACRBR68KXFICqD8D0IAQZAQoAHRYhBKAm5ShdO9gmF/o8jan0
|
||||||
|
RkmWoKbKBQJe1rl6AAoJEKn0RkmWoKbKacUL/3YYKmiVvcr5LYFzMdwdahkla+6m
|
||||||
|
hEEkL0l3dJNuU97Ou71tA1ieF0fjbVRSWjXKsntKwhyPoXjaZEZwMmv7iZ8BXV+b
|
||||||
|
oO/EG5sg2/6iukJFXZqGnQwMdLVo1jPoXDteZU1qYiCoxLHhGhHL7ivtD1ygEi6w
|
||||||
|
/cMbbOEB5Le1vOWIwqazs8dDcAYyy1PKthRl0ygvh8CpqPwy+AK3uLm0TVwetQAp
|
||||||
|
taux0bDYWCb5Aft1r1nlV44gU4RiC131TDo+TKd754+UuI+UHk1D+LjTmZxRX2S6
|
||||||
|
fXgoMXzrWmthGPdqvVOgKWm7Ef18hmaBECvPnp/tUJeDVVe02KrYQi8Bf2kxveSd
|
||||||
|
8T0N/ExcydU9HgzTL8MuyPI+yp086elQzKJu6vb9tpgxCcglQZrUNT9Uy82pzTRY
|
||||||
|
z9MmhnCDI2SD5L/CW5PsNpPTPy7s3f9DOV0G5Vka4LTSBOCK64NvAGBmRf8rFjJU
|
||||||
|
lPtRPhC7h6uHdUIx3Q550Xogvq5sQm8UBCsbG8OJDADT3FJSIulR9Sh96OsES3sc
|
||||||
|
H09juN4KcbpS03MAeUFwXqw3jBMhDoGKlsjX17Jf31qh/nI/XjigS3XWyj1BLSMG
|
||||||
|
rJfH0NyYoGDCnff37tf+8lD9km9TlnV4Qjd9ujYbDRsefhaSjLVcy/gqdxZEuNBC
|
||||||
|
BWmGwsmLI3nyZ4KDtNsa5JUHUNNZLBN20hvmE41Eszmz4Yg9Ho9DxKiFKvzUULMc
|
||||||
|
bnMHaVHseHHq6+NVUnN1SAcOA0ygjnEid8D57RtdBCD90LXjLB7vlR+HaSMZYOnr
|
||||||
|
DtseivHvqqy4+rxhwV2S3avnls9vRwE4bV6GCiqhoBnWIZRrARLZc2OTBIya82vS
|
||||||
|
BIS1eyhjif1mE7Lqhs6aPD+eqQK2mBtQ/sidN8P/IfKfVF5siXfFbuGZLz5nRIho
|
||||||
|
Yp1z7oO3OZ09lpUk0G1h+ouIFF6goDP48M/AKtbvs9OWk3QKxnOUZD8sRncq95x6
|
||||||
|
m4q1MVb+aJyxwBqDRGaFY+3TVArB1b+kG1JsAvV5dag=
|
||||||
|
=511T
|
||||||
-----END PGP PRIVATE KEY BLOCK-----
|
-----END PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
|
@ -0,0 +1,414 @@
|
||||||
|
// Copyright 2020 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 integrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
const privateActivityTestAdmin = "user1"
|
||||||
|
const privateActivityTestUser = "user2"
|
||||||
|
|
||||||
|
// user3 is an organization so it is not usable here
|
||||||
|
const privateActivityTestOtherUser = "user4"
|
||||||
|
|
||||||
|
// activity helpers
|
||||||
|
|
||||||
|
func testPrivateActivityDoSomethingForActionEntries(t *testing.T) {
|
||||||
|
repoBefore := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
|
||||||
|
owner := models.AssertExistsAndLoadBean(t, &models.User{ID: repoBefore.OwnerID}).(*models.User)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
token := getTokenForLoggedInUser(t, session)
|
||||||
|
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all&token=%s", owner.Name, repoBefore.Name, token)
|
||||||
|
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{
|
||||||
|
Body: "test",
|
||||||
|
Title: "test",
|
||||||
|
})
|
||||||
|
session.MakeRequest(t, req, http.StatusCreated)
|
||||||
|
}
|
||||||
|
|
||||||
|
// private activity helpers
|
||||||
|
|
||||||
|
func testPrivateActivityHelperEnablePrivateActivity(t *testing.T) {
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
|
||||||
|
"_csrf": GetCSRF(t, session, "/user/settings"),
|
||||||
|
"name": privateActivityTestUser,
|
||||||
|
"email": privateActivityTestUser + "@example.com",
|
||||||
|
"language": "en-us",
|
||||||
|
"keep_activity_private": "1",
|
||||||
|
})
|
||||||
|
session.MakeRequest(t, req, http.StatusFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasVisibleActivitiesInHTMLDoc(htmlDoc *HTMLDoc) bool {
|
||||||
|
return htmlDoc.doc.Find(".feeds").Find(".news").Length() > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasVisibleActivitiesFromSession(t *testing.T, session *TestSession) bool {
|
||||||
|
req := NewRequestf(t, "GET", "/%s?tab=activity", privateActivityTestUser)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
|
return testPrivateActivityHelperHasVisibleActivitiesInHTMLDoc(htmlDoc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasVisibleActivitiesFromPublic(t *testing.T) bool {
|
||||||
|
req := NewRequestf(t, "GET", "/%s?tab=activity", privateActivityTestUser)
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
|
return testPrivateActivityHelperHasVisibleActivitiesInHTMLDoc(htmlDoc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// heatmap UI helpers
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasVisibleHeatmapInHTMLDoc(htmlDoc *HTMLDoc) bool {
|
||||||
|
return htmlDoc.doc.Find("#user-heatmap").Length() > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasVisibleProfileHeatmapFromSession(t *testing.T, session *TestSession) bool {
|
||||||
|
req := NewRequestf(t, "GET", "/%s?tab=activity", privateActivityTestUser)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
|
return testPrivateActivityHelperHasVisibleHeatmapInHTMLDoc(htmlDoc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasVisibleDashboardHeatmapFromSession(t *testing.T, session *TestSession) bool {
|
||||||
|
req := NewRequest(t, "GET", "/")
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
|
return testPrivateActivityHelperHasVisibleHeatmapInHTMLDoc(htmlDoc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasVisibleHeatmapFromPublic(t *testing.T) bool {
|
||||||
|
req := NewRequestf(t, "GET", "/%s?tab=activity", privateActivityTestUser)
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
|
||||||
|
return testPrivateActivityHelperHasVisibleHeatmapInHTMLDoc(htmlDoc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// heatmap API helpers
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasHeatmapContentFromPublic(t *testing.T) bool {
|
||||||
|
req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap", privateActivityTestUser)
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
var items []*models.UserHeatmapData
|
||||||
|
DecodeJSON(t, resp, &items)
|
||||||
|
|
||||||
|
return len(items) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPrivateActivityHelperHasHeatmapContentFromSession(t *testing.T, session *TestSession) bool {
|
||||||
|
token := getTokenForLoggedInUser(t, session)
|
||||||
|
|
||||||
|
req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap?token=%s", privateActivityTestUser, token)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
var items []*models.UserHeatmapData
|
||||||
|
DecodeJSON(t, resp, &items)
|
||||||
|
|
||||||
|
return len(items) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// check activity visibility if the visibility is enabled
|
||||||
|
|
||||||
|
func TestPrivateActivityNoVisibleForPublic(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
visible := testPrivateActivityHelperHasVisibleActivitiesFromPublic(t)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible activities")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoVisibleForUserItself(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleActivitiesFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible activities")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoVisibleForOtherUser(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestOtherUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleActivitiesFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible activities")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoVisibleForAdmin(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestAdmin)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleActivitiesFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible activities")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check activity visibility if the visibility is disabled
|
||||||
|
|
||||||
|
func TestPrivateActivityYesInvisibleForPublic(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
visible := testPrivateActivityHelperHasVisibleActivitiesFromPublic(t)
|
||||||
|
|
||||||
|
assert.False(t, visible, "user should have no visible activities")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesVisibleForUserItself(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleActivitiesFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible activities")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesInvisibleForOtherUser(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestOtherUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleActivitiesFromSession(t, session)
|
||||||
|
|
||||||
|
assert.False(t, visible, "user should have no visible activities")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesVisibleForAdmin(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestAdmin)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleActivitiesFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible activities")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check heatmap visibility if the visibility is enabled
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapVisibleForPublic(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
visible := testPrivateActivityHelperHasVisibleHeatmapFromPublic(t)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapVisibleForUserItselfAtProfile(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleProfileHeatmapFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapVisibleForUserItselfAtDashboard(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleDashboardHeatmapFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapVisibleForOtherUser(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestOtherUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleProfileHeatmapFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapVisibleForAdmin(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestAdmin)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleProfileHeatmapFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, visible, "user should have visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check heatmap visibility if the visibility is disabled
|
||||||
|
// this behavior, in special the one for the admin, is
|
||||||
|
// due to the fact that the heatmap is the same for all viewers;
|
||||||
|
// otherwise, there is no reason for it
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapInvisibleForPublic(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
visible := testPrivateActivityHelperHasVisibleHeatmapFromPublic(t)
|
||||||
|
|
||||||
|
assert.False(t, visible, "user should have no visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapInvisibleForUserItselfAtProfile(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleProfileHeatmapFromSession(t, session)
|
||||||
|
|
||||||
|
assert.False(t, visible, "user should have no visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapInvisibleForUserItselfAtDashboard(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleDashboardHeatmapFromSession(t, session)
|
||||||
|
|
||||||
|
assert.False(t, visible, "user should have no visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapInvisibleForOtherUser(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestOtherUser)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleProfileHeatmapFromSession(t, session)
|
||||||
|
|
||||||
|
assert.False(t, visible, "user should have no visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapInvsisibleForAdmin(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestAdmin)
|
||||||
|
visible := testPrivateActivityHelperHasVisibleProfileHeatmapFromSession(t, session)
|
||||||
|
|
||||||
|
assert.False(t, visible, "user should have no visible heatmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check heatmap api provides content if the visibility is enabled
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapHasContentForPublic(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
hasContent := testPrivateActivityHelperHasHeatmapContentFromPublic(t)
|
||||||
|
|
||||||
|
assert.True(t, hasContent, "user should have heatmap content")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapHasContentForUserItself(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
hasContent := testPrivateActivityHelperHasHeatmapContentFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, hasContent, "user should have heatmap content")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapHasContentForOtherUser(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestOtherUser)
|
||||||
|
hasContent := testPrivateActivityHelperHasHeatmapContentFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, hasContent, "user should have heatmap content")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityNoHeatmapHasContentForAdmin(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestAdmin)
|
||||||
|
hasContent := testPrivateActivityHelperHasHeatmapContentFromSession(t, session)
|
||||||
|
|
||||||
|
assert.True(t, hasContent, "user should have heatmap content")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check heatmap api provides no content if the visibility is disabled
|
||||||
|
// this should be equal to the hidden heatmap at the UI
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapHasNoContentForPublic(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
hasContent := testPrivateActivityHelperHasHeatmapContentFromPublic(t)
|
||||||
|
|
||||||
|
assert.False(t, hasContent, "user should have no heatmap content")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapHasNoContentForUserItself(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestUser)
|
||||||
|
hasContent := testPrivateActivityHelperHasHeatmapContentFromSession(t, session)
|
||||||
|
|
||||||
|
assert.False(t, hasContent, "user should have no heatmap content")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapHasNoContentForOtherUser(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestOtherUser)
|
||||||
|
hasContent := testPrivateActivityHelperHasHeatmapContentFromSession(t, session)
|
||||||
|
|
||||||
|
assert.False(t, hasContent, "user should have no heatmap content")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrivateActivityYesHeatmapHasNoContentForAdmin(t *testing.T) {
|
||||||
|
defer prepareTestEnv(t)()
|
||||||
|
testPrivateActivityDoSomethingForActionEntries(t)
|
||||||
|
testPrivateActivityHelperEnablePrivateActivity(t)
|
||||||
|
|
||||||
|
session := loginUser(t, privateActivityTestAdmin)
|
||||||
|
hasContent := testPrivateActivityHelperHasHeatmapContentFromSession(t, session)
|
||||||
|
|
||||||
|
assert.False(t, hasContent, "user should have no heatmap content")
|
||||||
|
}
|
|
@ -194,7 +194,7 @@ func TestCantMergeWorkInProgress(t *testing.T) {
|
||||||
req := NewRequest(t, "GET", resp.Header().Get("Location"))
|
req := NewRequest(t, "GET", resp.Header().Get("Location"))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
text := strings.TrimSpace(htmlDoc.doc.Find(".attached.header > .text.grey").Last().Text())
|
text := strings.TrimSpace(htmlDoc.doc.Find(".attached.merge-section.no-header > .text.grey").Last().Text())
|
||||||
assert.NotEmpty(t, text, "Can't find WIP text")
|
assert.NotEmpty(t, text, "Can't find WIP text")
|
||||||
|
|
||||||
// remove <strong /> from lang
|
// remove <strong /> from lang
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/test"
|
"code.gitea.io/gitea/modules/test"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -106,6 +107,12 @@ func TestCreateReleaseDraft(t *testing.T) {
|
||||||
func TestCreateReleasePaging(t *testing.T) {
|
func TestCreateReleasePaging(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
defer prepareTestEnv(t)()
|
||||||
|
|
||||||
|
oldAPIDefaultNum := setting.API.DefaultPagingNum
|
||||||
|
defer func() {
|
||||||
|
setting.API.DefaultPagingNum = oldAPIDefaultNum
|
||||||
|
}()
|
||||||
|
setting.API.DefaultPagingNum = 10
|
||||||
|
|
||||||
session := loginUser(t, "user2")
|
session := loginUser(t, "user2")
|
||||||
// Create enaugh releases to have paging
|
// Create enaugh releases to have paging
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
|
|
|
@ -38,5 +38,5 @@ func testRepoMigrate(t testing.TB, session *TestSession, cloneAddr, repoName str
|
||||||
func TestRepoMigrate(t *testing.T) {
|
func TestRepoMigrate(t *testing.T) {
|
||||||
defer prepareTestEnv(t)()
|
defer prepareTestEnv(t)()
|
||||||
session := loginUser(t, "user2")
|
session := loginUser(t, "user2")
|
||||||
testRepoMigrate(t, session, "https://github.com/go-gitea/git.git", "git")
|
testRepoMigrate(t, session, "https://github.com/go-gitea/test_repo.git", "git")
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ func TestViewRepoWithSymlinks(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.Equal(t, len(items), 5)
|
assert.Equal(t, len(items), 5)
|
||||||
assert.Equal(t, items[0], "a: svg octicon-file-directory")
|
assert.Equal(t, items[0], "a: svg octicon-file-directory")
|
||||||
assert.Equal(t, items[1], "link_b: svg octicon-file-symlink-directory")
|
assert.Equal(t, items[1], "link_b: svg octicon-file-submodule")
|
||||||
assert.Equal(t, items[2], "link_d: svg octicon-file-symlink-file")
|
assert.Equal(t, items[2], "link_d: svg octicon-file-symlink-file")
|
||||||
assert.Equal(t, items[3], "link_hi: svg octicon-file-symlink-file")
|
assert.Equal(t, items[3], "link_hi: svg octicon-file-symlink-file")
|
||||||
assert.Equal(t, items[4], "link_link: svg octicon-file-symlink-file")
|
assert.Equal(t, items[4], "link_link: svg octicon-file-symlink-file")
|
||||||
|
|
|
@ -80,7 +80,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) {
|
||||||
|
|
||||||
t.Run("Delete README.md file", func(t *testing.T) {
|
t.Run("Delete README.md file", func(t *testing.T) {
|
||||||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
|
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
expectedFileResponse := getExpectedDeleteFileResponse(u)
|
expectedFileResponse := getExpectedDeleteFileResponse(u)
|
||||||
assert.NotNil(t, fileResponse)
|
assert.NotNil(t, fileResponse)
|
||||||
assert.Nil(t, fileResponse.Content)
|
assert.Nil(t, fileResponse.Content)
|
||||||
|
@ -122,7 +122,7 @@ func testDeleteRepoFileWithoutBranchNames(t *testing.T, u *url.URL) {
|
||||||
|
|
||||||
t.Run("Delete README.md without Branch Name", func(t *testing.T) {
|
t.Run("Delete README.md without Branch Name", func(t *testing.T) {
|
||||||
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
|
fileResponse, err := repofiles.DeleteRepoFile(repo, doer, opts)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
expectedFileResponse := getExpectedDeleteFileResponse(u)
|
expectedFileResponse := getExpectedDeleteFileResponse(u)
|
||||||
assert.NotNil(t, fileResponse)
|
assert.NotNil(t, fileResponse)
|
||||||
assert.Nil(t, fileResponse.Content)
|
assert.Nil(t, fileResponse.Content)
|
||||||
|
|
|
@ -201,7 +201,7 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
|
||||||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
|
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||||
|
|
||||||
// asserts
|
// asserts
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) {
|
||||||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
|
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||||
|
|
||||||
// asserts
|
// asserts
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
|
||||||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
|
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||||
|
|
||||||
// asserts
|
// asserts
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
|
||||||
t.Fatalf("expected git.ErrNotExist, got:%v", err)
|
t.Fatalf("expected git.ErrNotExist, got:%v", err)
|
||||||
}
|
}
|
||||||
toEntry, err := commit.GetTreeEntryByPath(opts.TreePath)
|
toEntry, err := commit.GetTreeEntryByPath(opts.TreePath)
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Nil(t, fromEntry) // Should no longer exist here
|
assert.Nil(t, fromEntry) // Should no longer exist here
|
||||||
assert.NotNil(t, toEntry) // Should exist here
|
assert.NotNil(t, toEntry) // Should exist here
|
||||||
// assert SHA has remained the same but paths use the new file name
|
// assert SHA has remained the same but paths use the new file name
|
||||||
|
@ -322,7 +322,7 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) {
|
||||||
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
|
fileResponse, err := repofiles.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||||
|
|
||||||
// asserts
|
// asserts
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
|
|
@ -29,13 +29,16 @@ SSH_LISTEN_HOST = localhost
|
||||||
SSH_PORT = 2203
|
SSH_PORT = 2203
|
||||||
START_SSH_SERVER = true
|
START_SSH_SERVER = true
|
||||||
LFS_START_SERVER = true
|
LFS_START_SERVER = true
|
||||||
LFS_CONTENT_PATH = data/lfs-sqlite
|
LFS_CONTENT_PATH = integrations/gitea-integration-sqlite/data
|
||||||
OFFLINE_MODE = false
|
OFFLINE_MODE = false
|
||||||
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
|
LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w
|
||||||
APP_DATA_PATH = integrations/gitea-integration-sqlite/data
|
APP_DATA_PATH = integrations/gitea-integration-sqlite/data
|
||||||
ENABLE_GZIP = true
|
ENABLE_GZIP = true
|
||||||
BUILTIN_SSH_SERVER_USER = git
|
BUILTIN_SSH_SERVER_USER = git
|
||||||
|
|
||||||
|
[attachment]
|
||||||
|
PATH = integrations/gitea-integration-sqlite/data
|
||||||
|
|
||||||
[mailer]
|
[mailer]
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
MAILER_TYPE = dummy
|
MAILER_TYPE = dummy
|
||||||
|
@ -52,11 +55,15 @@ DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||||
NO_REPLY_ADDRESS = noreply.example.org
|
NO_REPLY_ADDRESS = noreply.example.org
|
||||||
|
|
||||||
[picture]
|
[picture]
|
||||||
DISABLE_GRAVATAR = false
|
DISABLE_GRAVATAR = false
|
||||||
ENABLE_FEDERATED_AVATAR = false
|
ENABLE_FEDERATED_AVATAR = false
|
||||||
|
AVATAR_UPLOAD_PATH = integrations/gitea-integration-sqlite/data/avatars
|
||||||
|
REPOSITORY_AVATAR_UPLOAD_PATH = integrations/gitea-integration-sqlite/data/repo-avatars
|
||||||
|
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
PROVIDER = file
|
PROVIDER = file
|
||||||
|
PROVIDER_CONFIG = integrations/gitea-integration-sqlite/data/sessions
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
MODE = test,file
|
MODE = test,file
|
||||||
|
|
|
@ -13,12 +13,17 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/queue"
|
"code.gitea.io/gitea/modules/queue"
|
||||||
)
|
)
|
||||||
|
|
||||||
var prefix string
|
var (
|
||||||
|
prefix string
|
||||||
|
slowTest = 10 * time.Second
|
||||||
|
slowFlush = 5 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
// TestLogger is a logger which will write to the testing log
|
// TestLogger is a logger which will write to the testing log
|
||||||
type TestLogger struct {
|
type TestLogger struct {
|
||||||
|
@ -87,6 +92,7 @@ func (w *testLoggerWriterCloser) Close() error {
|
||||||
|
|
||||||
// PrintCurrentTest prints the current test to os.Stdout
|
// PrintCurrentTest prints the current test to os.Stdout
|
||||||
func PrintCurrentTest(t testing.TB, skip ...int) func() {
|
func PrintCurrentTest(t testing.TB, skip ...int) func() {
|
||||||
|
start := time.Now()
|
||||||
actualSkip := 1
|
actualSkip := 1
|
||||||
if len(skip) > 0 {
|
if len(skip) > 0 {
|
||||||
actualSkip = skip[0]
|
actualSkip = skip[0]
|
||||||
|
@ -100,9 +106,33 @@ func PrintCurrentTest(t testing.TB, skip ...int) func() {
|
||||||
}
|
}
|
||||||
writerCloser.setT(&t)
|
writerCloser.setT(&t)
|
||||||
return func() {
|
return func() {
|
||||||
|
took := time.Since(start)
|
||||||
|
if took > slowTest {
|
||||||
|
if log.CanColorStdout {
|
||||||
|
fmt.Fprintf(os.Stdout, "+++ %s is a slow test (took %v)\n", fmt.Formatter(log.NewColoredValue(t.Name(), log.Bold, log.FgYellow)), fmt.Formatter(log.NewColoredValue(took, log.Bold, log.FgYellow)))
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stdout, "+++ %s is a slow tets (took %v)\n", t.Name(), took)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timer := time.AfterFunc(slowFlush, func() {
|
||||||
|
if log.CanColorStdout {
|
||||||
|
fmt.Fprintf(os.Stdout, "+++ %s ... still flushing after %v ...\n", fmt.Formatter(log.NewColoredValue(t.Name(), log.Bold, log.FgRed)), slowFlush)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stdout, "+++ %s ... still flushing after %v ...\n", t.Name(), slowFlush)
|
||||||
|
}
|
||||||
|
})
|
||||||
if err := queue.GetManager().FlushAll(context.Background(), -1); err != nil {
|
if err := queue.GetManager().FlushAll(context.Background(), -1); err != nil {
|
||||||
t.Errorf("Flushing queues failed with error %v", err)
|
t.Errorf("Flushing queues failed with error %v", err)
|
||||||
}
|
}
|
||||||
|
timer.Stop()
|
||||||
|
flushTook := time.Since(start) - took
|
||||||
|
if flushTook > slowFlush {
|
||||||
|
if log.CanColorStdout {
|
||||||
|
fmt.Fprintf(os.Stdout, "+++ %s had a slow clean-up flush (took %v)\n", fmt.Formatter(log.NewColoredValue(t.Name(), log.Bold, log.FgRed)), fmt.Formatter(log.NewColoredValue(flushTook, log.Bold, log.FgRed)))
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stdout, "+++ %s had a slow clean-up flush (took %v)\n", t.Name(), flushTook)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ = writerCloser.Close()
|
_ = writerCloser.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,6 +170,11 @@ func (log *TestLogger) Init(config string) error {
|
||||||
func (log *TestLogger) Flush() {
|
func (log *TestLogger) Flush() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ReleaseReopen does nothing
|
||||||
|
func (log *TestLogger) ReleaseReopen() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetName returns the default name for this implementation
|
// GetName returns the default name for this implementation
|
||||||
func (log *TestLogger) GetName() string {
|
func (log *TestLogger) GetName() string {
|
||||||
return "test"
|
return "test"
|
||||||
|
|
|
@ -49,6 +49,7 @@ const (
|
||||||
ActionApprovePullRequest // 21
|
ActionApprovePullRequest // 21
|
||||||
ActionRejectPullRequest // 22
|
ActionRejectPullRequest // 22
|
||||||
ActionCommentPull // 23
|
ActionCommentPull // 23
|
||||||
|
ActionPublishRelease // 24
|
||||||
)
|
)
|
||||||
|
|
||||||
// Action represents user operation type and other information to
|
// Action represents user operation type and other information to
|
||||||
|
@ -319,6 +320,12 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
|
||||||
cond = cond.And(builder.In("repo_id", AccessibleRepoIDsQuery(opts.Actor)))
|
cond = cond.And(builder.In("repo_id", AccessibleRepoIDsQuery(opts.Actor)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.Actor == nil || !opts.Actor.IsAdmin {
|
||||||
|
if opts.RequestedUser.KeepActivityPrivate && actorID != opts.RequestedUser.ID {
|
||||||
|
return make([]*Action, 0), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cond = cond.And(builder.Eq{"user_id": opts.RequestedUser.ID})
|
cond = cond.And(builder.Eq{"user_id": opts.RequestedUser.ID})
|
||||||
|
|
||||||
if opts.OnlyPerformedBy {
|
if opts.OnlyPerformedBy {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
gouuid "github.com/satori/go.uuid"
|
gouuid "github.com/google/uuid"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ func (a *Attachment) LinkedRepository() (*Repository, UnitType, error) {
|
||||||
|
|
||||||
// NewAttachment creates a new attachment object.
|
// NewAttachment creates a new attachment object.
|
||||||
func NewAttachment(attach *Attachment, buf []byte, file io.Reader) (_ *Attachment, err error) {
|
func NewAttachment(attach *Attachment, buf []byte, file io.Reader) (_ *Attachment, err error) {
|
||||||
attach.UUID = gouuid.NewV4().String()
|
attach.UUID = gouuid.New().String()
|
||||||
|
|
||||||
localPath := attach.LocalPath()
|
localPath := attach.LocalPath()
|
||||||
if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
|
if err = os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil {
|
||||||
|
@ -136,9 +136,8 @@ func GetAttachmentByID(id int64) (*Attachment, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAttachmentByID(e Engine, id int64) (*Attachment, error) {
|
func getAttachmentByID(e Engine, id int64) (*Attachment, error) {
|
||||||
attach := &Attachment{ID: id}
|
attach := &Attachment{}
|
||||||
|
if has, err := e.ID(id).Get(attach); err != nil {
|
||||||
if has, err := e.Get(attach); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
return nil, ErrAttachmentNotExist{ID: id, UUID: ""}
|
return nil, ErrAttachmentNotExist{ID: id, UUID: ""}
|
||||||
|
@ -147,8 +146,8 @@ func getAttachmentByID(e Engine, id int64) (*Attachment, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAttachmentByUUID(e Engine, uuid string) (*Attachment, error) {
|
func getAttachmentByUUID(e Engine, uuid string) (*Attachment, error) {
|
||||||
attach := &Attachment{UUID: uuid}
|
attach := &Attachment{}
|
||||||
has, err := e.Get(attach)
|
has, err := e.Where("uuid=?", uuid).Get(attach)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
|
|
@ -240,8 +240,8 @@ func getProtectedBranchBy(e Engine, repoID int64, branchName string) (*Protected
|
||||||
|
|
||||||
// GetProtectedBranchByID getting protected branch by ID
|
// GetProtectedBranchByID getting protected branch by ID
|
||||||
func GetProtectedBranchByID(id int64) (*ProtectedBranch, error) {
|
func GetProtectedBranchByID(id int64) (*ProtectedBranch, error) {
|
||||||
rel := &ProtectedBranch{ID: id}
|
rel := &ProtectedBranch{}
|
||||||
has, err := x.Get(rel)
|
has, err := x.ID(id).Get(rel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -509,9 +509,9 @@ func (repo *Repository) GetDeletedBranches() ([]*DeletedBranch, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDeletedBranchByID get a deleted branch by its ID
|
// GetDeletedBranchByID get a deleted branch by its ID
|
||||||
func (repo *Repository) GetDeletedBranchByID(ID int64) (*DeletedBranch, error) {
|
func (repo *Repository) GetDeletedBranchByID(id int64) (*DeletedBranch, error) {
|
||||||
deletedBranch := &DeletedBranch{ID: ID}
|
deletedBranch := &DeletedBranch{}
|
||||||
has, err := x.Get(deletedBranch)
|
has, err := x.ID(id).Get(deletedBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
// consistencyCheckable a type that can be tested for database consistency
|
// consistencyCheckable a type that can be tested for database consistency
|
||||||
|
@ -167,3 +168,130 @@ func (action *Action) checkForConsistency(t *testing.T) {
|
||||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: action.RepoID}).(*Repository)
|
repo := AssertExistsAndLoadBean(t, &Repository{ID: action.RepoID}).(*Repository)
|
||||||
assert.Equal(t, repo.IsPrivate, action.IsPrivate, "action: %+v", action)
|
assert.Equal(t, repo.IsPrivate, action.IsPrivate, "action: %+v", action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountOrphanedLabels return count of labels witch are broken and not accessible via ui anymore
|
||||||
|
func CountOrphanedLabels() (int64, error) {
|
||||||
|
noref, err := x.Table("label").Where("repo_id=? AND org_id=?", 0, 0).Count("label.id")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
norepo, err := x.Table("label").
|
||||||
|
Join("LEFT", "repository", "label.repo_id=repository.id").
|
||||||
|
Where(builder.IsNull{"repository.id"}).And(builder.Gt{"label.repo_id": 0}).
|
||||||
|
Count("id")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
noorg, err := x.Table("label").
|
||||||
|
Join("LEFT", "`user`", "label.org_id=`user`.id").
|
||||||
|
Where(builder.IsNull{"`user`.id"}).And(builder.Gt{"label.org_id": 0}).
|
||||||
|
Count("id")
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return noref + norepo + noorg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOrphanedLabels delete labels witch are broken and not accessible via ui anymore
|
||||||
|
func DeleteOrphanedLabels() error {
|
||||||
|
// delete labels with no reference
|
||||||
|
if _, err := x.Table("label").Where("repo_id=? AND org_id=?", 0, 0).Delete(new(Label)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete labels with none existing repos
|
||||||
|
if _, err := x.In("id", builder.Select("label.id").From("label").
|
||||||
|
Join("LEFT", "repository", "label.repo_id=repository.id").
|
||||||
|
Where(builder.IsNull{"repository.id"}).And(builder.Gt{"label.repo_id": 0})).
|
||||||
|
Delete(Label{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete labels with none existing orgs
|
||||||
|
if _, err := x.In("id", builder.Select("label.id").From("label").
|
||||||
|
Join("LEFT", "`user`", "label.org_id=`user`.id").
|
||||||
|
Where(builder.IsNull{"`user`.id"}).And(builder.Gt{"label.org_id": 0})).
|
||||||
|
Delete(Label{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountOrphanedIssues count issues without a repo
|
||||||
|
func CountOrphanedIssues() (int64, error) {
|
||||||
|
return x.Table("issue").
|
||||||
|
Join("LEFT", "repository", "issue.repo_id=repository.id").
|
||||||
|
Where(builder.IsNull{"repository.id"}).
|
||||||
|
Count("id")
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOrphanedIssues delete issues without a repo
|
||||||
|
func DeleteOrphanedIssues() error {
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ids []int64
|
||||||
|
|
||||||
|
if err := sess.Table("issue").Distinct("issue.repo_id").
|
||||||
|
Join("LEFT", "repository", "issue.repo_id=repository.id").
|
||||||
|
Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id").
|
||||||
|
Find(&ids); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var attachmentPaths []string
|
||||||
|
for i := range ids {
|
||||||
|
paths, err := deleteIssuesByRepoID(sess, ids[i])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
attachmentPaths = append(attachmentPaths, paths...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := sess.Commit(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove issue attachment files.
|
||||||
|
for i := range attachmentPaths {
|
||||||
|
removeAllWithNotice(x, "Delete issue attachment", attachmentPaths[i])
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountOrphanedObjects count subjects with have no existing refobject anymore
|
||||||
|
func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) {
|
||||||
|
return x.Table("`"+subject+"`").
|
||||||
|
Join("LEFT", refobject, joinCond).
|
||||||
|
Where(builder.IsNull{"`" + refobject + "`.id"}).
|
||||||
|
Count("id")
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOrphanedObjects delete subjects with have no existing refobject anymore
|
||||||
|
func DeleteOrphanedObjects(subject, refobject, joinCond string) error {
|
||||||
|
_, err := x.In("id", builder.Select("`"+subject+"`.id").
|
||||||
|
From("`"+subject+"`").
|
||||||
|
Join("LEFT", "`"+refobject+"`", joinCond).
|
||||||
|
Where(builder.IsNull{"`" + refobject + "`.id"})).
|
||||||
|
Delete("`" + subject + "`")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountNullArchivedRepository counts the number of repositories with is_archived is null
|
||||||
|
func CountNullArchivedRepository() (int64, error) {
|
||||||
|
return x.Where(builder.IsNull{"is_archived"}).Count(new(Repository))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FixNullArchivedRepository sets is_archived to false where it is null
|
||||||
|
func FixNullArchivedRepository() (int64, error) {
|
||||||
|
return x.Where(builder.IsNull{"is_archived"}).Cols("is_archived").Update(&Repository{
|
||||||
|
IsArchived: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ func DefaultDBContext() DBContext {
|
||||||
// Committer represents an interface to Commit or Close the dbcontext
|
// Committer represents an interface to Commit or Close the dbcontext
|
||||||
type Committer interface {
|
type Committer interface {
|
||||||
Commit() error
|
Commit() error
|
||||||
Close()
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// TxDBContext represents a transaction DBContext
|
// TxDBContext represents a transaction DBContext
|
||||||
|
|
|
@ -995,6 +995,21 @@ func IsErrWontSign(err error) bool {
|
||||||
// |______ / |__| (____ /___| /\___ >___| /
|
// |______ / |__| (____ /___| /\___ >___| /
|
||||||
// \/ \/ \/ \/ \/
|
// \/ \/ \/ \/ \/
|
||||||
|
|
||||||
|
// ErrBranchDoesNotExist represents an error that branch with such name does not exist.
|
||||||
|
type ErrBranchDoesNotExist struct {
|
||||||
|
BranchName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrBranchDoesNotExist checks if an error is an ErrBranchDoesNotExist.
|
||||||
|
func IsErrBranchDoesNotExist(err error) bool {
|
||||||
|
_, ok := err.(ErrBranchDoesNotExist)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrBranchDoesNotExist) Error() string {
|
||||||
|
return fmt.Sprintf("branch does not exist [name: %s]", err.BranchName)
|
||||||
|
}
|
||||||
|
|
||||||
// ErrBranchAlreadyExists represents an error that branch with such name already exists.
|
// ErrBranchAlreadyExists represents an error that branch with such name already exists.
|
||||||
type ErrBranchAlreadyExists struct {
|
type ErrBranchAlreadyExists struct {
|
||||||
BranchName string
|
BranchName string
|
||||||
|
|
|
@ -273,7 +273,7 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity) (*GPGKey, error) {
|
||||||
for i, k := range e.Subkeys {
|
for i, k := range e.Subkeys {
|
||||||
subs, err := parseSubGPGKey(ownerID, pubkey.KeyIdString(), k.PublicKey, expiry)
|
subs, err := parseSubGPGKey(ownerID, pubkey.KeyIdString(), k.PublicKey, expiry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, ErrGPGKeyParsing{ParseError: err}
|
||||||
}
|
}
|
||||||
subkeys[i] = subs
|
subkeys[i] = subs
|
||||||
}
|
}
|
||||||
|
@ -509,6 +509,18 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
|
var primaryKeys []*GPGKey
|
||||||
|
if key.PrimaryKeyID != "" {
|
||||||
|
primaryKeys, err = GetGPGKeysByKeyID(key.PrimaryKeyID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("GetGPGKeysByKeyID: %v", err)
|
||||||
|
return &CommitVerification{
|
||||||
|
CommittingUser: committer,
|
||||||
|
Verified: false,
|
||||||
|
Reason: "gpg.error.failed_retrieval_gpg_keys",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
activated := false
|
activated := false
|
||||||
if len(email) != 0 {
|
if len(email) != 0 {
|
||||||
for _, e := range key.Emails {
|
for _, e := range key.Emails {
|
||||||
|
@ -518,6 +530,20 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !activated {
|
||||||
|
for _, pkey := range primaryKeys {
|
||||||
|
for _, e := range pkey.Emails {
|
||||||
|
if e.IsActivated && strings.EqualFold(e.Email, email) {
|
||||||
|
activated = true
|
||||||
|
email = e.Email
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if activated {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, e := range key.Emails {
|
for _, e := range key.Emails {
|
||||||
if e.IsActivated {
|
if e.IsActivated {
|
||||||
|
@ -526,7 +552,22 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !activated {
|
||||||
|
for _, pkey := range primaryKeys {
|
||||||
|
for _, e := range pkey.Emails {
|
||||||
|
if e.IsActivated {
|
||||||
|
activated = true
|
||||||
|
email = e.Email
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if activated {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !activated {
|
if !activated {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -614,7 +655,6 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
|
||||||
if keyID == "" && sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) > 0 {
|
if keyID == "" && sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) > 0 {
|
||||||
keyID = fmt.Sprintf("%X", sig.IssuerFingerprint[12:20])
|
keyID = fmt.Sprintf("%X", sig.IssuerFingerprint[12:20])
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultReason := NoKeyFound
|
defaultReason := NoKeyFound
|
||||||
|
|
||||||
// First check if the sig has a keyID and if so just look at that
|
// First check if the sig has a keyID and if so just look at that
|
||||||
|
@ -741,6 +781,21 @@ func verifyWithGPGSettings(gpgSettings *git.GPGSettings, sig *packet.Signature,
|
||||||
CanSign: pubkey.CanSign(),
|
CanSign: pubkey.CanSign(),
|
||||||
KeyID: pubkey.KeyIdString(),
|
KeyID: pubkey.KeyIdString(),
|
||||||
}
|
}
|
||||||
|
for _, subKey := range ekey.Subkeys {
|
||||||
|
content, err := base64EncPubKey(subKey.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return &CommitVerification{
|
||||||
|
CommittingUser: committer,
|
||||||
|
Verified: false,
|
||||||
|
Reason: "gpg.error.generate_hash",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k.SubsKey = append(k.SubsKey, &GPGKey{
|
||||||
|
Content: content,
|
||||||
|
CanSign: subKey.PublicKey.CanSign(),
|
||||||
|
KeyID: subKey.PublicKey.KeyIdString(),
|
||||||
|
})
|
||||||
|
}
|
||||||
if commitVerification := hashAndVerifyWithSubKeys(sig, payload, k, committer, &User{
|
if commitVerification := hashAndVerifyWithSubKeys(sig, payload, k, committer, &User{
|
||||||
Name: gpgSettings.Name,
|
Name: gpgSettings.Name,
|
||||||
Email: gpgSettings.Email,
|
Email: gpgSettings.Email,
|
||||||
|
|
|
@ -76,7 +76,6 @@ var (
|
||||||
const issueTasksRegexpStr = `(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`
|
const issueTasksRegexpStr = `(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`
|
||||||
const issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`
|
const issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`
|
||||||
const issueMaxDupIndexAttempts = 3
|
const issueMaxDupIndexAttempts = 3
|
||||||
const maxIssueIDs = 950
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
|
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
|
||||||
|
@ -249,7 +248,7 @@ func (issue *Issue) loadReactions(e Engine) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (issue *Issue) loadMilestone(e Engine) (err error) {
|
func (issue *Issue) loadMilestone(e Engine) (err error) {
|
||||||
if issue.Milestone == nil && issue.MilestoneID > 0 {
|
if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 {
|
||||||
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
|
issue.Milestone, err = getMilestoneByRepoID(e, issue.RepoID, issue.MilestoneID)
|
||||||
if err != nil && !IsErrMilestoneNotExist(err) {
|
if err != nil && !IsErrMilestoneNotExist(err) {
|
||||||
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
|
return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err)
|
||||||
|
@ -1114,9 +1113,6 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opts.IssueIDs) > 0 {
|
if len(opts.IssueIDs) > 0 {
|
||||||
if len(opts.IssueIDs) > maxIssueIDs {
|
|
||||||
opts.IssueIDs = opts.IssueIDs[:maxIssueIDs]
|
|
||||||
}
|
|
||||||
sess.In("issue.id", opts.IssueIDs)
|
sess.In("issue.id", opts.IssueIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1360,9 +1356,6 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
|
||||||
Where("issue.repo_id = ?", opts.RepoID)
|
Where("issue.repo_id = ?", opts.RepoID)
|
||||||
|
|
||||||
if len(opts.IssueIDs) > 0 {
|
if len(opts.IssueIDs) > 0 {
|
||||||
if len(opts.IssueIDs) > maxIssueIDs {
|
|
||||||
opts.IssueIDs = opts.IssueIDs[:maxIssueIDs]
|
|
||||||
}
|
|
||||||
sess.In("issue.id", opts.IssueIDs)
|
sess.In("issue.id", opts.IssueIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1446,9 +1439,6 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
|
||||||
cond = cond.And(builder.In("issue.repo_id", opts.RepoIDs))
|
cond = cond.And(builder.In("issue.repo_id", opts.RepoIDs))
|
||||||
}
|
}
|
||||||
if len(opts.IssueIDs) > 0 {
|
if len(opts.IssueIDs) > 0 {
|
||||||
if len(opts.IssueIDs) > maxIssueIDs {
|
|
||||||
opts.IssueIDs = opts.IssueIDs[:maxIssueIDs]
|
|
||||||
}
|
|
||||||
cond = cond.And(builder.In("issue.id", opts.IssueIDs))
|
cond = cond.And(builder.In("issue.id", opts.IssueIDs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1916,3 +1906,70 @@ func UpdateReactionsMigrationsByType(gitServiceType structs.GitServiceType, orig
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteIssuesByRepoID(sess Engine, repoID int64) (attachmentPaths []string, err error) {
|
||||||
|
deleteCond := builder.Select("id").From("issue").Where(builder.Eq{"issue.repo_id": repoID})
|
||||||
|
|
||||||
|
// Delete comments and attachments
|
||||||
|
if _, err = sess.In("issue_id", deleteCond).
|
||||||
|
Delete(&Comment{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dependencies for issues in this repository
|
||||||
|
if _, err = sess.In("issue_id", deleteCond).
|
||||||
|
Delete(&IssueDependency{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete dependencies for issues in other repositories
|
||||||
|
if _, err = sess.In("dependency_id", deleteCond).
|
||||||
|
Delete(&IssueDependency{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.In("issue_id", deleteCond).
|
||||||
|
Delete(&IssueUser{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.In("issue_id", deleteCond).
|
||||||
|
Delete(&Reaction{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.In("issue_id", deleteCond).
|
||||||
|
Delete(&IssueWatch{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.In("issue_id", deleteCond).
|
||||||
|
Delete(&Stopwatch{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.In("issue_id", deleteCond).
|
||||||
|
Delete(&TrackedTime{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var attachments []*Attachment
|
||||||
|
if err = sess.In("issue_id", deleteCond).
|
||||||
|
Find(&attachments); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for j := range attachments {
|
||||||
|
attachmentPaths = append(attachmentPaths, attachments[j].LocalPath())
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.In("issue_id", deleteCond).
|
||||||
|
Delete(&Attachment{}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = sess.Delete(&Issue{RepoID: repoID}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -7,8 +7,13 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"container/list"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
@ -90,6 +95,8 @@ const (
|
||||||
CommentTypeReviewRequest
|
CommentTypeReviewRequest
|
||||||
// merge pull request
|
// merge pull request
|
||||||
CommentTypeMergePull
|
CommentTypeMergePull
|
||||||
|
// push to PR head branch
|
||||||
|
CommentTypePullPush
|
||||||
)
|
)
|
||||||
|
|
||||||
// CommentTag defines comment tag type
|
// CommentTag defines comment tag type
|
||||||
|
@ -138,7 +145,8 @@ type Comment struct {
|
||||||
RenderedContent string `xorm:"-"`
|
RenderedContent string `xorm:"-"`
|
||||||
|
|
||||||
// Path represents the 4 lines of code cemented by this comment
|
// Path represents the 4 lines of code cemented by this comment
|
||||||
Patch string `xorm:"TEXT"`
|
Patch string `xorm:"-"`
|
||||||
|
PatchQuoted string `xorm:"TEXT patch"`
|
||||||
|
|
||||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||||
|
@ -167,6 +175,18 @@ type Comment struct {
|
||||||
RefRepo *Repository `xorm:"-"`
|
RefRepo *Repository `xorm:"-"`
|
||||||
RefIssue *Issue `xorm:"-"`
|
RefIssue *Issue `xorm:"-"`
|
||||||
RefComment *Comment `xorm:"-"`
|
RefComment *Comment `xorm:"-"`
|
||||||
|
|
||||||
|
Commits *list.List `xorm:"-"`
|
||||||
|
OldCommit string `xorm:"-"`
|
||||||
|
NewCommit string `xorm:"-"`
|
||||||
|
CommitsNum int64 `xorm:"-"`
|
||||||
|
IsForcePush bool `xorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushActionContent is content of push pull comment
|
||||||
|
type PushActionContent struct {
|
||||||
|
IsForcePush bool `json:"is_force_push"`
|
||||||
|
CommitIDs []string `json:"commit_ids"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadIssue loads issue from database
|
// LoadIssue loads issue from database
|
||||||
|
@ -182,6 +202,33 @@ func (c *Comment) loadIssue(e Engine) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BeforeInsert will be invoked by XORM before inserting a record
|
||||||
|
func (c *Comment) BeforeInsert() {
|
||||||
|
c.PatchQuoted = c.Patch
|
||||||
|
if !utf8.ValidString(c.Patch) {
|
||||||
|
c.PatchQuoted = strconv.Quote(c.Patch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeforeUpdate will be invoked by XORM before updating a record
|
||||||
|
func (c *Comment) BeforeUpdate() {
|
||||||
|
c.PatchQuoted = c.Patch
|
||||||
|
if !utf8.ValidString(c.Patch) {
|
||||||
|
c.PatchQuoted = strconv.Quote(c.Patch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
|
||||||
|
func (c *Comment) AfterLoad(session *xorm.Session) {
|
||||||
|
c.Patch = c.PatchQuoted
|
||||||
|
if len(c.PatchQuoted) > 0 && c.PatchQuoted[0] == '"' {
|
||||||
|
unquoted, err := strconv.Unquote(c.PatchQuoted)
|
||||||
|
if err == nil {
|
||||||
|
c.Patch = unquoted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Comment) loadPoster(e Engine) (err error) {
|
func (c *Comment) loadPoster(e Engine) (err error) {
|
||||||
if c.PosterID <= 0 || c.Poster != nil {
|
if c.PosterID <= 0 || c.Poster != nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -489,10 +536,12 @@ func (c *Comment) LoadReview() error {
|
||||||
return c.loadReview(x)
|
return c.loadReview(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var notEnoughLines = regexp.MustCompile(`fatal: file .* has only \d+ lines?`)
|
||||||
|
|
||||||
func (c *Comment) checkInvalidation(doer *User, repo *git.Repository, branch string) error {
|
func (c *Comment) checkInvalidation(doer *User, repo *git.Repository, branch string) error {
|
||||||
// FIXME differentiate between previous and proposed line
|
// FIXME differentiate between previous and proposed line
|
||||||
commit, err := repo.LineBlame(branch, repo.Path, c.TreePath, uint(c.UnsignedLine()))
|
commit, err := repo.LineBlame(branch, repo.Path, c.TreePath, uint(c.UnsignedLine()))
|
||||||
if err != nil && strings.Contains(err.Error(), "fatal: no such path") {
|
if err != nil && (strings.Contains(err.Error(), "fatal: no such path") || notEnoughLines.MatchString(err.Error())) {
|
||||||
c.Invalidated = true
|
c.Invalidated = true
|
||||||
return UpdateComment(c, doer)
|
return UpdateComment(c, doer)
|
||||||
}
|
}
|
||||||
|
@ -543,6 +592,47 @@ func (c *Comment) CodeCommentURL() string {
|
||||||
return fmt.Sprintf("%s/files#%s", c.Issue.HTMLURL(), c.HashTag())
|
return fmt.Sprintf("%s/files#%s", c.Issue.HTMLURL(), c.HashTag())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadPushCommits Load push commits
|
||||||
|
func (c *Comment) LoadPushCommits() (err error) {
|
||||||
|
if c.Content == "" || c.Commits != nil || c.Type != CommentTypePullPush {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var data PushActionContent
|
||||||
|
|
||||||
|
err = json.Unmarshal([]byte(c.Content), &data)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.IsForcePush = data.IsForcePush
|
||||||
|
|
||||||
|
if c.IsForcePush {
|
||||||
|
if len(data.CommitIDs) != 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.OldCommit = data.CommitIDs[0]
|
||||||
|
c.NewCommit = data.CommitIDs[1]
|
||||||
|
} else {
|
||||||
|
repoPath := c.Issue.Repo.RepoPath()
|
||||||
|
gitRepo, err := git.OpenRepository(repoPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
c.Commits = gitRepo.GetCommitsFromIDs(data.CommitIDs)
|
||||||
|
c.CommitsNum = int64(c.Commits.Len())
|
||||||
|
if c.CommitsNum > 0 {
|
||||||
|
c.Commits = ValidateCommitsWithEmails(c.Commits)
|
||||||
|
c.Commits = ParseCommitsWithSignature(c.Commits, c.Issue.Repo)
|
||||||
|
c.Commits = ParseCommitsWithStatus(c.Commits, c.Issue.Repo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
|
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
|
||||||
var LabelID int64
|
var LabelID int64
|
||||||
if opts.Label != nil {
|
if opts.Label != nil {
|
||||||
|
@ -576,6 +666,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
|
||||||
RefCommentID: opts.RefCommentID,
|
RefCommentID: opts.RefCommentID,
|
||||||
RefAction: opts.RefAction,
|
RefAction: opts.RefAction,
|
||||||
RefIsPull: opts.RefIsPull,
|
RefIsPull: opts.RefIsPull,
|
||||||
|
IsForcePush: opts.IsForcePush,
|
||||||
}
|
}
|
||||||
if _, err = e.Insert(comment); err != nil {
|
if _, err = e.Insert(comment); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -738,6 +829,7 @@ type CreateCommentOptions struct {
|
||||||
RefCommentID int64
|
RefCommentID int64
|
||||||
RefAction references.XRefAction
|
RefAction references.XRefAction
|
||||||
RefIsPull bool
|
RefIsPull bool
|
||||||
|
IsForcePush bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateComment creates comment of issue or commit.
|
// CreateComment creates comment of issue or commit.
|
||||||
|
@ -1016,3 +1108,168 @@ func UpdateCommentsMigrationsByType(tp structs.GitServiceType, originalAuthorID
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreatePushPullComment create push code to pull base commend
|
||||||
|
func CreatePushPullComment(pusher *User, pr *PullRequest, oldCommitID, newCommitID string) (comment *Comment, err error) {
|
||||||
|
if pr.HasMerged || oldCommitID == "" || newCommitID == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ops := &CreateCommentOptions{
|
||||||
|
Type: CommentTypePullPush,
|
||||||
|
Doer: pusher,
|
||||||
|
Repo: pr.BaseRepo,
|
||||||
|
}
|
||||||
|
|
||||||
|
var data PushActionContent
|
||||||
|
|
||||||
|
data.CommitIDs, data.IsForcePush, err = getCommitIDsFromRepo(pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ops.Issue = pr.Issue
|
||||||
|
dataJSON, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ops.Content = string(dataJSON)
|
||||||
|
|
||||||
|
comment, err = CreateComment(ops)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// getCommitsFromRepo get commit IDs from repo in betwern oldCommitID and newCommitID
|
||||||
|
// isForcePush will be true if oldCommit isn't on the branch
|
||||||
|
// Commit on baseBranch will skip
|
||||||
|
func getCommitIDsFromRepo(repo *Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
|
||||||
|
repoPath := repo.RepoPath()
|
||||||
|
gitRepo, err := git.OpenRepository(repoPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
oldCommit, err := gitRepo.GetCommit(oldCommitID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = oldCommit.LoadBranchName(); err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(oldCommit.Branch) == 0 {
|
||||||
|
commitIDs = make([]string, 2)
|
||||||
|
commitIDs[0] = oldCommitID
|
||||||
|
commitIDs[1] = newCommitID
|
||||||
|
|
||||||
|
return commitIDs, true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newCommit, err := gitRepo.GetCommit(newCommitID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
commits *list.List
|
||||||
|
commitChecks map[string]commitBranchCheckItem
|
||||||
|
)
|
||||||
|
commits, err = newCommit.CommitsBeforeUntil(oldCommitID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
commitIDs = make([]string, 0, commits.Len())
|
||||||
|
commitChecks = make(map[string]commitBranchCheckItem)
|
||||||
|
|
||||||
|
for e := commits.Front(); e != nil; e = e.Next() {
|
||||||
|
commitChecks[e.Value.(*git.Commit).ID.String()] = commitBranchCheckItem{
|
||||||
|
Commit: e.Value.(*git.Commit),
|
||||||
|
Checked: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = commitBranchCheck(gitRepo, newCommit, oldCommitID, baseBranch, commitChecks); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for e := commits.Back(); e != nil; e = e.Prev() {
|
||||||
|
commitID := e.Value.(*git.Commit).ID.String()
|
||||||
|
if item, ok := commitChecks[commitID]; ok && item.Checked {
|
||||||
|
commitIDs = append(commitIDs, commitID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type commitBranchCheckItem struct {
|
||||||
|
Commit *git.Commit
|
||||||
|
Checked bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func commitBranchCheck(gitRepo *git.Repository, startCommit *git.Commit, endCommitID, baseBranch string, commitList map[string]commitBranchCheckItem) (err error) {
|
||||||
|
var (
|
||||||
|
item commitBranchCheckItem
|
||||||
|
ok bool
|
||||||
|
listItem *list.Element
|
||||||
|
tmp string
|
||||||
|
)
|
||||||
|
|
||||||
|
if startCommit.ID.String() == endCommitID {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
checkStack := list.New()
|
||||||
|
checkStack.PushBack(startCommit.ID.String())
|
||||||
|
listItem = checkStack.Back()
|
||||||
|
|
||||||
|
for listItem != nil {
|
||||||
|
tmp = listItem.Value.(string)
|
||||||
|
checkStack.Remove(listItem)
|
||||||
|
|
||||||
|
if item, ok = commitList[tmp]; !ok {
|
||||||
|
listItem = checkStack.Back()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Commit.ID.String() == endCommitID {
|
||||||
|
listItem = checkStack.Back()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = item.Commit.LoadBranchName(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Commit.Branch == baseBranch {
|
||||||
|
listItem = checkStack.Back()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Checked {
|
||||||
|
listItem = checkStack.Back()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Checked = true
|
||||||
|
commitList[tmp] = item
|
||||||
|
|
||||||
|
parentNum := item.Commit.ParentCount()
|
||||||
|
for i := 0; i < parentNum; i++ {
|
||||||
|
var parentCommit *git.Commit
|
||||||
|
parentCommit, err = item.Commit.Parent(i)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
checkStack.PushBack(parentCommit.ID.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
listItem = checkStack.Back()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -295,10 +295,8 @@ func getLabelByID(e Engine, labelID int64) (*Label, error) {
|
||||||
return nil, ErrLabelNotExist{labelID}
|
return nil, ErrLabelNotExist{labelID}
|
||||||
}
|
}
|
||||||
|
|
||||||
l := &Label{
|
l := &Label{}
|
||||||
ID: labelID,
|
has, err := e.ID(labelID).Get(l)
|
||||||
}
|
|
||||||
has, err := e.Get(l)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
|
|
@ -330,41 +330,38 @@ func (milestones MilestoneList) getMilestoneIDs() []int64 {
|
||||||
return ids
|
return ids
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMilestonesByRepoID returns all opened milestones of a repository.
|
// GetMilestonesOption contain options to get milestones
|
||||||
func GetMilestonesByRepoID(repoID int64, state api.StateType, listOptions ListOptions) (MilestoneList, error) {
|
type GetMilestonesOption struct {
|
||||||
sess := x.Where("repo_id = ?", repoID)
|
ListOptions
|
||||||
|
RepoID int64
|
||||||
|
State api.StateType
|
||||||
|
Name string
|
||||||
|
SortType string
|
||||||
|
}
|
||||||
|
|
||||||
switch state {
|
// GetMilestones returns milestones filtered by GetMilestonesOption's
|
||||||
|
func GetMilestones(opts GetMilestonesOption) (MilestoneList, error) {
|
||||||
|
sess := x.Where("repo_id = ?", opts.RepoID)
|
||||||
|
|
||||||
|
switch opts.State {
|
||||||
case api.StateClosed:
|
case api.StateClosed:
|
||||||
sess = sess.And("is_closed = ?", true)
|
sess = sess.And("is_closed = ?", true)
|
||||||
|
|
||||||
case api.StateAll:
|
case api.StateAll:
|
||||||
break
|
break
|
||||||
|
// api.StateOpen:
|
||||||
case api.StateOpen:
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sess = sess.And("is_closed = ?", false)
|
sess = sess.And("is_closed = ?", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if listOptions.Page != 0 {
|
if len(opts.Name) != 0 {
|
||||||
sess = listOptions.setSessionPagination(sess)
|
sess = sess.And(builder.Like{"name", opts.Name})
|
||||||
}
|
}
|
||||||
|
|
||||||
miles := make([]*Milestone, 0, listOptions.PageSize)
|
if opts.Page != 0 {
|
||||||
return miles, sess.Asc("deadline_unix").Asc("id").Find(&miles)
|
sess = opts.setSessionPagination(sess)
|
||||||
}
|
|
||||||
|
|
||||||
// GetMilestones returns a list of milestones of given repository and status.
|
|
||||||
func GetMilestones(repoID int64, page int, isClosed bool, sortType string) (MilestoneList, error) {
|
|
||||||
miles := make([]*Milestone, 0, setting.UI.IssuePagingNum)
|
|
||||||
sess := x.Where("repo_id = ? AND is_closed = ?", repoID, isClosed)
|
|
||||||
if page > 0 {
|
|
||||||
sess = sess.Limit(setting.UI.IssuePagingNum, (page-1)*setting.UI.IssuePagingNum)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch sortType {
|
switch opts.SortType {
|
||||||
case "furthestduedate":
|
case "furthestduedate":
|
||||||
sess.Desc("deadline_unix")
|
sess.Desc("deadline_unix")
|
||||||
case "leastcomplete":
|
case "leastcomplete":
|
||||||
|
@ -375,9 +372,13 @@ func GetMilestones(repoID int64, page int, isClosed bool, sortType string) (Mile
|
||||||
sess.Asc("num_issues")
|
sess.Asc("num_issues")
|
||||||
case "mostissues":
|
case "mostissues":
|
||||||
sess.Desc("num_issues")
|
sess.Desc("num_issues")
|
||||||
|
case "id":
|
||||||
|
sess.Asc("id")
|
||||||
default:
|
default:
|
||||||
sess.Asc("deadline_unix")
|
sess.Asc("deadline_unix").Asc("id")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
miles := make([]*Milestone, 0, opts.PageSize)
|
||||||
return miles, sess.Find(&miles)
|
return miles, sess.Find(&miles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
|
||||||
|
@ -49,7 +50,10 @@ func TestGetMilestonesByRepoID(t *testing.T) {
|
||||||
assert.NoError(t, PrepareTestDatabase())
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
test := func(repoID int64, state api.StateType) {
|
test := func(repoID int64, state api.StateType) {
|
||||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
|
repo := AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository)
|
||||||
milestones, err := GetMilestonesByRepoID(repo.ID, state, ListOptions{})
|
milestones, err := GetMilestones(GetMilestonesOption{
|
||||||
|
RepoID: repo.ID,
|
||||||
|
State: state,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
var n int
|
var n int
|
||||||
|
@ -83,7 +87,10 @@ func TestGetMilestonesByRepoID(t *testing.T) {
|
||||||
test(3, api.StateClosed)
|
test(3, api.StateClosed)
|
||||||
test(3, api.StateAll)
|
test(3, api.StateAll)
|
||||||
|
|
||||||
milestones, err := GetMilestonesByRepoID(NonexistentID, api.StateOpen, ListOptions{})
|
milestones, err := GetMilestones(GetMilestonesOption{
|
||||||
|
RepoID: NonexistentID,
|
||||||
|
State: api.StateOpen,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, milestones, 0)
|
assert.Len(t, milestones, 0)
|
||||||
}
|
}
|
||||||
|
@ -93,7 +100,15 @@ func TestGetMilestones(t *testing.T) {
|
||||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
|
||||||
test := func(sortType string, sortCond func(*Milestone) int) {
|
test := func(sortType string, sortCond func(*Milestone) int) {
|
||||||
for _, page := range []int{0, 1} {
|
for _, page := range []int{0, 1} {
|
||||||
milestones, err := GetMilestones(repo.ID, page, false, sortType)
|
milestones, err := GetMilestones(GetMilestonesOption{
|
||||||
|
ListOptions: ListOptions{
|
||||||
|
Page: page,
|
||||||
|
PageSize: setting.UI.IssuePagingNum,
|
||||||
|
},
|
||||||
|
RepoID: repo.ID,
|
||||||
|
State: api.StateOpen,
|
||||||
|
SortType: sortType,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, milestones, repo.NumMilestones-repo.NumClosedMilestones)
|
assert.Len(t, milestones, repo.NumMilestones-repo.NumClosedMilestones)
|
||||||
values := make([]int, len(milestones))
|
values := make([]int, len(milestones))
|
||||||
|
@ -102,7 +117,16 @@ func TestGetMilestones(t *testing.T) {
|
||||||
}
|
}
|
||||||
assert.True(t, sort.IntsAreSorted(values))
|
assert.True(t, sort.IntsAreSorted(values))
|
||||||
|
|
||||||
milestones, err = GetMilestones(repo.ID, page, true, sortType)
|
milestones, err = GetMilestones(GetMilestonesOption{
|
||||||
|
ListOptions: ListOptions{
|
||||||
|
Page: page,
|
||||||
|
PageSize: setting.UI.IssuePagingNum,
|
||||||
|
},
|
||||||
|
RepoID: repo.ID,
|
||||||
|
State: api.StateClosed,
|
||||||
|
Name: "",
|
||||||
|
SortType: sortType,
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, milestones, repo.NumClosedMilestones)
|
assert.Len(t, milestones, repo.NumClosedMilestones)
|
||||||
values = make([]int, len(milestones))
|
values = make([]int, len(milestones))
|
||||||
|
|
|
@ -101,6 +101,21 @@ func CreateOrStopIssueStopwatch(user *User, issue *Issue) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
//if another stopwatch is running: stop it
|
||||||
|
exists, sw, err := HasUserStopwatch(user.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
issue, err := getIssueByID(x, sw.IssueID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := CreateOrStopIssueStopwatch(user, issue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create stopwatch
|
// Create stopwatch
|
||||||
sw = &Stopwatch{
|
sw = &Stopwatch{
|
||||||
UserID: user.ID,
|
UserID: user.ID,
|
||||||
|
|
|
@ -38,7 +38,10 @@ func (opts ListOptions) setEnginePagination(e Engine) Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opts ListOptions) setDefaultValues() {
|
func (opts ListOptions) setDefaultValues() {
|
||||||
if opts.PageSize <= 0 || opts.PageSize > setting.API.MaxResponseItems {
|
if opts.PageSize <= 0 {
|
||||||
|
opts.PageSize = setting.API.DefaultPagingNum
|
||||||
|
}
|
||||||
|
if opts.PageSize > setting.API.MaxResponseItems {
|
||||||
opts.PageSize = setting.API.MaxResponseItems
|
opts.PageSize = setting.API.MaxResponseItems
|
||||||
}
|
}
|
||||||
if opts.Page <= 0 {
|
if opts.Page <= 0 {
|
||||||
|
|
|
@ -300,7 +300,7 @@ func (source *LoginSource) SSPI() *SSPIConfig {
|
||||||
// CreateLoginSource inserts a LoginSource in the DB if not already
|
// CreateLoginSource inserts a LoginSource in the DB if not already
|
||||||
// existing with the given name.
|
// existing with the given name.
|
||||||
func CreateLoginSource(source *LoginSource) error {
|
func CreateLoginSource(source *LoginSource) error {
|
||||||
has, err := x.Get(&LoginSource{Name: source.Name})
|
has, err := x.Where("name=?", source.Name).Exist(new(LoginSource))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if has {
|
} else if has {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue