mirror of
https://github.com/go-gitea/gitea.git
synced 2025-02-20 11:43:57 +08:00
Merge branch 'main' into lunny/issue_dev
This commit is contained in:
commit
a84034a838
999
.eslintrc.cjs
Normal file
999
.eslintrc.cjs
Normal file
@ -0,0 +1,999 @@
|
||||
const restrictedSyntax = ['WithStatement', 'ForInStatement', 'LabeledStatement', 'SequenceExpression'];
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
reportUnusedDisableDirectives: true,
|
||||
ignorePatterns: [
|
||||
'/web_src/js/vendor',
|
||||
'/web_src/fomantic',
|
||||
'/public/assets/js',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 'latest',
|
||||
project: true,
|
||||
extraFileExtensions: ['.vue'],
|
||||
parser: '@typescript-eslint/parser', // for vue plugin - https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
|
||||
},
|
||||
settings: {
|
||||
'import-x/extensions': ['.js', '.ts'],
|
||||
'import-x/parsers': {
|
||||
'@typescript-eslint/parser': ['.js', '.ts'],
|
||||
},
|
||||
'import-x/resolver': {
|
||||
typescript: true,
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
'@eslint-community/eslint-plugin-eslint-comments',
|
||||
'@stylistic/eslint-plugin-js',
|
||||
'@typescript-eslint/eslint-plugin',
|
||||
'eslint-plugin-array-func',
|
||||
'eslint-plugin-github',
|
||||
'eslint-plugin-import-x',
|
||||
'eslint-plugin-no-jquery',
|
||||
'eslint-plugin-no-use-extend-native',
|
||||
'eslint-plugin-regexp',
|
||||
'eslint-plugin-sonarjs',
|
||||
'eslint-plugin-unicorn',
|
||||
'eslint-plugin-vitest',
|
||||
'eslint-plugin-vitest-globals',
|
||||
'eslint-plugin-wc',
|
||||
],
|
||||
env: {
|
||||
es2024: true,
|
||||
node: true,
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['web_src/**/*'],
|
||||
globals: {
|
||||
__webpack_public_path__: true,
|
||||
process: false, // https://github.com/webpack/webpack/issues/15833
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['web_src/**/*', 'docs/**/*'],
|
||||
env: {
|
||||
browser: true,
|
||||
node: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.config.*'],
|
||||
rules: {
|
||||
'import-x/no-unused-modules': [0],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.d.ts'],
|
||||
rules: {
|
||||
'import-x/no-unused-modules': [0],
|
||||
'@typescript-eslint/consistent-type-definitions': [0],
|
||||
'@typescript-eslint/consistent-type-imports': [0],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['web_src/js/types.ts'],
|
||||
rules: {
|
||||
'import-x/no-unused-modules': [0],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.test.*', 'web_src/js/test/setup.ts'],
|
||||
env: {
|
||||
'vitest-globals/env': true,
|
||||
},
|
||||
rules: {
|
||||
'vitest/consistent-test-filename': [0],
|
||||
'vitest/consistent-test-it': [0],
|
||||
'vitest/expect-expect': [0],
|
||||
'vitest/max-expects': [0],
|
||||
'vitest/max-nested-describe': [0],
|
||||
'vitest/no-alias-methods': [0],
|
||||
'vitest/no-commented-out-tests': [0],
|
||||
'vitest/no-conditional-expect': [0],
|
||||
'vitest/no-conditional-in-test': [0],
|
||||
'vitest/no-conditional-tests': [0],
|
||||
'vitest/no-disabled-tests': [0],
|
||||
'vitest/no-done-callback': [0],
|
||||
'vitest/no-duplicate-hooks': [0],
|
||||
'vitest/no-focused-tests': [0],
|
||||
'vitest/no-hooks': [0],
|
||||
'vitest/no-identical-title': [2],
|
||||
'vitest/no-interpolation-in-snapshots': [0],
|
||||
'vitest/no-large-snapshots': [0],
|
||||
'vitest/no-mocks-import': [0],
|
||||
'vitest/no-restricted-matchers': [0],
|
||||
'vitest/no-restricted-vi-methods': [0],
|
||||
'vitest/no-standalone-expect': [0],
|
||||
'vitest/no-test-prefixes': [0],
|
||||
'vitest/no-test-return-statement': [0],
|
||||
'vitest/prefer-called-with': [0],
|
||||
'vitest/prefer-comparison-matcher': [0],
|
||||
'vitest/prefer-each': [0],
|
||||
'vitest/prefer-equality-matcher': [0],
|
||||
'vitest/prefer-expect-resolves': [0],
|
||||
'vitest/prefer-hooks-in-order': [0],
|
||||
'vitest/prefer-hooks-on-top': [2],
|
||||
'vitest/prefer-lowercase-title': [0],
|
||||
'vitest/prefer-mock-promise-shorthand': [0],
|
||||
'vitest/prefer-snapshot-hint': [0],
|
||||
'vitest/prefer-spy-on': [0],
|
||||
'vitest/prefer-strict-equal': [0],
|
||||
'vitest/prefer-to-be': [0],
|
||||
'vitest/prefer-to-be-falsy': [0],
|
||||
'vitest/prefer-to-be-object': [0],
|
||||
'vitest/prefer-to-be-truthy': [0],
|
||||
'vitest/prefer-to-contain': [0],
|
||||
'vitest/prefer-to-have-length': [0],
|
||||
'vitest/prefer-todo': [0],
|
||||
'vitest/require-hook': [0],
|
||||
'vitest/require-to-throw-message': [0],
|
||||
'vitest/require-top-level-describe': [0],
|
||||
'vitest/valid-describe-callback': [2],
|
||||
'vitest/valid-expect': [2],
|
||||
'vitest/valid-title': [2],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['web_src/js/modules/fetch.ts', 'web_src/js/standalone/**/*'],
|
||||
rules: {
|
||||
'no-restricted-syntax': [2, ...restrictedSyntax],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.vue'],
|
||||
plugins: [
|
||||
'eslint-plugin-vue',
|
||||
'eslint-plugin-vue-scoped-css',
|
||||
],
|
||||
extends: [
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:vue-scoped-css/vue3-recommended',
|
||||
],
|
||||
rules: {
|
||||
'vue/attributes-order': [0],
|
||||
'vue/html-closing-bracket-spacing': [2, {startTag: 'never', endTag: 'never', selfClosingTag: 'never'}],
|
||||
'vue/max-attributes-per-line': [0],
|
||||
'vue/singleline-html-element-content-newline': [0],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['tests/e2e/**'],
|
||||
plugins: [
|
||||
'eslint-plugin-playwright'
|
||||
],
|
||||
extends: [
|
||||
'plugin:playwright/recommended',
|
||||
],
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
'@eslint-community/eslint-comments/disable-enable-pair': [2],
|
||||
'@eslint-community/eslint-comments/no-aggregating-enable': [2],
|
||||
'@eslint-community/eslint-comments/no-duplicate-disable': [2],
|
||||
'@eslint-community/eslint-comments/no-restricted-disable': [0],
|
||||
'@eslint-community/eslint-comments/no-unlimited-disable': [2],
|
||||
'@eslint-community/eslint-comments/no-unused-disable': [2],
|
||||
'@eslint-community/eslint-comments/no-unused-enable': [2],
|
||||
'@eslint-community/eslint-comments/no-use': [0],
|
||||
'@eslint-community/eslint-comments/require-description': [0],
|
||||
'@stylistic/js/array-bracket-newline': [0],
|
||||
'@stylistic/js/array-bracket-spacing': [2, 'never'],
|
||||
'@stylistic/js/array-element-newline': [0],
|
||||
'@stylistic/js/arrow-parens': [2, 'always'],
|
||||
'@stylistic/js/arrow-spacing': [2, {before: true, after: true}],
|
||||
'@stylistic/js/block-spacing': [0],
|
||||
'@stylistic/js/brace-style': [2, '1tbs', {allowSingleLine: true}],
|
||||
'@stylistic/js/comma-dangle': [2, 'always-multiline'],
|
||||
'@stylistic/js/comma-spacing': [2, {before: false, after: true}],
|
||||
'@stylistic/js/comma-style': [2, 'last'],
|
||||
'@stylistic/js/computed-property-spacing': [2, 'never'],
|
||||
'@stylistic/js/dot-location': [2, 'property'],
|
||||
'@stylistic/js/eol-last': [2],
|
||||
'@stylistic/js/function-call-argument-newline': [0],
|
||||
'@stylistic/js/function-call-spacing': [2, 'never'],
|
||||
'@stylistic/js/function-paren-newline': [0],
|
||||
'@stylistic/js/generator-star-spacing': [0],
|
||||
'@stylistic/js/implicit-arrow-linebreak': [0],
|
||||
'@stylistic/js/indent': [2, 2, {ignoreComments: true, SwitchCase: 1}],
|
||||
'@stylistic/js/key-spacing': [2],
|
||||
'@stylistic/js/keyword-spacing': [2],
|
||||
'@stylistic/js/line-comment-position': [0],
|
||||
'@stylistic/js/linebreak-style': [2, 'unix'],
|
||||
'@stylistic/js/lines-around-comment': [0],
|
||||
'@stylistic/js/lines-between-class-members': [0],
|
||||
'@stylistic/js/max-len': [0],
|
||||
'@stylistic/js/max-statements-per-line': [0],
|
||||
'@stylistic/js/multiline-comment-style': [0],
|
||||
'@stylistic/js/multiline-ternary': [0],
|
||||
'@stylistic/js/new-parens': [2],
|
||||
'@stylistic/js/newline-per-chained-call': [0],
|
||||
'@stylistic/js/no-confusing-arrow': [0],
|
||||
'@stylistic/js/no-extra-parens': [0],
|
||||
'@stylistic/js/no-extra-semi': [2],
|
||||
'@stylistic/js/no-floating-decimal': [0],
|
||||
'@stylistic/js/no-mixed-operators': [0],
|
||||
'@stylistic/js/no-mixed-spaces-and-tabs': [2],
|
||||
'@stylistic/js/no-multi-spaces': [2, {ignoreEOLComments: true, exceptions: {Property: true}}],
|
||||
'@stylistic/js/no-multiple-empty-lines': [2, {max: 1, maxEOF: 0, maxBOF: 0}],
|
||||
'@stylistic/js/no-tabs': [2],
|
||||
'@stylistic/js/no-trailing-spaces': [2],
|
||||
'@stylistic/js/no-whitespace-before-property': [2],
|
||||
'@stylistic/js/nonblock-statement-body-position': [2],
|
||||
'@stylistic/js/object-curly-newline': [0],
|
||||
'@stylistic/js/object-curly-spacing': [2, 'never'],
|
||||
'@stylistic/js/object-property-newline': [0],
|
||||
'@stylistic/js/one-var-declaration-per-line': [0],
|
||||
'@stylistic/js/operator-linebreak': [2, 'after'],
|
||||
'@stylistic/js/padded-blocks': [2, 'never'],
|
||||
'@stylistic/js/padding-line-between-statements': [0],
|
||||
'@stylistic/js/quote-props': [0],
|
||||
'@stylistic/js/quotes': [2, 'single', {avoidEscape: true, allowTemplateLiterals: true}],
|
||||
'@stylistic/js/rest-spread-spacing': [2, 'never'],
|
||||
'@stylistic/js/semi': [2, 'always', {omitLastInOneLineBlock: true}],
|
||||
'@stylistic/js/semi-spacing': [2, {before: false, after: true}],
|
||||
'@stylistic/js/semi-style': [2, 'last'],
|
||||
'@stylistic/js/space-before-blocks': [2, 'always'],
|
||||
'@stylistic/js/space-before-function-paren': [2, {anonymous: 'ignore', named: 'never', asyncArrow: 'always'}],
|
||||
'@stylistic/js/space-in-parens': [2, 'never'],
|
||||
'@stylistic/js/space-infix-ops': [2],
|
||||
'@stylistic/js/space-unary-ops': [2],
|
||||
'@stylistic/js/spaced-comment': [2, 'always'],
|
||||
'@stylistic/js/switch-colon-spacing': [2],
|
||||
'@stylistic/js/template-curly-spacing': [2, 'never'],
|
||||
'@stylistic/js/template-tag-spacing': [2, 'never'],
|
||||
'@stylistic/js/wrap-iife': [2, 'inside'],
|
||||
'@stylistic/js/wrap-regex': [0],
|
||||
'@stylistic/js/yield-star-spacing': [2, 'after'],
|
||||
'@typescript-eslint/adjacent-overload-signatures': [0],
|
||||
'@typescript-eslint/array-type': [0],
|
||||
'@typescript-eslint/await-thenable': [2],
|
||||
'@typescript-eslint/ban-ts-comment': [2, {'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': false, 'ts-check': false}],
|
||||
'@typescript-eslint/ban-tslint-comment': [0],
|
||||
'@typescript-eslint/class-literal-property-style': [0],
|
||||
'@typescript-eslint/class-methods-use-this': [0],
|
||||
'@typescript-eslint/consistent-generic-constructors': [0],
|
||||
'@typescript-eslint/consistent-indexed-object-style': [0],
|
||||
'@typescript-eslint/consistent-return': [0],
|
||||
'@typescript-eslint/consistent-type-assertions': [2, {assertionStyle: 'as', objectLiteralTypeAssertions: 'allow'}],
|
||||
'@typescript-eslint/consistent-type-definitions': [2, 'type'],
|
||||
'@typescript-eslint/consistent-type-exports': [2, {fixMixedExportsWithInlineTypeSpecifier: false}],
|
||||
'@typescript-eslint/consistent-type-imports': [2, {prefer: 'type-imports', fixStyle: 'separate-type-imports', disallowTypeAnnotations: true}],
|
||||
'@typescript-eslint/default-param-last': [0],
|
||||
'@typescript-eslint/dot-notation': [0],
|
||||
'@typescript-eslint/explicit-function-return-type': [0],
|
||||
'@typescript-eslint/explicit-member-accessibility': [0],
|
||||
'@typescript-eslint/explicit-module-boundary-types': [0],
|
||||
'@typescript-eslint/init-declarations': [0],
|
||||
'@typescript-eslint/max-params': [0],
|
||||
'@typescript-eslint/member-ordering': [0],
|
||||
'@typescript-eslint/method-signature-style': [0],
|
||||
'@typescript-eslint/naming-convention': [0],
|
||||
'@typescript-eslint/no-array-constructor': [2],
|
||||
'@typescript-eslint/no-array-delete': [2],
|
||||
'@typescript-eslint/no-base-to-string': [0],
|
||||
'@typescript-eslint/no-confusing-non-null-assertion': [2],
|
||||
'@typescript-eslint/no-confusing-void-expression': [0],
|
||||
'@typescript-eslint/no-deprecated': [2],
|
||||
'@typescript-eslint/no-dupe-class-members': [0],
|
||||
'@typescript-eslint/no-duplicate-enum-values': [2],
|
||||
'@typescript-eslint/no-duplicate-type-constituents': [2, {ignoreUnions: true}],
|
||||
'@typescript-eslint/no-dynamic-delete': [0],
|
||||
'@typescript-eslint/no-empty-function': [0],
|
||||
'@typescript-eslint/no-empty-interface': [0],
|
||||
'@typescript-eslint/no-empty-object-type': [2],
|
||||
'@typescript-eslint/no-explicit-any': [0],
|
||||
'@typescript-eslint/no-extra-non-null-assertion': [2],
|
||||
'@typescript-eslint/no-extraneous-class': [0],
|
||||
'@typescript-eslint/no-floating-promises': [0],
|
||||
'@typescript-eslint/no-for-in-array': [2],
|
||||
'@typescript-eslint/no-implied-eval': [2],
|
||||
'@typescript-eslint/no-import-type-side-effects': [0], // dupe with consistent-type-imports
|
||||
'@typescript-eslint/no-inferrable-types': [0],
|
||||
'@typescript-eslint/no-invalid-this': [0],
|
||||
'@typescript-eslint/no-invalid-void-type': [0],
|
||||
'@typescript-eslint/no-loop-func': [0],
|
||||
'@typescript-eslint/no-loss-of-precision': [0],
|
||||
'@typescript-eslint/no-magic-numbers': [0],
|
||||
'@typescript-eslint/no-meaningless-void-operator': [0],
|
||||
'@typescript-eslint/no-misused-new': [2],
|
||||
'@typescript-eslint/no-misused-promises': [2, {checksVoidReturn: {attributes: false, arguments: false}}],
|
||||
'@typescript-eslint/no-mixed-enums': [0],
|
||||
'@typescript-eslint/no-namespace': [2],
|
||||
'@typescript-eslint/no-non-null-asserted-nullish-coalescing': [0],
|
||||
'@typescript-eslint/no-non-null-asserted-optional-chain': [2],
|
||||
'@typescript-eslint/no-non-null-assertion': [0],
|
||||
'@typescript-eslint/no-redeclare': [0],
|
||||
'@typescript-eslint/no-redundant-type-constituents': [2],
|
||||
'@typescript-eslint/no-require-imports': [2],
|
||||
'@typescript-eslint/no-restricted-imports': [0],
|
||||
'@typescript-eslint/no-restricted-types': [0],
|
||||
'@typescript-eslint/no-shadow': [0],
|
||||
'@typescript-eslint/no-this-alias': [0], // handled by unicorn/no-this-assignment
|
||||
'@typescript-eslint/no-unnecessary-boolean-literal-compare': [0],
|
||||
'@typescript-eslint/no-unnecessary-condition': [0],
|
||||
'@typescript-eslint/no-unnecessary-qualifier': [0],
|
||||
'@typescript-eslint/no-unnecessary-template-expression': [0],
|
||||
'@typescript-eslint/no-unnecessary-type-arguments': [0],
|
||||
'@typescript-eslint/no-unnecessary-type-assertion': [2],
|
||||
'@typescript-eslint/no-unnecessary-type-constraint': [2],
|
||||
'@typescript-eslint/no-unsafe-argument': [0],
|
||||
'@typescript-eslint/no-unsafe-assignment': [0],
|
||||
'@typescript-eslint/no-unsafe-call': [0],
|
||||
'@typescript-eslint/no-unsafe-declaration-merging': [2],
|
||||
'@typescript-eslint/no-unsafe-enum-comparison': [2],
|
||||
'@typescript-eslint/no-unsafe-function-type': [2],
|
||||
'@typescript-eslint/no-unsafe-member-access': [0],
|
||||
'@typescript-eslint/no-unsafe-return': [0],
|
||||
'@typescript-eslint/no-unsafe-unary-minus': [2],
|
||||
'@typescript-eslint/no-unused-expressions': [0],
|
||||
'@typescript-eslint/no-unused-vars': [2, {vars: 'all', args: 'all', caughtErrors: 'all', ignoreRestSiblings: false, argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_'}],
|
||||
'@typescript-eslint/no-use-before-define': [0],
|
||||
'@typescript-eslint/no-useless-constructor': [0],
|
||||
'@typescript-eslint/no-useless-empty-export': [0],
|
||||
'@typescript-eslint/no-wrapper-object-types': [2],
|
||||
'@typescript-eslint/non-nullable-type-assertion-style': [0],
|
||||
'@typescript-eslint/only-throw-error': [2],
|
||||
'@typescript-eslint/parameter-properties': [0],
|
||||
'@typescript-eslint/prefer-as-const': [2],
|
||||
'@typescript-eslint/prefer-destructuring': [0],
|
||||
'@typescript-eslint/prefer-enum-initializers': [0],
|
||||
'@typescript-eslint/prefer-find': [2],
|
||||
'@typescript-eslint/prefer-for-of': [2],
|
||||
'@typescript-eslint/prefer-function-type': [2],
|
||||
'@typescript-eslint/prefer-includes': [2],
|
||||
'@typescript-eslint/prefer-literal-enum-member': [0],
|
||||
'@typescript-eslint/prefer-namespace-keyword': [0],
|
||||
'@typescript-eslint/prefer-nullish-coalescing': [0],
|
||||
'@typescript-eslint/prefer-optional-chain': [2, {requireNullish: true}],
|
||||
'@typescript-eslint/prefer-promise-reject-errors': [0],
|
||||
'@typescript-eslint/prefer-readonly': [0],
|
||||
'@typescript-eslint/prefer-readonly-parameter-types': [0],
|
||||
'@typescript-eslint/prefer-reduce-type-parameter': [0],
|
||||
'@typescript-eslint/prefer-regexp-exec': [0],
|
||||
'@typescript-eslint/prefer-return-this-type': [0],
|
||||
'@typescript-eslint/prefer-string-starts-ends-with': [2, {allowSingleElementEquality: 'always'}],
|
||||
'@typescript-eslint/promise-function-async': [0],
|
||||
'@typescript-eslint/require-array-sort-compare': [0],
|
||||
'@typescript-eslint/require-await': [0],
|
||||
'@typescript-eslint/restrict-plus-operands': [2],
|
||||
'@typescript-eslint/restrict-template-expressions': [0],
|
||||
'@typescript-eslint/return-await': [0],
|
||||
'@typescript-eslint/strict-boolean-expressions': [0],
|
||||
'@typescript-eslint/switch-exhaustiveness-check': [0],
|
||||
'@typescript-eslint/triple-slash-reference': [2],
|
||||
'@typescript-eslint/typedef': [0],
|
||||
'@typescript-eslint/unbound-method': [0], // too many false-positives
|
||||
'@typescript-eslint/unified-signatures': [2],
|
||||
'accessor-pairs': [2],
|
||||
'array-callback-return': [2, {checkForEach: true}],
|
||||
'array-func/avoid-reverse': [2],
|
||||
'array-func/from-map': [2],
|
||||
'array-func/no-unnecessary-this-arg': [2],
|
||||
'array-func/prefer-array-from': [2],
|
||||
'array-func/prefer-flat-map': [0], // handled by unicorn/prefer-array-flat-map
|
||||
'array-func/prefer-flat': [0], // handled by unicorn/prefer-array-flat
|
||||
'arrow-body-style': [0],
|
||||
'block-scoped-var': [2],
|
||||
'camelcase': [0],
|
||||
'capitalized-comments': [0],
|
||||
'class-methods-use-this': [0],
|
||||
'complexity': [0],
|
||||
'consistent-return': [0],
|
||||
'consistent-this': [0],
|
||||
'constructor-super': [2],
|
||||
'curly': [0],
|
||||
'default-case-last': [2],
|
||||
'default-case': [0],
|
||||
'default-param-last': [0],
|
||||
'dot-notation': [0],
|
||||
'eqeqeq': [2],
|
||||
'for-direction': [2],
|
||||
'func-name-matching': [2],
|
||||
'func-names': [0],
|
||||
'func-style': [0],
|
||||
'getter-return': [2],
|
||||
'github/a11y-aria-label-is-well-formatted': [0],
|
||||
'github/a11y-no-title-attribute': [0],
|
||||
'github/a11y-no-visually-hidden-interactive-element': [0],
|
||||
'github/a11y-role-supports-aria-props': [0],
|
||||
'github/a11y-svg-has-accessible-name': [0],
|
||||
'github/array-foreach': [0],
|
||||
'github/async-currenttarget': [2],
|
||||
'github/async-preventdefault': [2],
|
||||
'github/authenticity-token': [0],
|
||||
'github/get-attribute': [0],
|
||||
'github/js-class-name': [0],
|
||||
'github/no-blur': [0],
|
||||
'github/no-d-none': [0],
|
||||
'github/no-dataset': [2],
|
||||
'github/no-dynamic-script-tag': [2],
|
||||
'github/no-implicit-buggy-globals': [2],
|
||||
'github/no-inner-html': [0],
|
||||
'github/no-innerText': [2],
|
||||
'github/no-then': [2],
|
||||
'github/no-useless-passive': [2],
|
||||
'github/prefer-observers': [2],
|
||||
'github/require-passive-events': [2],
|
||||
'github/unescaped-html-literal': [0],
|
||||
'grouped-accessor-pairs': [2],
|
||||
'guard-for-in': [0],
|
||||
'id-blacklist': [0],
|
||||
'id-length': [0],
|
||||
'id-match': [0],
|
||||
'import-x/consistent-type-specifier-style': [0],
|
||||
'import-x/default': [0],
|
||||
'import-x/dynamic-import-chunkname': [0],
|
||||
'import-x/export': [2],
|
||||
'import-x/exports-last': [0],
|
||||
'import-x/extensions': [2, 'always', {ignorePackages: true}],
|
||||
'import-x/first': [2],
|
||||
'import-x/group-exports': [0],
|
||||
'import-x/max-dependencies': [0],
|
||||
'import-x/named': [2],
|
||||
'import-x/namespace': [0],
|
||||
'import-x/newline-after-import': [0],
|
||||
'import-x/no-absolute-path': [0],
|
||||
'import-x/no-amd': [2],
|
||||
'import-x/no-anonymous-default-export': [0],
|
||||
'import-x/no-commonjs': [2],
|
||||
'import-x/no-cycle': [2, {ignoreExternal: true, maxDepth: 1}],
|
||||
'import-x/no-default-export': [0],
|
||||
'import-x/no-deprecated': [0],
|
||||
'import-x/no-dynamic-require': [0],
|
||||
'import-x/no-empty-named-blocks': [2],
|
||||
'import-x/no-extraneous-dependencies': [2],
|
||||
'import-x/no-import-module-exports': [0],
|
||||
'import-x/no-internal-modules': [0],
|
||||
'import-x/no-mutable-exports': [0],
|
||||
'import-x/no-named-as-default-member': [0],
|
||||
'import-x/no-named-as-default': [0],
|
||||
'import-x/no-named-default': [0],
|
||||
'import-x/no-named-export': [0],
|
||||
'import-x/no-namespace': [0],
|
||||
'import-x/no-nodejs-modules': [0],
|
||||
'import-x/no-relative-packages': [0],
|
||||
'import-x/no-relative-parent-imports': [0],
|
||||
'import-x/no-restricted-paths': [0],
|
||||
'import-x/no-self-import': [2],
|
||||
'import-x/no-unassigned-import': [0],
|
||||
'import-x/no-unresolved': [2, {commonjs: true, ignore: ['\\?.+$']}],
|
||||
'import-x/no-unused-modules': [2, {unusedExports: true}],
|
||||
'import-x/no-useless-path-segments': [2, {commonjs: true}],
|
||||
'import-x/no-webpack-loader-syntax': [2],
|
||||
'import-x/order': [0],
|
||||
'import-x/prefer-default-export': [0],
|
||||
'import-x/unambiguous': [0],
|
||||
'init-declarations': [0],
|
||||
'line-comment-position': [0],
|
||||
'logical-assignment-operators': [0],
|
||||
'max-classes-per-file': [0],
|
||||
'max-depth': [0],
|
||||
'max-lines-per-function': [0],
|
||||
'max-lines': [0],
|
||||
'max-nested-callbacks': [0],
|
||||
'max-params': [0],
|
||||
'max-statements': [0],
|
||||
'multiline-comment-style': [2, 'separate-lines'],
|
||||
'new-cap': [0],
|
||||
'no-alert': [0],
|
||||
'no-array-constructor': [0], // handled by @typescript-eslint/no-array-constructor
|
||||
'no-async-promise-executor': [0],
|
||||
'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-console': [1, {allow: ['debug', 'info', 'warn', 'error']}],
|
||||
'no-const-assign': [2],
|
||||
'no-constant-binary-expression': [2],
|
||||
'no-constant-condition': [0],
|
||||
'no-constructor-return': [2],
|
||||
'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': [0],
|
||||
'no-else-return': [2],
|
||||
'no-empty-character-class': [2],
|
||||
'no-empty-function': [0],
|
||||
'no-empty-pattern': [2],
|
||||
'no-empty-static-block': [2],
|
||||
'no-empty': [2, {allowEmptyCatch: true}],
|
||||
'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-fallthrough': [2],
|
||||
'no-func-assign': [2],
|
||||
'no-global-assign': [2],
|
||||
'no-implicit-coercion': [2],
|
||||
'no-implicit-globals': [0],
|
||||
'no-implied-eval': [0], // handled by @typescript-eslint/no-implied-eval
|
||||
'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-jquery/no-ajax-events': [2],
|
||||
'no-jquery/no-ajax': [2],
|
||||
'no-jquery/no-and-self': [2],
|
||||
'no-jquery/no-animate-toggle': [2],
|
||||
'no-jquery/no-animate': [2],
|
||||
'no-jquery/no-append-html': [2],
|
||||
'no-jquery/no-attr': [2],
|
||||
'no-jquery/no-bind': [2],
|
||||
'no-jquery/no-box-model': [2],
|
||||
'no-jquery/no-browser': [2],
|
||||
'no-jquery/no-camel-case': [2],
|
||||
'no-jquery/no-class-state': [2],
|
||||
'no-jquery/no-class': [0],
|
||||
'no-jquery/no-clone': [2],
|
||||
'no-jquery/no-closest': [0],
|
||||
'no-jquery/no-constructor-attributes': [2],
|
||||
'no-jquery/no-contains': [2],
|
||||
'no-jquery/no-context-prop': [2],
|
||||
'no-jquery/no-css': [2],
|
||||
'no-jquery/no-data': [0],
|
||||
'no-jquery/no-deferred': [2],
|
||||
'no-jquery/no-delegate': [2],
|
||||
'no-jquery/no-done-fail': [2],
|
||||
'no-jquery/no-each-collection': [0],
|
||||
'no-jquery/no-each-util': [0],
|
||||
'no-jquery/no-each': [0],
|
||||
'no-jquery/no-error-shorthand': [2],
|
||||
'no-jquery/no-error': [2],
|
||||
'no-jquery/no-escape-selector': [2],
|
||||
'no-jquery/no-event-shorthand': [2],
|
||||
'no-jquery/no-extend': [2],
|
||||
'no-jquery/no-fade': [2],
|
||||
'no-jquery/no-filter': [0],
|
||||
'no-jquery/no-find-collection': [0],
|
||||
'no-jquery/no-find-util': [2],
|
||||
'no-jquery/no-find': [0],
|
||||
'no-jquery/no-fx-interval': [2],
|
||||
'no-jquery/no-fx': [2],
|
||||
'no-jquery/no-global-eval': [2],
|
||||
'no-jquery/no-global-selector': [0],
|
||||
'no-jquery/no-grep': [2],
|
||||
'no-jquery/no-has': [2],
|
||||
'no-jquery/no-hold-ready': [2],
|
||||
'no-jquery/no-html': [0],
|
||||
'no-jquery/no-in-array': [2],
|
||||
'no-jquery/no-is-array': [2],
|
||||
'no-jquery/no-is-empty-object': [2],
|
||||
'no-jquery/no-is-function': [2],
|
||||
'no-jquery/no-is-numeric': [2],
|
||||
'no-jquery/no-is-plain-object': [2],
|
||||
'no-jquery/no-is-window': [2],
|
||||
'no-jquery/no-is': [2],
|
||||
'no-jquery/no-jquery-constructor': [0],
|
||||
'no-jquery/no-live': [2],
|
||||
'no-jquery/no-load-shorthand': [2],
|
||||
'no-jquery/no-load': [2],
|
||||
'no-jquery/no-map-collection': [0],
|
||||
'no-jquery/no-map-util': [2],
|
||||
'no-jquery/no-map': [2],
|
||||
'no-jquery/no-merge': [2],
|
||||
'no-jquery/no-node-name': [2],
|
||||
'no-jquery/no-noop': [2],
|
||||
'no-jquery/no-now': [2],
|
||||
'no-jquery/no-on-ready': [2],
|
||||
'no-jquery/no-other-methods': [0],
|
||||
'no-jquery/no-other-utils': [2],
|
||||
'no-jquery/no-param': [2],
|
||||
'no-jquery/no-parent': [0],
|
||||
'no-jquery/no-parents': [2],
|
||||
'no-jquery/no-parse-html-literal': [2],
|
||||
'no-jquery/no-parse-html': [2],
|
||||
'no-jquery/no-parse-json': [2],
|
||||
'no-jquery/no-parse-xml': [2],
|
||||
'no-jquery/no-prop': [2],
|
||||
'no-jquery/no-proxy': [2],
|
||||
'no-jquery/no-ready-shorthand': [2],
|
||||
'no-jquery/no-ready': [2],
|
||||
'no-jquery/no-selector-prop': [2],
|
||||
'no-jquery/no-serialize': [2],
|
||||
'no-jquery/no-size': [2],
|
||||
'no-jquery/no-sizzle': [2],
|
||||
'no-jquery/no-slide': [2],
|
||||
'no-jquery/no-sub': [2],
|
||||
'no-jquery/no-support': [2],
|
||||
'no-jquery/no-text': [2],
|
||||
'no-jquery/no-trigger': [0],
|
||||
'no-jquery/no-trim': [2],
|
||||
'no-jquery/no-type': [2],
|
||||
'no-jquery/no-unique': [2],
|
||||
'no-jquery/no-unload-shorthand': [2],
|
||||
'no-jquery/no-val': [0],
|
||||
'no-jquery/no-visibility': [2],
|
||||
'no-jquery/no-when': [2],
|
||||
'no-jquery/no-wrap': [2],
|
||||
'no-jquery/variable-pattern': [2],
|
||||
'no-label-var': [2],
|
||||
'no-labels': [0], // handled by no-restricted-syntax
|
||||
'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-multi-assign': [0],
|
||||
'no-multi-str': [2],
|
||||
'no-negated-condition': [0],
|
||||
'no-nested-ternary': [0],
|
||||
'no-new-func': [2],
|
||||
'no-new-native-nonconstructor': [2],
|
||||
'no-new-object': [2],
|
||||
'no-new-symbol': [2],
|
||||
'no-new-wrappers': [2],
|
||||
'no-new': [0],
|
||||
'no-nonoctal-decimal-escape': [2],
|
||||
'no-obj-calls': [2],
|
||||
'no-octal-escape': [2],
|
||||
'no-octal': [2],
|
||||
'no-param-reassign': [0],
|
||||
'no-plusplus': [0],
|
||||
'no-promise-executor-return': [0],
|
||||
'no-proto': [2],
|
||||
'no-prototype-builtins': [2],
|
||||
'no-redeclare': [0], // must be disabled for typescript overloads
|
||||
'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', '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'],
|
||||
'no-restricted-imports': [0],
|
||||
'no-restricted-syntax': [2, ...restrictedSyntax, {selector: 'CallExpression[callee.name="fetch"]', message: 'use modules/fetch.ts instead'}],
|
||||
'no-return-assign': [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-sparse-arrays': [2],
|
||||
'no-template-curly-in-string': [2],
|
||||
'no-ternary': [0],
|
||||
'no-this-before-super': [2],
|
||||
'no-throw-literal': [2],
|
||||
'no-undef-init': [2],
|
||||
'no-undef': [2], // it is still needed by eslint & IDE to prompt undefined names in real time
|
||||
'no-undefined': [0],
|
||||
'no-underscore-dangle': [0],
|
||||
'no-unexpected-multiline': [2],
|
||||
'no-unmodified-loop-condition': [2],
|
||||
'no-unneeded-ternary': [2],
|
||||
'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-private-class-members': [2],
|
||||
'no-unused-vars': [0], // handled by @typescript-eslint/no-unused-vars
|
||||
'no-use-before-define': [2, {functions: false, classes: true, variables: true, allowNamedExports: true}],
|
||||
'no-use-extend-native/no-use-extend-native': [2],
|
||||
'no-useless-backreference': [2],
|
||||
'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-void': [2],
|
||||
'no-warning-comments': [0],
|
||||
'no-with': [0], // handled by no-restricted-syntax
|
||||
'object-shorthand': [2, 'always'],
|
||||
'one-var-declaration-per-line': [0],
|
||||
'one-var': [0],
|
||||
'operator-assignment': [2, 'always'],
|
||||
'operator-linebreak': [2, 'after'],
|
||||
'prefer-arrow-callback': [2, {allowNamedFunctions: true, allowUnboundThis: true}],
|
||||
'prefer-const': [2, {destructuring: 'all', ignoreReadBeforeAssign: true}],
|
||||
'prefer-destructuring': [0],
|
||||
'prefer-exponentiation-operator': [2],
|
||||
'prefer-named-capture-group': [0],
|
||||
'prefer-numeric-literals': [2],
|
||||
'prefer-object-has-own': [2],
|
||||
'prefer-object-spread': [2],
|
||||
'prefer-promise-reject-errors': [2, {allowEmptyReject: false}],
|
||||
'prefer-regex-literals': [2],
|
||||
'prefer-rest-params': [2],
|
||||
'prefer-spread': [2],
|
||||
'prefer-template': [2],
|
||||
'radix': [2, 'as-needed'],
|
||||
'regexp/confusing-quantifier': [2],
|
||||
'regexp/control-character-escape': [2],
|
||||
'regexp/hexadecimal-escape': [0],
|
||||
'regexp/letter-case': [0],
|
||||
'regexp/match-any': [2],
|
||||
'regexp/negation': [2],
|
||||
'regexp/no-contradiction-with-assertion': [0],
|
||||
'regexp/no-control-character': [0],
|
||||
'regexp/no-dupe-characters-character-class': [2],
|
||||
'regexp/no-dupe-disjunctions': [2],
|
||||
'regexp/no-empty-alternative': [2],
|
||||
'regexp/no-empty-capturing-group': [2],
|
||||
'regexp/no-empty-character-class': [0],
|
||||
'regexp/no-empty-group': [2],
|
||||
'regexp/no-empty-lookarounds-assertion': [2],
|
||||
'regexp/no-empty-string-literal': [2],
|
||||
'regexp/no-escape-backspace': [2],
|
||||
'regexp/no-extra-lookaround-assertions': [0],
|
||||
'regexp/no-invalid-regexp': [2],
|
||||
'regexp/no-invisible-character': [2],
|
||||
'regexp/no-lazy-ends': [2],
|
||||
'regexp/no-legacy-features': [2],
|
||||
'regexp/no-misleading-capturing-group': [0],
|
||||
'regexp/no-misleading-unicode-character': [0],
|
||||
'regexp/no-missing-g-flag': [2],
|
||||
'regexp/no-non-standard-flag': [2],
|
||||
'regexp/no-obscure-range': [2],
|
||||
'regexp/no-octal': [2],
|
||||
'regexp/no-optional-assertion': [2],
|
||||
'regexp/no-potentially-useless-backreference': [2],
|
||||
'regexp/no-standalone-backslash': [2],
|
||||
'regexp/no-super-linear-backtracking': [0],
|
||||
'regexp/no-super-linear-move': [0],
|
||||
'regexp/no-trivially-nested-assertion': [2],
|
||||
'regexp/no-trivially-nested-quantifier': [2],
|
||||
'regexp/no-unused-capturing-group': [0],
|
||||
'regexp/no-useless-assertions': [2],
|
||||
'regexp/no-useless-backreference': [2],
|
||||
'regexp/no-useless-character-class': [2],
|
||||
'regexp/no-useless-dollar-replacements': [2],
|
||||
'regexp/no-useless-escape': [2],
|
||||
'regexp/no-useless-flag': [2],
|
||||
'regexp/no-useless-lazy': [2],
|
||||
'regexp/no-useless-non-capturing-group': [2],
|
||||
'regexp/no-useless-quantifier': [2],
|
||||
'regexp/no-useless-range': [2],
|
||||
'regexp/no-useless-set-operand': [2],
|
||||
'regexp/no-useless-string-literal': [2],
|
||||
'regexp/no-useless-two-nums-quantifier': [2],
|
||||
'regexp/no-zero-quantifier': [2],
|
||||
'regexp/optimal-lookaround-quantifier': [2],
|
||||
'regexp/optimal-quantifier-concatenation': [0],
|
||||
'regexp/prefer-character-class': [0],
|
||||
'regexp/prefer-d': [0],
|
||||
'regexp/prefer-escape-replacement-dollar-char': [0],
|
||||
'regexp/prefer-lookaround': [0],
|
||||
'regexp/prefer-named-backreference': [0],
|
||||
'regexp/prefer-named-capture-group': [0],
|
||||
'regexp/prefer-named-replacement': [0],
|
||||
'regexp/prefer-plus-quantifier': [2],
|
||||
'regexp/prefer-predefined-assertion': [2],
|
||||
'regexp/prefer-quantifier': [0],
|
||||
'regexp/prefer-question-quantifier': [2],
|
||||
'regexp/prefer-range': [2],
|
||||
'regexp/prefer-regexp-exec': [2],
|
||||
'regexp/prefer-regexp-test': [2],
|
||||
'regexp/prefer-result-array-groups': [0],
|
||||
'regexp/prefer-set-operation': [2],
|
||||
'regexp/prefer-star-quantifier': [2],
|
||||
'regexp/prefer-unicode-codepoint-escapes': [2],
|
||||
'regexp/prefer-w': [0],
|
||||
'regexp/require-unicode-regexp': [0],
|
||||
'regexp/simplify-set-operations': [2],
|
||||
'regexp/sort-alternatives': [0],
|
||||
'regexp/sort-character-class-elements': [0],
|
||||
'regexp/sort-flags': [0],
|
||||
'regexp/strict': [2],
|
||||
'regexp/unicode-escape': [0],
|
||||
'regexp/use-ignore-case': [0],
|
||||
'require-atomic-updates': [0],
|
||||
'require-await': [0], // handled by @typescript-eslint/require-await
|
||||
'require-unicode-regexp': [0],
|
||||
'require-yield': [2],
|
||||
'sonarjs/cognitive-complexity': [0],
|
||||
'sonarjs/elseif-without-else': [0],
|
||||
'sonarjs/max-switch-cases': [0],
|
||||
'sonarjs/no-all-duplicated-branches': [2],
|
||||
'sonarjs/no-collapsible-if': [0],
|
||||
'sonarjs/no-collection-size-mischeck': [2],
|
||||
'sonarjs/no-duplicate-string': [0],
|
||||
'sonarjs/no-duplicated-branches': [0],
|
||||
'sonarjs/no-element-overwrite': [2],
|
||||
'sonarjs/no-empty-collection': [2],
|
||||
'sonarjs/no-extra-arguments': [2],
|
||||
'sonarjs/no-gratuitous-expressions': [2],
|
||||
'sonarjs/no-identical-conditions': [2],
|
||||
'sonarjs/no-identical-expressions': [2],
|
||||
'sonarjs/no-identical-functions': [2, 5],
|
||||
'sonarjs/no-ignored-return': [2],
|
||||
'sonarjs/no-inverted-boolean-check': [2],
|
||||
'sonarjs/no-nested-switch': [0],
|
||||
'sonarjs/no-nested-template-literals': [0],
|
||||
'sonarjs/no-one-iteration-loop': [2],
|
||||
'sonarjs/no-redundant-boolean': [2],
|
||||
'sonarjs/no-redundant-jump': [2],
|
||||
'sonarjs/no-same-line-conditional': [2],
|
||||
'sonarjs/no-small-switch': [0],
|
||||
'sonarjs/no-unused-collection': [2],
|
||||
'sonarjs/no-use-of-empty-return-value': [2],
|
||||
'sonarjs/no-useless-catch': [2],
|
||||
'sonarjs/non-existent-operator': [2],
|
||||
'sonarjs/prefer-immediate-return': [0],
|
||||
'sonarjs/prefer-object-literal': [0],
|
||||
'sonarjs/prefer-single-boolean-return': [0],
|
||||
'sonarjs/prefer-while': [2],
|
||||
'sort-imports': [0],
|
||||
'sort-keys': [0],
|
||||
'sort-vars': [0],
|
||||
'strict': [0],
|
||||
'symbol-description': [2],
|
||||
'unicode-bom': [2, 'never'],
|
||||
'unicorn/better-regex': [0],
|
||||
'unicorn/catch-error-name': [0],
|
||||
'unicorn/consistent-destructuring': [2],
|
||||
'unicorn/consistent-empty-array-spread': [2],
|
||||
'unicorn/consistent-existence-index-check': [0],
|
||||
'unicorn/consistent-function-scoping': [0],
|
||||
'unicorn/custom-error-definition': [0],
|
||||
'unicorn/empty-brace-spaces': [2],
|
||||
'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/import-style': [0],
|
||||
'unicorn/new-for-builtins': [2],
|
||||
'unicorn/no-abusive-eslint-disable': [0],
|
||||
'unicorn/no-anonymous-default-export': [0],
|
||||
'unicorn/no-array-callback-reference': [0],
|
||||
'unicorn/no-array-for-each': [2],
|
||||
'unicorn/no-array-method-this-argument': [2],
|
||||
'unicorn/no-array-push-push': [2],
|
||||
'unicorn/no-array-reduce': [2],
|
||||
'unicorn/no-await-expression-member': [0],
|
||||
'unicorn/no-await-in-promise-methods': [2],
|
||||
'unicorn/no-console-spaces': [0],
|
||||
'unicorn/no-document-cookie': [2],
|
||||
'unicorn/no-empty-file': [2],
|
||||
'unicorn/no-for-loop': [0],
|
||||
'unicorn/no-hex-escape': [0],
|
||||
'unicorn/no-instanceof-array': [0],
|
||||
'unicorn/no-invalid-fetch-options': [2],
|
||||
'unicorn/no-invalid-remove-event-listener': [2],
|
||||
'unicorn/no-keyword-prefix': [0],
|
||||
'unicorn/no-length-as-slice-end': [2],
|
||||
'unicorn/no-lonely-if': [2],
|
||||
'unicorn/no-magic-array-flat-depth': [0],
|
||||
'unicorn/no-negated-condition': [0],
|
||||
'unicorn/no-negation-in-equality-check': [2],
|
||||
'unicorn/no-nested-ternary': [0],
|
||||
'unicorn/no-new-array': [0],
|
||||
'unicorn/no-new-buffer': [0],
|
||||
'unicorn/no-null': [0],
|
||||
'unicorn/no-object-as-default-parameter': [0],
|
||||
'unicorn/no-process-exit': [0],
|
||||
'unicorn/no-single-promise-in-promise-methods': [2],
|
||||
'unicorn/no-static-only-class': [2],
|
||||
'unicorn/no-thenable': [2],
|
||||
'unicorn/no-this-assignment': [2],
|
||||
'unicorn/no-typeof-undefined': [2],
|
||||
'unicorn/no-unnecessary-await': [2],
|
||||
'unicorn/no-unnecessary-polyfills': [2],
|
||||
'unicorn/no-unreadable-array-destructuring': [0],
|
||||
'unicorn/no-unreadable-iife': [2],
|
||||
'unicorn/no-unused-properties': [2],
|
||||
'unicorn/no-useless-fallback-in-spread': [2],
|
||||
'unicorn/no-useless-length-check': [2],
|
||||
'unicorn/no-useless-promise-resolve-reject': [2],
|
||||
'unicorn/no-useless-spread': [2],
|
||||
'unicorn/no-useless-switch-case': [2],
|
||||
'unicorn/no-useless-undefined': [0],
|
||||
'unicorn/no-zero-fractions': [2],
|
||||
'unicorn/number-literal-case': [0],
|
||||
'unicorn/numeric-separators-style': [0],
|
||||
'unicorn/prefer-add-event-listener': [2],
|
||||
'unicorn/prefer-array-find': [2],
|
||||
'unicorn/prefer-array-flat-map': [2],
|
||||
'unicorn/prefer-array-flat': [2],
|
||||
'unicorn/prefer-array-index-of': [2],
|
||||
'unicorn/prefer-array-some': [2],
|
||||
'unicorn/prefer-at': [0],
|
||||
'unicorn/prefer-blob-reading-methods': [2],
|
||||
'unicorn/prefer-code-point': [0],
|
||||
'unicorn/prefer-date-now': [2],
|
||||
'unicorn/prefer-default-parameters': [0],
|
||||
'unicorn/prefer-dom-node-append': [2],
|
||||
'unicorn/prefer-dom-node-dataset': [0],
|
||||
'unicorn/prefer-dom-node-remove': [2],
|
||||
'unicorn/prefer-dom-node-text-content': [2],
|
||||
'unicorn/prefer-event-target': [2],
|
||||
'unicorn/prefer-export-from': [0],
|
||||
'unicorn/prefer-global-this': [0],
|
||||
'unicorn/prefer-includes': [2],
|
||||
'unicorn/prefer-json-parse-buffer': [0],
|
||||
'unicorn/prefer-keyboard-event-key': [2],
|
||||
'unicorn/prefer-logical-operator-over-ternary': [2],
|
||||
'unicorn/prefer-math-min-max': [2],
|
||||
'unicorn/prefer-math-trunc': [2],
|
||||
'unicorn/prefer-modern-dom-apis': [0],
|
||||
'unicorn/prefer-modern-math-apis': [2],
|
||||
'unicorn/prefer-module': [2],
|
||||
'unicorn/prefer-native-coercion-functions': [2],
|
||||
'unicorn/prefer-negative-index': [2],
|
||||
'unicorn/prefer-node-protocol': [2],
|
||||
'unicorn/prefer-number-properties': [0],
|
||||
'unicorn/prefer-object-from-entries': [2],
|
||||
'unicorn/prefer-object-has-own': [0],
|
||||
'unicorn/prefer-optional-catch-binding': [2],
|
||||
'unicorn/prefer-prototype-methods': [0],
|
||||
'unicorn/prefer-query-selector': [2],
|
||||
'unicorn/prefer-reflect-apply': [0],
|
||||
'unicorn/prefer-regexp-test': [2],
|
||||
'unicorn/prefer-set-has': [0],
|
||||
'unicorn/prefer-set-size': [2],
|
||||
'unicorn/prefer-spread': [0],
|
||||
'unicorn/prefer-string-raw': [0],
|
||||
'unicorn/prefer-string-replace-all': [0],
|
||||
'unicorn/prefer-string-slice': [0],
|
||||
'unicorn/prefer-string-starts-ends-with': [2],
|
||||
'unicorn/prefer-string-trim-start-end': [2],
|
||||
'unicorn/prefer-structured-clone': [2],
|
||||
'unicorn/prefer-switch': [0],
|
||||
'unicorn/prefer-ternary': [0],
|
||||
'unicorn/prefer-text-content': [2],
|
||||
'unicorn/prefer-top-level-await': [0],
|
||||
'unicorn/prefer-type-error': [0],
|
||||
'unicorn/prevent-abbreviations': [0],
|
||||
'unicorn/relative-url-style': [2],
|
||||
'unicorn/require-array-join-separator': [2],
|
||||
'unicorn/require-number-to-fixed-digits-argument': [2],
|
||||
'unicorn/require-post-message-target-origin': [0],
|
||||
'unicorn/string-content': [0],
|
||||
'unicorn/switch-case-braces': [0],
|
||||
'unicorn/template-indent': [2],
|
||||
'unicorn/text-encoding-identifier-case': [0],
|
||||
'unicorn/throw-new-error': [2],
|
||||
'use-isnan': [2],
|
||||
'valid-typeof': [2, {requireStringLiterals: true}],
|
||||
'vars-on-top': [0],
|
||||
'wc/attach-shadow-constructor': [2],
|
||||
'wc/define-tag-after-class-definition': [0],
|
||||
'wc/expose-class-on-global': [0],
|
||||
'wc/file-name-matches-element': [2],
|
||||
'wc/guard-define-call': [0],
|
||||
'wc/guard-super-call': [2],
|
||||
'wc/max-elements-per-file': [0],
|
||||
'wc/no-child-traversal-in-attributechangedcallback': [2],
|
||||
'wc/no-child-traversal-in-connectedcallback': [2],
|
||||
'wc/no-closed-shadow-root': [2],
|
||||
'wc/no-constructor-attributes': [2],
|
||||
'wc/no-constructor-params': [2],
|
||||
'wc/no-constructor': [2],
|
||||
'wc/no-customized-built-in-elements': [2],
|
||||
'wc/no-exports-with-element': [0],
|
||||
'wc/no-invalid-element-name': [2],
|
||||
'wc/no-invalid-extends': [2],
|
||||
'wc/no-method-prefixed-with-on': [2],
|
||||
'wc/no-self-class': [2],
|
||||
'wc/no-typos': [2],
|
||||
'wc/require-listener-teardown': [2],
|
||||
'wc/tag-name-matches-class': [2],
|
||||
'yoda': [2, 'never'],
|
||||
},
|
||||
};
|
967
.eslintrc.yaml
967
.eslintrc.yaml
@ -1,967 +0,0 @@
|
||||
root: true
|
||||
reportUnusedDisableDirectives: true
|
||||
|
||||
ignorePatterns:
|
||||
- /web_src/js/vendor
|
||||
- /web_src/fomantic
|
||||
- /public/assets/js
|
||||
|
||||
parser: "@typescript-eslint/parser"
|
||||
|
||||
parserOptions:
|
||||
sourceType: module
|
||||
ecmaVersion: latest
|
||||
project: true
|
||||
extraFileExtensions: [".vue"]
|
||||
parser: "@typescript-eslint/parser" # for vue plugin - https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
|
||||
|
||||
settings:
|
||||
import/extensions: [".js", ".ts"]
|
||||
import/parsers:
|
||||
"@typescript-eslint/parser": [".js", ".ts"]
|
||||
import/resolver:
|
||||
typescript: true
|
||||
|
||||
plugins:
|
||||
- "@eslint-community/eslint-plugin-eslint-comments"
|
||||
- "@stylistic/eslint-plugin-js"
|
||||
- "@typescript-eslint/eslint-plugin"
|
||||
- eslint-plugin-array-func
|
||||
- eslint-plugin-github
|
||||
- eslint-plugin-i
|
||||
- eslint-plugin-no-jquery
|
||||
- eslint-plugin-no-use-extend-native
|
||||
- eslint-plugin-regexp
|
||||
- eslint-plugin-sonarjs
|
||||
- eslint-plugin-unicorn
|
||||
- eslint-plugin-vitest
|
||||
- eslint-plugin-vitest-globals
|
||||
- eslint-plugin-wc
|
||||
|
||||
env:
|
||||
es2024: true
|
||||
node: true
|
||||
|
||||
overrides:
|
||||
- files: ["web_src/**/*"]
|
||||
globals:
|
||||
__webpack_public_path__: true
|
||||
process: false # https://github.com/webpack/webpack/issues/15833
|
||||
- files: ["web_src/**/*", "docs/**/*"]
|
||||
env:
|
||||
browser: true
|
||||
node: false
|
||||
- files: ["web_src/**/*worker.*"]
|
||||
env:
|
||||
worker: true
|
||||
rules:
|
||||
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, 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: ["*.config.*"]
|
||||
rules:
|
||||
i/no-unused-modules: [0]
|
||||
- files: ["**/*.d.ts"]
|
||||
rules:
|
||||
i/no-unused-modules: [0]
|
||||
"@typescript-eslint/consistent-type-definitions": [0]
|
||||
"@typescript-eslint/consistent-type-imports": [0]
|
||||
- files: ["web_src/js/types.ts"]
|
||||
rules:
|
||||
i/no-unused-modules: [0]
|
||||
- files: ["**/*.test.*", "web_src/js/test/setup.ts"]
|
||||
env:
|
||||
vitest-globals/env: true
|
||||
rules:
|
||||
vitest/consistent-test-filename: [0]
|
||||
vitest/consistent-test-it: [0]
|
||||
vitest/expect-expect: [0]
|
||||
vitest/max-expects: [0]
|
||||
vitest/max-nested-describe: [0]
|
||||
vitest/no-alias-methods: [0]
|
||||
vitest/no-commented-out-tests: [0]
|
||||
vitest/no-conditional-expect: [0]
|
||||
vitest/no-conditional-in-test: [0]
|
||||
vitest/no-conditional-tests: [0]
|
||||
vitest/no-disabled-tests: [0]
|
||||
vitest/no-done-callback: [0]
|
||||
vitest/no-duplicate-hooks: [0]
|
||||
vitest/no-focused-tests: [0]
|
||||
vitest/no-hooks: [0]
|
||||
vitest/no-identical-title: [2]
|
||||
vitest/no-interpolation-in-snapshots: [0]
|
||||
vitest/no-large-snapshots: [0]
|
||||
vitest/no-mocks-import: [0]
|
||||
vitest/no-restricted-matchers: [0]
|
||||
vitest/no-restricted-vi-methods: [0]
|
||||
vitest/no-standalone-expect: [0]
|
||||
vitest/no-test-prefixes: [0]
|
||||
vitest/no-test-return-statement: [0]
|
||||
vitest/prefer-called-with: [0]
|
||||
vitest/prefer-comparison-matcher: [0]
|
||||
vitest/prefer-each: [0]
|
||||
vitest/prefer-equality-matcher: [0]
|
||||
vitest/prefer-expect-resolves: [0]
|
||||
vitest/prefer-hooks-in-order: [0]
|
||||
vitest/prefer-hooks-on-top: [2]
|
||||
vitest/prefer-lowercase-title: [0]
|
||||
vitest/prefer-mock-promise-shorthand: [0]
|
||||
vitest/prefer-snapshot-hint: [0]
|
||||
vitest/prefer-spy-on: [0]
|
||||
vitest/prefer-strict-equal: [0]
|
||||
vitest/prefer-to-be: [0]
|
||||
vitest/prefer-to-be-falsy: [0]
|
||||
vitest/prefer-to-be-object: [0]
|
||||
vitest/prefer-to-be-truthy: [0]
|
||||
vitest/prefer-to-contain: [0]
|
||||
vitest/prefer-to-have-length: [0]
|
||||
vitest/prefer-todo: [0]
|
||||
vitest/require-hook: [0]
|
||||
vitest/require-to-throw-message: [0]
|
||||
vitest/require-top-level-describe: [0]
|
||||
vitest/valid-describe-callback: [2]
|
||||
vitest/valid-expect: [2]
|
||||
vitest/valid-title: [2]
|
||||
- files: ["web_src/js/modules/fetch.ts", "web_src/js/standalone/**/*"]
|
||||
rules:
|
||||
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression]
|
||||
- files: ["**/*.vue"]
|
||||
plugins:
|
||||
- eslint-plugin-vue
|
||||
- eslint-plugin-vue-scoped-css
|
||||
extends:
|
||||
- plugin:vue/vue3-recommended
|
||||
- plugin:vue-scoped-css/vue3-recommended
|
||||
rules:
|
||||
vue/attributes-order: [0]
|
||||
vue/html-closing-bracket-spacing: [2, {startTag: never, endTag: never, selfClosingTag: never}]
|
||||
vue/max-attributes-per-line: [0]
|
||||
vue/singleline-html-element-content-newline: [0]
|
||||
- files: ["tests/e2e/**"]
|
||||
plugins:
|
||||
- eslint-plugin-playwright
|
||||
extends: plugin:playwright/recommended
|
||||
|
||||
rules:
|
||||
"@eslint-community/eslint-comments/disable-enable-pair": [2]
|
||||
"@eslint-community/eslint-comments/no-aggregating-enable": [2]
|
||||
"@eslint-community/eslint-comments/no-duplicate-disable": [2]
|
||||
"@eslint-community/eslint-comments/no-restricted-disable": [0]
|
||||
"@eslint-community/eslint-comments/no-unlimited-disable": [2]
|
||||
"@eslint-community/eslint-comments/no-unused-disable": [2]
|
||||
"@eslint-community/eslint-comments/no-unused-enable": [2]
|
||||
"@eslint-community/eslint-comments/no-use": [0]
|
||||
"@eslint-community/eslint-comments/require-description": [0]
|
||||
"@stylistic/js/array-bracket-newline": [0]
|
||||
"@stylistic/js/array-bracket-spacing": [2, never]
|
||||
"@stylistic/js/array-element-newline": [0]
|
||||
"@stylistic/js/arrow-parens": [2, always]
|
||||
"@stylistic/js/arrow-spacing": [2, {before: true, after: true}]
|
||||
"@stylistic/js/block-spacing": [0]
|
||||
"@stylistic/js/brace-style": [2, 1tbs, {allowSingleLine: true}]
|
||||
"@stylistic/js/comma-dangle": [2, always-multiline]
|
||||
"@stylistic/js/comma-spacing": [2, {before: false, after: true}]
|
||||
"@stylistic/js/comma-style": [2, last]
|
||||
"@stylistic/js/computed-property-spacing": [2, never]
|
||||
"@stylistic/js/dot-location": [2, property]
|
||||
"@stylistic/js/eol-last": [2]
|
||||
"@stylistic/js/function-call-argument-newline": [0]
|
||||
"@stylistic/js/function-call-spacing": [2, never]
|
||||
"@stylistic/js/function-paren-newline": [0]
|
||||
"@stylistic/js/generator-star-spacing": [0]
|
||||
"@stylistic/js/implicit-arrow-linebreak": [0]
|
||||
"@stylistic/js/indent": [2, 2, {ignoreComments: true, SwitchCase: 1}]
|
||||
"@stylistic/js/key-spacing": [2]
|
||||
"@stylistic/js/keyword-spacing": [2]
|
||||
"@stylistic/js/line-comment-position": [0]
|
||||
"@stylistic/js/linebreak-style": [2, unix]
|
||||
"@stylistic/js/lines-around-comment": [0]
|
||||
"@stylistic/js/lines-between-class-members": [0]
|
||||
"@stylistic/js/max-len": [0]
|
||||
"@stylistic/js/max-statements-per-line": [0]
|
||||
"@stylistic/js/multiline-comment-style": [0]
|
||||
"@stylistic/js/multiline-ternary": [0]
|
||||
"@stylistic/js/new-parens": [2]
|
||||
"@stylistic/js/newline-per-chained-call": [0]
|
||||
"@stylistic/js/no-confusing-arrow": [0]
|
||||
"@stylistic/js/no-extra-parens": [0]
|
||||
"@stylistic/js/no-extra-semi": [2]
|
||||
"@stylistic/js/no-floating-decimal": [0]
|
||||
"@stylistic/js/no-mixed-operators": [0]
|
||||
"@stylistic/js/no-mixed-spaces-and-tabs": [2]
|
||||
"@stylistic/js/no-multi-spaces": [2, {ignoreEOLComments: true, exceptions: {Property: true}}]
|
||||
"@stylistic/js/no-multiple-empty-lines": [2, {max: 1, maxEOF: 0, maxBOF: 0}]
|
||||
"@stylistic/js/no-tabs": [2]
|
||||
"@stylistic/js/no-trailing-spaces": [2]
|
||||
"@stylistic/js/no-whitespace-before-property": [2]
|
||||
"@stylistic/js/nonblock-statement-body-position": [2]
|
||||
"@stylistic/js/object-curly-newline": [0]
|
||||
"@stylistic/js/object-curly-spacing": [2, never]
|
||||
"@stylistic/js/object-property-newline": [0]
|
||||
"@stylistic/js/one-var-declaration-per-line": [0]
|
||||
"@stylistic/js/operator-linebreak": [2, after]
|
||||
"@stylistic/js/padded-blocks": [2, never]
|
||||
"@stylistic/js/padding-line-between-statements": [0]
|
||||
"@stylistic/js/quote-props": [0]
|
||||
"@stylistic/js/quotes": [2, single, {avoidEscape: true, allowTemplateLiterals: true}]
|
||||
"@stylistic/js/rest-spread-spacing": [2, never]
|
||||
"@stylistic/js/semi": [2, always, {omitLastInOneLineBlock: true}]
|
||||
"@stylistic/js/semi-spacing": [2, {before: false, after: true}]
|
||||
"@stylistic/js/semi-style": [2, last]
|
||||
"@stylistic/js/space-before-blocks": [2, always]
|
||||
"@stylistic/js/space-before-function-paren": [2, {anonymous: ignore, named: never, asyncArrow: always}]
|
||||
"@stylistic/js/space-in-parens": [2, never]
|
||||
"@stylistic/js/space-infix-ops": [2]
|
||||
"@stylistic/js/space-unary-ops": [2]
|
||||
"@stylistic/js/spaced-comment": [2, always]
|
||||
"@stylistic/js/switch-colon-spacing": [2]
|
||||
"@stylistic/js/template-curly-spacing": [2, never]
|
||||
"@stylistic/js/template-tag-spacing": [2, never]
|
||||
"@stylistic/js/wrap-iife": [2, inside]
|
||||
"@stylistic/js/wrap-regex": [0]
|
||||
"@stylistic/js/yield-star-spacing": [2, after]
|
||||
"@typescript-eslint/adjacent-overload-signatures": [0]
|
||||
"@typescript-eslint/array-type": [0]
|
||||
"@typescript-eslint/await-thenable": [2]
|
||||
"@typescript-eslint/ban-ts-comment": [2, {'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': false, 'ts-check': false}]
|
||||
"@typescript-eslint/ban-tslint-comment": [0]
|
||||
"@typescript-eslint/class-literal-property-style": [0]
|
||||
"@typescript-eslint/class-methods-use-this": [0]
|
||||
"@typescript-eslint/consistent-generic-constructors": [0]
|
||||
"@typescript-eslint/consistent-indexed-object-style": [0]
|
||||
"@typescript-eslint/consistent-return": [0]
|
||||
"@typescript-eslint/consistent-type-assertions": [2, {assertionStyle: as, objectLiteralTypeAssertions: allow}]
|
||||
"@typescript-eslint/consistent-type-definitions": [2, type]
|
||||
"@typescript-eslint/consistent-type-exports": [2, {fixMixedExportsWithInlineTypeSpecifier: false}]
|
||||
"@typescript-eslint/consistent-type-imports": [2, {prefer: type-imports, fixStyle: separate-type-imports, disallowTypeAnnotations: true}]
|
||||
"@typescript-eslint/default-param-last": [0]
|
||||
"@typescript-eslint/dot-notation": [0]
|
||||
"@typescript-eslint/explicit-function-return-type": [0]
|
||||
"@typescript-eslint/explicit-member-accessibility": [0]
|
||||
"@typescript-eslint/explicit-module-boundary-types": [0]
|
||||
"@typescript-eslint/init-declarations": [0]
|
||||
"@typescript-eslint/max-params": [0]
|
||||
"@typescript-eslint/member-ordering": [0]
|
||||
"@typescript-eslint/method-signature-style": [0]
|
||||
"@typescript-eslint/naming-convention": [0]
|
||||
"@typescript-eslint/no-array-constructor": [2]
|
||||
"@typescript-eslint/no-array-delete": [2]
|
||||
"@typescript-eslint/no-base-to-string": [0]
|
||||
"@typescript-eslint/no-confusing-non-null-assertion": [2]
|
||||
"@typescript-eslint/no-confusing-void-expression": [0]
|
||||
"@typescript-eslint/no-deprecated": [2]
|
||||
"@typescript-eslint/no-dupe-class-members": [0]
|
||||
"@typescript-eslint/no-duplicate-enum-values": [2]
|
||||
"@typescript-eslint/no-duplicate-type-constituents": [2, {ignoreUnions: true}]
|
||||
"@typescript-eslint/no-dynamic-delete": [0]
|
||||
"@typescript-eslint/no-empty-function": [0]
|
||||
"@typescript-eslint/no-empty-interface": [0]
|
||||
"@typescript-eslint/no-empty-object-type": [2]
|
||||
"@typescript-eslint/no-explicit-any": [0]
|
||||
"@typescript-eslint/no-extra-non-null-assertion": [2]
|
||||
"@typescript-eslint/no-extraneous-class": [0]
|
||||
"@typescript-eslint/no-floating-promises": [0]
|
||||
"@typescript-eslint/no-for-in-array": [2]
|
||||
"@typescript-eslint/no-implied-eval": [2]
|
||||
"@typescript-eslint/no-import-type-side-effects": [0] # dupe with consistent-type-imports
|
||||
"@typescript-eslint/no-inferrable-types": [0]
|
||||
"@typescript-eslint/no-invalid-this": [0]
|
||||
"@typescript-eslint/no-invalid-void-type": [0]
|
||||
"@typescript-eslint/no-loop-func": [0]
|
||||
"@typescript-eslint/no-loss-of-precision": [0]
|
||||
"@typescript-eslint/no-magic-numbers": [0]
|
||||
"@typescript-eslint/no-meaningless-void-operator": [0]
|
||||
"@typescript-eslint/no-misused-new": [2]
|
||||
"@typescript-eslint/no-misused-promises": [2, {checksVoidReturn: {attributes: false, arguments: false}}]
|
||||
"@typescript-eslint/no-mixed-enums": [0]
|
||||
"@typescript-eslint/no-namespace": [2]
|
||||
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": [0]
|
||||
"@typescript-eslint/no-non-null-asserted-optional-chain": [2]
|
||||
"@typescript-eslint/no-non-null-assertion": [0]
|
||||
"@typescript-eslint/no-redeclare": [0]
|
||||
"@typescript-eslint/no-redundant-type-constituents": [2]
|
||||
"@typescript-eslint/no-require-imports": [2]
|
||||
"@typescript-eslint/no-restricted-imports": [0]
|
||||
"@typescript-eslint/no-restricted-types": [0]
|
||||
"@typescript-eslint/no-shadow": [0]
|
||||
"@typescript-eslint/no-this-alias": [0] # handled by unicorn/no-this-assignment
|
||||
"@typescript-eslint/no-unnecessary-boolean-literal-compare": [0]
|
||||
"@typescript-eslint/no-unnecessary-condition": [0]
|
||||
"@typescript-eslint/no-unnecessary-qualifier": [0]
|
||||
"@typescript-eslint/no-unnecessary-template-expression": [0]
|
||||
"@typescript-eslint/no-unnecessary-type-arguments": [0]
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": [2]
|
||||
"@typescript-eslint/no-unnecessary-type-constraint": [2]
|
||||
"@typescript-eslint/no-unsafe-argument": [0]
|
||||
"@typescript-eslint/no-unsafe-assignment": [0]
|
||||
"@typescript-eslint/no-unsafe-call": [0]
|
||||
"@typescript-eslint/no-unsafe-declaration-merging": [2]
|
||||
"@typescript-eslint/no-unsafe-enum-comparison": [2]
|
||||
"@typescript-eslint/no-unsafe-function-type": [2]
|
||||
"@typescript-eslint/no-unsafe-member-access": [0]
|
||||
"@typescript-eslint/no-unsafe-return": [0]
|
||||
"@typescript-eslint/no-unsafe-unary-minus": [2]
|
||||
"@typescript-eslint/no-unused-expressions": [0]
|
||||
"@typescript-eslint/no-unused-vars": [2, {vars: all, args: all, caughtErrors: all, ignoreRestSiblings: false, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_}]
|
||||
"@typescript-eslint/no-use-before-define": [0]
|
||||
"@typescript-eslint/no-useless-constructor": [0]
|
||||
"@typescript-eslint/no-useless-empty-export": [0]
|
||||
"@typescript-eslint/no-wrapper-object-types": [2]
|
||||
"@typescript-eslint/non-nullable-type-assertion-style": [0]
|
||||
"@typescript-eslint/only-throw-error": [2]
|
||||
"@typescript-eslint/parameter-properties": [0]
|
||||
"@typescript-eslint/prefer-as-const": [2]
|
||||
"@typescript-eslint/prefer-destructuring": [0]
|
||||
"@typescript-eslint/prefer-enum-initializers": [0]
|
||||
"@typescript-eslint/prefer-find": [2]
|
||||
"@typescript-eslint/prefer-for-of": [2]
|
||||
"@typescript-eslint/prefer-function-type": [2]
|
||||
"@typescript-eslint/prefer-includes": [2]
|
||||
"@typescript-eslint/prefer-literal-enum-member": [0]
|
||||
"@typescript-eslint/prefer-namespace-keyword": [0]
|
||||
"@typescript-eslint/prefer-nullish-coalescing": [0]
|
||||
"@typescript-eslint/prefer-optional-chain": [2, {requireNullish: true}]
|
||||
"@typescript-eslint/prefer-promise-reject-errors": [0]
|
||||
"@typescript-eslint/prefer-readonly": [0]
|
||||
"@typescript-eslint/prefer-readonly-parameter-types": [0]
|
||||
"@typescript-eslint/prefer-reduce-type-parameter": [0]
|
||||
"@typescript-eslint/prefer-regexp-exec": [0]
|
||||
"@typescript-eslint/prefer-return-this-type": [0]
|
||||
"@typescript-eslint/prefer-string-starts-ends-with": [2, {allowSingleElementEquality: always}]
|
||||
"@typescript-eslint/promise-function-async": [0]
|
||||
"@typescript-eslint/require-array-sort-compare": [0]
|
||||
"@typescript-eslint/require-await": [0]
|
||||
"@typescript-eslint/restrict-plus-operands": [2]
|
||||
"@typescript-eslint/restrict-template-expressions": [0]
|
||||
"@typescript-eslint/return-await": [0]
|
||||
"@typescript-eslint/strict-boolean-expressions": [0]
|
||||
"@typescript-eslint/switch-exhaustiveness-check": [0]
|
||||
"@typescript-eslint/triple-slash-reference": [2]
|
||||
"@typescript-eslint/typedef": [0]
|
||||
"@typescript-eslint/unbound-method": [0] # too many false-positives
|
||||
"@typescript-eslint/unified-signatures": [2]
|
||||
accessor-pairs: [2]
|
||||
array-callback-return: [2, {checkForEach: true}]
|
||||
array-func/avoid-reverse: [2]
|
||||
array-func/from-map: [2]
|
||||
array-func/no-unnecessary-this-arg: [2]
|
||||
array-func/prefer-array-from: [2]
|
||||
array-func/prefer-flat-map: [0] # handled by unicorn/prefer-array-flat-map
|
||||
array-func/prefer-flat: [0] # handled by unicorn/prefer-array-flat
|
||||
arrow-body-style: [0]
|
||||
block-scoped-var: [2]
|
||||
camelcase: [0]
|
||||
capitalized-comments: [0]
|
||||
class-methods-use-this: [0]
|
||||
complexity: [0]
|
||||
consistent-return: [0]
|
||||
consistent-this: [0]
|
||||
constructor-super: [2]
|
||||
curly: [0]
|
||||
default-case-last: [2]
|
||||
default-case: [0]
|
||||
default-param-last: [0]
|
||||
dot-notation: [0]
|
||||
eqeqeq: [2]
|
||||
for-direction: [2]
|
||||
func-name-matching: [2]
|
||||
func-names: [0]
|
||||
func-style: [0]
|
||||
getter-return: [2]
|
||||
github/a11y-aria-label-is-well-formatted: [0]
|
||||
github/a11y-no-title-attribute: [0]
|
||||
github/a11y-no-visually-hidden-interactive-element: [0]
|
||||
github/a11y-role-supports-aria-props: [0]
|
||||
github/a11y-svg-has-accessible-name: [0]
|
||||
github/array-foreach: [0]
|
||||
github/async-currenttarget: [2]
|
||||
github/async-preventdefault: [2]
|
||||
github/authenticity-token: [0]
|
||||
github/get-attribute: [0]
|
||||
github/js-class-name: [0]
|
||||
github/no-blur: [0]
|
||||
github/no-d-none: [0]
|
||||
github/no-dataset: [2]
|
||||
github/no-dynamic-script-tag: [2]
|
||||
github/no-implicit-buggy-globals: [2]
|
||||
github/no-inner-html: [0]
|
||||
github/no-innerText: [2]
|
||||
github/no-then: [2]
|
||||
github/no-useless-passive: [2]
|
||||
github/prefer-observers: [2]
|
||||
github/require-passive-events: [2]
|
||||
github/unescaped-html-literal: [0]
|
||||
grouped-accessor-pairs: [2]
|
||||
guard-for-in: [0]
|
||||
id-blacklist: [0]
|
||||
id-length: [0]
|
||||
id-match: [0]
|
||||
i/consistent-type-specifier-style: [0]
|
||||
i/default: [0]
|
||||
i/dynamic-import-chunkname: [0]
|
||||
i/export: [2]
|
||||
i/exports-last: [0]
|
||||
i/extensions: [2, always, {ignorePackages: true}]
|
||||
i/first: [2]
|
||||
i/group-exports: [0]
|
||||
i/max-dependencies: [0]
|
||||
i/named: [2]
|
||||
i/namespace: [0]
|
||||
i/newline-after-import: [0]
|
||||
i/no-absolute-path: [0]
|
||||
i/no-amd: [2]
|
||||
i/no-anonymous-default-export: [0]
|
||||
i/no-commonjs: [2]
|
||||
i/no-cycle: [2, {ignoreExternal: true, maxDepth: 1}]
|
||||
i/no-default-export: [0]
|
||||
i/no-deprecated: [0]
|
||||
i/no-dynamic-require: [0]
|
||||
i/no-empty-named-blocks: [2]
|
||||
i/no-extraneous-dependencies: [2]
|
||||
i/no-import-module-exports: [0]
|
||||
i/no-internal-modules: [0]
|
||||
i/no-mutable-exports: [0]
|
||||
i/no-named-as-default-member: [0]
|
||||
i/no-named-as-default: [0]
|
||||
i/no-named-default: [0]
|
||||
i/no-named-export: [0]
|
||||
i/no-namespace: [0]
|
||||
i/no-nodejs-modules: [0]
|
||||
i/no-relative-packages: [0]
|
||||
i/no-relative-parent-imports: [0]
|
||||
i/no-restricted-paths: [0]
|
||||
i/no-self-import: [2]
|
||||
i/no-unassigned-import: [0]
|
||||
i/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$"]}]
|
||||
i/no-unused-modules: [2, {unusedExports: true}]
|
||||
i/no-useless-path-segments: [2, {commonjs: true}]
|
||||
i/no-webpack-loader-syntax: [2]
|
||||
i/order: [0]
|
||||
i/prefer-default-export: [0]
|
||||
i/unambiguous: [0]
|
||||
init-declarations: [0]
|
||||
line-comment-position: [0]
|
||||
logical-assignment-operators: [0]
|
||||
max-classes-per-file: [0]
|
||||
max-depth: [0]
|
||||
max-lines-per-function: [0]
|
||||
max-lines: [0]
|
||||
max-nested-callbacks: [0]
|
||||
max-params: [0]
|
||||
max-statements: [0]
|
||||
multiline-comment-style: [2, separate-lines]
|
||||
new-cap: [0]
|
||||
no-alert: [0]
|
||||
no-array-constructor: [0] # handled by @typescript-eslint/no-array-constructor
|
||||
no-async-promise-executor: [0]
|
||||
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-console: [1, {allow: [debug, info, warn, error]}]
|
||||
no-const-assign: [2]
|
||||
no-constant-binary-expression: [2]
|
||||
no-constant-condition: [0]
|
||||
no-constructor-return: [2]
|
||||
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: [0]
|
||||
no-else-return: [2]
|
||||
no-empty-character-class: [2]
|
||||
no-empty-function: [0]
|
||||
no-empty-pattern: [2]
|
||||
no-empty-static-block: [2]
|
||||
no-empty: [2, {allowEmptyCatch: true}]
|
||||
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-fallthrough: [2]
|
||||
no-func-assign: [2]
|
||||
no-global-assign: [2]
|
||||
no-implicit-coercion: [2]
|
||||
no-implicit-globals: [0]
|
||||
no-implied-eval: [0] # handled by @typescript-eslint/no-implied-eval
|
||||
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-jquery/no-ajax-events: [2]
|
||||
no-jquery/no-ajax: [2]
|
||||
no-jquery/no-and-self: [2]
|
||||
no-jquery/no-animate-toggle: [2]
|
||||
no-jquery/no-animate: [2]
|
||||
no-jquery/no-append-html: [2]
|
||||
no-jquery/no-attr: [2]
|
||||
no-jquery/no-bind: [2]
|
||||
no-jquery/no-box-model: [2]
|
||||
no-jquery/no-browser: [2]
|
||||
no-jquery/no-camel-case: [2]
|
||||
no-jquery/no-class-state: [2]
|
||||
no-jquery/no-class: [0]
|
||||
no-jquery/no-clone: [2]
|
||||
no-jquery/no-closest: [0]
|
||||
no-jquery/no-constructor-attributes: [2]
|
||||
no-jquery/no-contains: [2]
|
||||
no-jquery/no-context-prop: [2]
|
||||
no-jquery/no-css: [2]
|
||||
no-jquery/no-data: [0]
|
||||
no-jquery/no-deferred: [2]
|
||||
no-jquery/no-delegate: [2]
|
||||
no-jquery/no-done-fail: [2]
|
||||
no-jquery/no-each-collection: [0]
|
||||
no-jquery/no-each-util: [0]
|
||||
no-jquery/no-each: [0]
|
||||
no-jquery/no-error-shorthand: [2]
|
||||
no-jquery/no-error: [2]
|
||||
no-jquery/no-escape-selector: [2]
|
||||
no-jquery/no-event-shorthand: [2]
|
||||
no-jquery/no-extend: [2]
|
||||
no-jquery/no-fade: [2]
|
||||
no-jquery/no-filter: [0]
|
||||
no-jquery/no-find-collection: [0]
|
||||
no-jquery/no-find-util: [2]
|
||||
no-jquery/no-find: [0]
|
||||
no-jquery/no-fx-interval: [2]
|
||||
no-jquery/no-fx: [2]
|
||||
no-jquery/no-global-eval: [2]
|
||||
no-jquery/no-global-selector: [0]
|
||||
no-jquery/no-grep: [2]
|
||||
no-jquery/no-has: [2]
|
||||
no-jquery/no-hold-ready: [2]
|
||||
no-jquery/no-html: [0]
|
||||
no-jquery/no-in-array: [2]
|
||||
no-jquery/no-is-array: [2]
|
||||
no-jquery/no-is-empty-object: [2]
|
||||
no-jquery/no-is-function: [2]
|
||||
no-jquery/no-is-numeric: [2]
|
||||
no-jquery/no-is-plain-object: [2]
|
||||
no-jquery/no-is-window: [2]
|
||||
no-jquery/no-is: [2]
|
||||
no-jquery/no-jquery-constructor: [0]
|
||||
no-jquery/no-live: [2]
|
||||
no-jquery/no-load-shorthand: [2]
|
||||
no-jquery/no-load: [2]
|
||||
no-jquery/no-map-collection: [0]
|
||||
no-jquery/no-map-util: [2]
|
||||
no-jquery/no-map: [2]
|
||||
no-jquery/no-merge: [2]
|
||||
no-jquery/no-node-name: [2]
|
||||
no-jquery/no-noop: [2]
|
||||
no-jquery/no-now: [2]
|
||||
no-jquery/no-on-ready: [2]
|
||||
no-jquery/no-other-methods: [0]
|
||||
no-jquery/no-other-utils: [2]
|
||||
no-jquery/no-param: [2]
|
||||
no-jquery/no-parent: [0]
|
||||
no-jquery/no-parents: [2]
|
||||
no-jquery/no-parse-html-literal: [2]
|
||||
no-jquery/no-parse-html: [2]
|
||||
no-jquery/no-parse-json: [2]
|
||||
no-jquery/no-parse-xml: [2]
|
||||
no-jquery/no-prop: [2]
|
||||
no-jquery/no-proxy: [2]
|
||||
no-jquery/no-ready-shorthand: [2]
|
||||
no-jquery/no-ready: [2]
|
||||
no-jquery/no-selector-prop: [2]
|
||||
no-jquery/no-serialize: [2]
|
||||
no-jquery/no-size: [2]
|
||||
no-jquery/no-sizzle: [2]
|
||||
no-jquery/no-slide: [2]
|
||||
no-jquery/no-sub: [2]
|
||||
no-jquery/no-support: [2]
|
||||
no-jquery/no-text: [2]
|
||||
no-jquery/no-trigger: [0]
|
||||
no-jquery/no-trim: [2]
|
||||
no-jquery/no-type: [2]
|
||||
no-jquery/no-unique: [2]
|
||||
no-jquery/no-unload-shorthand: [2]
|
||||
no-jquery/no-val: [0]
|
||||
no-jquery/no-visibility: [2]
|
||||
no-jquery/no-when: [2]
|
||||
no-jquery/no-wrap: [2]
|
||||
no-jquery/variable-pattern: [2]
|
||||
no-label-var: [2]
|
||||
no-labels: [0] # handled by no-restricted-syntax
|
||||
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-multi-assign: [0]
|
||||
no-multi-str: [2]
|
||||
no-negated-condition: [0]
|
||||
no-nested-ternary: [0]
|
||||
no-new-func: [2]
|
||||
no-new-native-nonconstructor: [2]
|
||||
no-new-object: [2]
|
||||
no-new-symbol: [2]
|
||||
no-new-wrappers: [2]
|
||||
no-new: [0]
|
||||
no-nonoctal-decimal-escape: [2]
|
||||
no-obj-calls: [2]
|
||||
no-octal-escape: [2]
|
||||
no-octal: [2]
|
||||
no-param-reassign: [0]
|
||||
no-plusplus: [0]
|
||||
no-promise-executor-return: [0]
|
||||
no-proto: [2]
|
||||
no-prototype-builtins: [2]
|
||||
no-redeclare: [0] # must be disabled for typescript overloads
|
||||
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, __dirname, __filename]
|
||||
no-restricted-imports: [0]
|
||||
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression, {selector: "CallExpression[callee.name='fetch']", message: "use modules/fetch.ts instead"}]
|
||||
no-return-assign: [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-sparse-arrays: [2]
|
||||
no-template-curly-in-string: [2]
|
||||
no-ternary: [0]
|
||||
no-this-before-super: [2]
|
||||
no-throw-literal: [2]
|
||||
no-undef-init: [2]
|
||||
no-undef: [2, {typeof: true}] # TODO: disable this rule after tsc passes
|
||||
no-undefined: [0]
|
||||
no-underscore-dangle: [0]
|
||||
no-unexpected-multiline: [2]
|
||||
no-unmodified-loop-condition: [2]
|
||||
no-unneeded-ternary: [2]
|
||||
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-private-class-members: [2]
|
||||
no-unused-vars: [0] # handled by @typescript-eslint/no-unused-vars
|
||||
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
|
||||
no-use-extend-native/no-use-extend-native: [2]
|
||||
no-useless-backreference: [2]
|
||||
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-void: [2]
|
||||
no-warning-comments: [0]
|
||||
no-with: [0] # handled by no-restricted-syntax
|
||||
object-shorthand: [2, always]
|
||||
one-var-declaration-per-line: [0]
|
||||
one-var: [0]
|
||||
operator-assignment: [2, always]
|
||||
operator-linebreak: [2, after]
|
||||
prefer-arrow-callback: [2, {allowNamedFunctions: true, allowUnboundThis: true}]
|
||||
prefer-const: [2, {destructuring: all, ignoreReadBeforeAssign: true}]
|
||||
prefer-destructuring: [0]
|
||||
prefer-exponentiation-operator: [2]
|
||||
prefer-named-capture-group: [0]
|
||||
prefer-numeric-literals: [2]
|
||||
prefer-object-has-own: [2]
|
||||
prefer-object-spread: [2]
|
||||
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
|
||||
prefer-regex-literals: [2]
|
||||
prefer-rest-params: [2]
|
||||
prefer-spread: [2]
|
||||
prefer-template: [2]
|
||||
radix: [2, as-needed]
|
||||
regexp/confusing-quantifier: [2]
|
||||
regexp/control-character-escape: [2]
|
||||
regexp/hexadecimal-escape: [0]
|
||||
regexp/letter-case: [0]
|
||||
regexp/match-any: [2]
|
||||
regexp/negation: [2]
|
||||
regexp/no-contradiction-with-assertion: [0]
|
||||
regexp/no-control-character: [0]
|
||||
regexp/no-dupe-characters-character-class: [2]
|
||||
regexp/no-dupe-disjunctions: [2]
|
||||
regexp/no-empty-alternative: [2]
|
||||
regexp/no-empty-capturing-group: [2]
|
||||
regexp/no-empty-character-class: [0]
|
||||
regexp/no-empty-group: [2]
|
||||
regexp/no-empty-lookarounds-assertion: [2]
|
||||
regexp/no-empty-string-literal: [2]
|
||||
regexp/no-escape-backspace: [2]
|
||||
regexp/no-extra-lookaround-assertions: [0]
|
||||
regexp/no-invalid-regexp: [2]
|
||||
regexp/no-invisible-character: [2]
|
||||
regexp/no-lazy-ends: [2]
|
||||
regexp/no-legacy-features: [2]
|
||||
regexp/no-misleading-capturing-group: [0]
|
||||
regexp/no-misleading-unicode-character: [0]
|
||||
regexp/no-missing-g-flag: [2]
|
||||
regexp/no-non-standard-flag: [2]
|
||||
regexp/no-obscure-range: [2]
|
||||
regexp/no-octal: [2]
|
||||
regexp/no-optional-assertion: [2]
|
||||
regexp/no-potentially-useless-backreference: [2]
|
||||
regexp/no-standalone-backslash: [2]
|
||||
regexp/no-super-linear-backtracking: [0]
|
||||
regexp/no-super-linear-move: [0]
|
||||
regexp/no-trivially-nested-assertion: [2]
|
||||
regexp/no-trivially-nested-quantifier: [2]
|
||||
regexp/no-unused-capturing-group: [0]
|
||||
regexp/no-useless-assertions: [2]
|
||||
regexp/no-useless-backreference: [2]
|
||||
regexp/no-useless-character-class: [2]
|
||||
regexp/no-useless-dollar-replacements: [2]
|
||||
regexp/no-useless-escape: [2]
|
||||
regexp/no-useless-flag: [2]
|
||||
regexp/no-useless-lazy: [2]
|
||||
regexp/no-useless-non-capturing-group: [2]
|
||||
regexp/no-useless-quantifier: [2]
|
||||
regexp/no-useless-range: [2]
|
||||
regexp/no-useless-set-operand: [2]
|
||||
regexp/no-useless-string-literal: [2]
|
||||
regexp/no-useless-two-nums-quantifier: [2]
|
||||
regexp/no-zero-quantifier: [2]
|
||||
regexp/optimal-lookaround-quantifier: [2]
|
||||
regexp/optimal-quantifier-concatenation: [0]
|
||||
regexp/prefer-character-class: [0]
|
||||
regexp/prefer-d: [0]
|
||||
regexp/prefer-escape-replacement-dollar-char: [0]
|
||||
regexp/prefer-lookaround: [0]
|
||||
regexp/prefer-named-backreference: [0]
|
||||
regexp/prefer-named-capture-group: [0]
|
||||
regexp/prefer-named-replacement: [0]
|
||||
regexp/prefer-plus-quantifier: [2]
|
||||
regexp/prefer-predefined-assertion: [2]
|
||||
regexp/prefer-quantifier: [0]
|
||||
regexp/prefer-question-quantifier: [2]
|
||||
regexp/prefer-range: [2]
|
||||
regexp/prefer-regexp-exec: [2]
|
||||
regexp/prefer-regexp-test: [2]
|
||||
regexp/prefer-result-array-groups: [0]
|
||||
regexp/prefer-set-operation: [2]
|
||||
regexp/prefer-star-quantifier: [2]
|
||||
regexp/prefer-unicode-codepoint-escapes: [2]
|
||||
regexp/prefer-w: [0]
|
||||
regexp/require-unicode-regexp: [0]
|
||||
regexp/simplify-set-operations: [2]
|
||||
regexp/sort-alternatives: [0]
|
||||
regexp/sort-character-class-elements: [0]
|
||||
regexp/sort-flags: [0]
|
||||
regexp/strict: [2]
|
||||
regexp/unicode-escape: [0]
|
||||
regexp/use-ignore-case: [0]
|
||||
require-atomic-updates: [0]
|
||||
require-await: [0] # handled by @typescript-eslint/require-await
|
||||
require-unicode-regexp: [0]
|
||||
require-yield: [2]
|
||||
sonarjs/cognitive-complexity: [0]
|
||||
sonarjs/elseif-without-else: [0]
|
||||
sonarjs/max-switch-cases: [0]
|
||||
sonarjs/no-all-duplicated-branches: [2]
|
||||
sonarjs/no-collapsible-if: [0]
|
||||
sonarjs/no-collection-size-mischeck: [2]
|
||||
sonarjs/no-duplicate-string: [0]
|
||||
sonarjs/no-duplicated-branches: [0]
|
||||
sonarjs/no-element-overwrite: [2]
|
||||
sonarjs/no-empty-collection: [2]
|
||||
sonarjs/no-extra-arguments: [2]
|
||||
sonarjs/no-gratuitous-expressions: [2]
|
||||
sonarjs/no-identical-conditions: [2]
|
||||
sonarjs/no-identical-expressions: [2]
|
||||
sonarjs/no-identical-functions: [2, 5]
|
||||
sonarjs/no-ignored-return: [2]
|
||||
sonarjs/no-inverted-boolean-check: [2]
|
||||
sonarjs/no-nested-switch: [0]
|
||||
sonarjs/no-nested-template-literals: [0]
|
||||
sonarjs/no-one-iteration-loop: [2]
|
||||
sonarjs/no-redundant-boolean: [2]
|
||||
sonarjs/no-redundant-jump: [2]
|
||||
sonarjs/no-same-line-conditional: [2]
|
||||
sonarjs/no-small-switch: [0]
|
||||
sonarjs/no-unused-collection: [2]
|
||||
sonarjs/no-use-of-empty-return-value: [2]
|
||||
sonarjs/no-useless-catch: [2]
|
||||
sonarjs/non-existent-operator: [2]
|
||||
sonarjs/prefer-immediate-return: [0]
|
||||
sonarjs/prefer-object-literal: [0]
|
||||
sonarjs/prefer-single-boolean-return: [0]
|
||||
sonarjs/prefer-while: [2]
|
||||
sort-imports: [0]
|
||||
sort-keys: [0]
|
||||
sort-vars: [0]
|
||||
strict: [0]
|
||||
symbol-description: [2]
|
||||
unicode-bom: [2, never]
|
||||
unicorn/better-regex: [0]
|
||||
unicorn/catch-error-name: [0]
|
||||
unicorn/consistent-destructuring: [2]
|
||||
unicorn/consistent-empty-array-spread: [2]
|
||||
unicorn/consistent-existence-index-check: [0]
|
||||
unicorn/consistent-function-scoping: [0]
|
||||
unicorn/custom-error-definition: [0]
|
||||
unicorn/empty-brace-spaces: [2]
|
||||
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/import-style: [0]
|
||||
unicorn/new-for-builtins: [2]
|
||||
unicorn/no-abusive-eslint-disable: [0]
|
||||
unicorn/no-anonymous-default-export: [0]
|
||||
unicorn/no-array-callback-reference: [0]
|
||||
unicorn/no-array-for-each: [2]
|
||||
unicorn/no-array-method-this-argument: [2]
|
||||
unicorn/no-array-push-push: [2]
|
||||
unicorn/no-array-reduce: [2]
|
||||
unicorn/no-await-expression-member: [0]
|
||||
unicorn/no-await-in-promise-methods: [2]
|
||||
unicorn/no-console-spaces: [0]
|
||||
unicorn/no-document-cookie: [2]
|
||||
unicorn/no-empty-file: [2]
|
||||
unicorn/no-for-loop: [0]
|
||||
unicorn/no-hex-escape: [0]
|
||||
unicorn/no-instanceof-array: [0]
|
||||
unicorn/no-invalid-fetch-options: [2]
|
||||
unicorn/no-invalid-remove-event-listener: [2]
|
||||
unicorn/no-keyword-prefix: [0]
|
||||
unicorn/no-length-as-slice-end: [2]
|
||||
unicorn/no-lonely-if: [2]
|
||||
unicorn/no-magic-array-flat-depth: [0]
|
||||
unicorn/no-negated-condition: [0]
|
||||
unicorn/no-negation-in-equality-check: [2]
|
||||
unicorn/no-nested-ternary: [0]
|
||||
unicorn/no-new-array: [0]
|
||||
unicorn/no-new-buffer: [0]
|
||||
unicorn/no-null: [0]
|
||||
unicorn/no-object-as-default-parameter: [0]
|
||||
unicorn/no-process-exit: [0]
|
||||
unicorn/no-single-promise-in-promise-methods: [2]
|
||||
unicorn/no-static-only-class: [2]
|
||||
unicorn/no-thenable: [2]
|
||||
unicorn/no-this-assignment: [2]
|
||||
unicorn/no-typeof-undefined: [2]
|
||||
unicorn/no-unnecessary-await: [2]
|
||||
unicorn/no-unnecessary-polyfills: [2]
|
||||
unicorn/no-unreadable-array-destructuring: [0]
|
||||
unicorn/no-unreadable-iife: [2]
|
||||
unicorn/no-unused-properties: [2]
|
||||
unicorn/no-useless-fallback-in-spread: [2]
|
||||
unicorn/no-useless-length-check: [2]
|
||||
unicorn/no-useless-promise-resolve-reject: [2]
|
||||
unicorn/no-useless-spread: [2]
|
||||
unicorn/no-useless-switch-case: [2]
|
||||
unicorn/no-useless-undefined: [0]
|
||||
unicorn/no-zero-fractions: [2]
|
||||
unicorn/number-literal-case: [0]
|
||||
unicorn/numeric-separators-style: [0]
|
||||
unicorn/prefer-add-event-listener: [2]
|
||||
unicorn/prefer-array-find: [2]
|
||||
unicorn/prefer-array-flat-map: [2]
|
||||
unicorn/prefer-array-flat: [2]
|
||||
unicorn/prefer-array-index-of: [2]
|
||||
unicorn/prefer-array-some: [2]
|
||||
unicorn/prefer-at: [0]
|
||||
unicorn/prefer-blob-reading-methods: [2]
|
||||
unicorn/prefer-code-point: [0]
|
||||
unicorn/prefer-date-now: [2]
|
||||
unicorn/prefer-default-parameters: [0]
|
||||
unicorn/prefer-dom-node-append: [2]
|
||||
unicorn/prefer-dom-node-dataset: [0]
|
||||
unicorn/prefer-dom-node-remove: [2]
|
||||
unicorn/prefer-dom-node-text-content: [2]
|
||||
unicorn/prefer-event-target: [2]
|
||||
unicorn/prefer-export-from: [0]
|
||||
unicorn/prefer-global-this: [0]
|
||||
unicorn/prefer-includes: [2]
|
||||
unicorn/prefer-json-parse-buffer: [0]
|
||||
unicorn/prefer-keyboard-event-key: [2]
|
||||
unicorn/prefer-logical-operator-over-ternary: [2]
|
||||
unicorn/prefer-math-min-max: [2]
|
||||
unicorn/prefer-math-trunc: [2]
|
||||
unicorn/prefer-modern-dom-apis: [0]
|
||||
unicorn/prefer-modern-math-apis: [2]
|
||||
unicorn/prefer-module: [2]
|
||||
unicorn/prefer-native-coercion-functions: [2]
|
||||
unicorn/prefer-negative-index: [2]
|
||||
unicorn/prefer-node-protocol: [2]
|
||||
unicorn/prefer-number-properties: [0]
|
||||
unicorn/prefer-object-from-entries: [2]
|
||||
unicorn/prefer-object-has-own: [0]
|
||||
unicorn/prefer-optional-catch-binding: [2]
|
||||
unicorn/prefer-prototype-methods: [0]
|
||||
unicorn/prefer-query-selector: [2]
|
||||
unicorn/prefer-reflect-apply: [0]
|
||||
unicorn/prefer-regexp-test: [2]
|
||||
unicorn/prefer-set-has: [0]
|
||||
unicorn/prefer-set-size: [2]
|
||||
unicorn/prefer-spread: [0]
|
||||
unicorn/prefer-string-raw: [0]
|
||||
unicorn/prefer-string-replace-all: [0]
|
||||
unicorn/prefer-string-slice: [0]
|
||||
unicorn/prefer-string-starts-ends-with: [2]
|
||||
unicorn/prefer-string-trim-start-end: [2]
|
||||
unicorn/prefer-structured-clone: [2]
|
||||
unicorn/prefer-switch: [0]
|
||||
unicorn/prefer-ternary: [0]
|
||||
unicorn/prefer-text-content: [2]
|
||||
unicorn/prefer-top-level-await: [0]
|
||||
unicorn/prefer-type-error: [0]
|
||||
unicorn/prevent-abbreviations: [0]
|
||||
unicorn/relative-url-style: [2]
|
||||
unicorn/require-array-join-separator: [2]
|
||||
unicorn/require-number-to-fixed-digits-argument: [2]
|
||||
unicorn/require-post-message-target-origin: [0]
|
||||
unicorn/string-content: [0]
|
||||
unicorn/switch-case-braces: [0]
|
||||
unicorn/template-indent: [2]
|
||||
unicorn/text-encoding-identifier-case: [0]
|
||||
unicorn/throw-new-error: [2]
|
||||
use-isnan: [2]
|
||||
valid-typeof: [2, {requireStringLiterals: true}]
|
||||
vars-on-top: [0]
|
||||
wc/attach-shadow-constructor: [2]
|
||||
wc/define-tag-after-class-definition: [0]
|
||||
wc/expose-class-on-global: [0]
|
||||
wc/file-name-matches-element: [2]
|
||||
wc/guard-define-call: [0]
|
||||
wc/guard-super-call: [2]
|
||||
wc/max-elements-per-file: [0]
|
||||
wc/no-child-traversal-in-attributechangedcallback: [2]
|
||||
wc/no-child-traversal-in-connectedcallback: [2]
|
||||
wc/no-closed-shadow-root: [2]
|
||||
wc/no-constructor-attributes: [2]
|
||||
wc/no-constructor-params: [2]
|
||||
wc/no-constructor: [2]
|
||||
wc/no-customized-built-in-elements: [2]
|
||||
wc/no-exports-with-element: [0]
|
||||
wc/no-invalid-element-name: [2]
|
||||
wc/no-invalid-extends: [2]
|
||||
wc/no-method-prefixed-with-on: [2]
|
||||
wc/no-self-class: [2]
|
||||
wc/no-typos: [2]
|
||||
wc/require-listener-teardown: [2]
|
||||
wc/tag-name-matches-class: [2]
|
||||
yoda: [2, never]
|
2
.github/actionlint.yaml
vendored
2
.github/actionlint.yaml
vendored
@ -3,3 +3,5 @@ self-hosted-runner:
|
||||
- actuated-4cpu-8gb
|
||||
- actuated-4cpu-16gb
|
||||
- nscloud
|
||||
- namespace-profile-gitea-release-docker
|
||||
- namespace-profile-gitea-release-binary
|
||||
|
6
.github/workflows/release-nightly.yml
vendored
6
.github/workflows/release-nightly.yml
vendored
@ -10,7 +10,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
nightly-binary:
|
||||
runs-on: nscloud
|
||||
runs-on: namespace-profile-gitea-release-binary
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
@ -58,7 +58,7 @@ jobs:
|
||||
run: |
|
||||
aws s3 sync dist/release s3://${{ secrets.AWS_S3_BUCKET }}/gitea/${{ steps.clean_name.outputs.branch }} --no-progress
|
||||
nightly-docker-rootful:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: namespace-profile-gitea-release-docker
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
@ -95,7 +95,7 @@ jobs:
|
||||
push: true
|
||||
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}
|
||||
nightly-docker-rootless:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: namespace-profile-gitea-release-docker
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
|
6
.github/workflows/release-tag-rc.yml
vendored
6
.github/workflows/release-tag-rc.yml
vendored
@ -11,7 +11,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
binary:
|
||||
runs-on: nscloud
|
||||
runs-on: namespace-profile-gitea-release-binary
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
@ -68,7 +68,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
docker-rootful:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: namespace-profile-gitea-release-docker
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
@ -99,7 +99,7 @@ jobs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
docker-rootless:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: namespace-profile-gitea-release-docker
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
|
6
.github/workflows/release-tag-version.yml
vendored
6
.github/workflows/release-tag-version.yml
vendored
@ -13,7 +13,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
binary:
|
||||
runs-on: nscloud
|
||||
runs-on: namespace-profile-gitea-release-binary
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
@ -70,7 +70,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
docker-rootful:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: namespace-profile-gitea-release-docker
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
@ -105,7 +105,7 @@ jobs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
docker-rootless:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: namespace-profile-gitea-release-docker
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -9,6 +9,10 @@ _test
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
|
||||
# IntelliJ Gateway
|
||||
.uuid
|
||||
|
||||
# Goland's output filename can not be set manually
|
||||
/go_build_*
|
||||
/gitea_*
|
||||
|
@ -19,6 +19,8 @@ linters:
|
||||
- revive
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
- tenv
|
||||
- testifylint
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unused
|
||||
@ -34,6 +36,10 @@ output:
|
||||
show-stats: true
|
||||
|
||||
linters-settings:
|
||||
testifylint:
|
||||
disable:
|
||||
- go-require
|
||||
- require-error
|
||||
stylecheck:
|
||||
checks: ["all", "-ST1005", "-ST1003"]
|
||||
nakedret:
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Build stage
|
||||
FROM docker.io/library/golang:1.23-alpine3.20 AS build-env
|
||||
FROM docker.io/library/golang:1.23-alpine3.21 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY=${GOPROXY:-direct}
|
||||
@ -41,7 +41,7 @@ RUN chmod 755 /tmp/local/usr/bin/entrypoint \
|
||||
/go/src/code.gitea.io/gitea/environment-to-ini
|
||||
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
|
||||
|
||||
FROM docker.io/library/alpine:3.20
|
||||
FROM docker.io/library/alpine:3.21
|
||||
LABEL maintainer="maintainers@gitea.io"
|
||||
|
||||
EXPOSE 22 3000
|
||||
@ -78,7 +78,7 @@ ENV GITEA_CUSTOM=/data/gitea
|
||||
VOLUME ["/data"]
|
||||
|
||||
ENTRYPOINT ["/usr/bin/entrypoint"]
|
||||
CMD ["/bin/s6-svscan", "/etc/s6"]
|
||||
CMD ["/usr/bin/s6-svscan", "/etc/s6"]
|
||||
|
||||
COPY --from=build-env /tmp/local /
|
||||
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Build stage
|
||||
FROM docker.io/library/golang:1.23-alpine3.20 AS build-env
|
||||
FROM docker.io/library/golang:1.23-alpine3.21 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY=${GOPROXY:-direct}
|
||||
@ -39,7 +39,7 @@ RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \
|
||||
/go/src/code.gitea.io/gitea/environment-to-ini
|
||||
RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete
|
||||
|
||||
FROM docker.io/library/alpine:3.20
|
||||
FROM docker.io/library/alpine:3.21
|
||||
LABEL maintainer="maintainers@gitea.io"
|
||||
|
||||
EXPOSE 2222 3000
|
||||
|
@ -46,7 +46,6 @@ Wim <wim@42.be> (@42wim)
|
||||
Jason Song <i@wolfogre.com> (@wolfogre)
|
||||
Yarden Shoham <git@yardenshoham.com> (@yardenshoham)
|
||||
Yu Tian <zettat123@gmail.com> (@Zettat123)
|
||||
Eddie Yang <576951401@qq.com> (@yp05327)
|
||||
Dong Ge <gedong_1994@163.com> (@sillyguodong)
|
||||
Xinyi Gong <hestergong@gmail.com> (@HesterG)
|
||||
wxiaoguang <wxiaoguang@gmail.com> (@wxiaoguang)
|
||||
|
28
Makefile
28
Makefile
@ -26,17 +26,17 @@ COMMA := ,
|
||||
XGO_VERSION := go-1.23.x
|
||||
|
||||
AIR_PACKAGE ?= github.com/air-verse/air@v1
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.7.0
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3.0.3
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.7.0
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.60.3
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
|
||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.5.1
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.2
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.12
|
||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.6.0
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0
|
||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1
|
||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
|
||||
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1
|
||||
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.15.3
|
||||
GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.17.0
|
||||
|
||||
DOCKER_IMAGE ?= gitea/gitea
|
||||
DOCKER_TAG ?= latest
|
||||
@ -377,12 +377,12 @@ lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig
|
||||
.PHONY: lint-js
|
||||
lint-js: node_modules
|
||||
npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES)
|
||||
# npx vue-tsc
|
||||
npx vue-tsc
|
||||
|
||||
.PHONY: lint-js-fix
|
||||
lint-js-fix: node_modules
|
||||
npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) --fix
|
||||
# npx vue-tsc
|
||||
npx vue-tsc
|
||||
|
||||
.PHONY: lint-css
|
||||
lint-css: node_modules
|
||||
@ -451,10 +451,6 @@ lint-templates: .venv node_modules
|
||||
lint-yaml: .venv
|
||||
@poetry run yamllint .
|
||||
|
||||
.PHONY: tsc
|
||||
tsc:
|
||||
npx vue-tsc
|
||||
|
||||
.PHONY: watch
|
||||
watch:
|
||||
@bash tools/watch.sh
|
||||
@ -810,22 +806,22 @@ $(DIST_DIRS):
|
||||
|
||||
.PHONY: release-windows
|
||||
release-windows: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo $(TAGS)' -ldflags '-s -w -linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||
ifeq (,$(findstring gogit,$(TAGS)))
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo gogit $(TAGS)' -ldflags '-s -w -linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
|
||||
endif
|
||||
|
||||
.PHONY: release-linux
|
||||
release-linux: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w -linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) .
|
||||
|
||||
.PHONY: release-darwin
|
||||
release-darwin: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
|
||||
|
||||
.PHONY: release-freebsd
|
||||
release-freebsd: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'freebsd/amd64' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets 'freebsd/amd64' -out gitea-$(VERSION) .
|
||||
|
||||
.PHONY: release-copy
|
||||
release-copy: | $(DIST_DIRS)
|
||||
|
60
assets/go-licenses.json
generated
60
assets/go-licenses.json
generated
File diff suppressed because one or more lines are too long
@ -69,6 +69,10 @@ var microcmdUserCreate = &cli.Command{
|
||||
}
|
||||
|
||||
func runCreateUser(c *cli.Context) error {
|
||||
// this command highly depends on the many setting options (create org, visibility, etc.), so it must have a full setting load first
|
||||
// duplicate setting loading should be safe at the moment, but it should be refactored & improved in the future.
|
||||
setting.LoadSettings()
|
||||
|
||||
if err := argsSet(c, "email"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
11
cmd/web.go
11
cmd/web.go
@ -12,6 +12,7 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
|
||||
|
||||
@ -115,6 +116,16 @@ func showWebStartupMessage(msg string) {
|
||||
log.Info("* CustomPath: %s", setting.CustomPath)
|
||||
log.Info("* ConfigFile: %s", setting.CustomConf)
|
||||
log.Info("%s", msg) // show startup message
|
||||
|
||||
if setting.CORSConfig.Enabled {
|
||||
log.Info("CORS Service Enabled")
|
||||
}
|
||||
if setting.DefaultUILocation != time.Local {
|
||||
log.Info("Default UI Location is %v", setting.DefaultUILocation.String())
|
||||
}
|
||||
if setting.MailService != nil {
|
||||
log.Info("Mail Service Enabled: RegisterEmailConfirm=%v, Service.EnableNotifyMail=%v", setting.Service.RegisterEmailConfirm, setting.Service.EnableNotifyMail)
|
||||
}
|
||||
}
|
||||
|
||||
func serveInstall(ctx *cli.Context) error {
|
||||
|
@ -1040,9 +1040,13 @@ LEVEL = Info
|
||||
;; Don't allow download source archive files from UI
|
||||
;DISABLE_DOWNLOAD_SOURCE_ARCHIVES = false
|
||||
|
||||
;; Allow fork repositories without maximum number limit
|
||||
;; Allow to fork repositories without maximum number limit
|
||||
;ALLOW_FORK_WITHOUT_MAXIMUM_LIMIT = true
|
||||
|
||||
;; Allow to fork repositories into the same owner (user or organization)
|
||||
;; This feature is experimental, not fully tested, and may be changed in the future
|
||||
;ALLOW_FORK_INTO_SAME_OWNER = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[repository.editor]
|
||||
@ -1335,6 +1339,9 @@ LEVEL = Info
|
||||
;; Number of repos that are displayed on one page
|
||||
;REPO_PAGING_NUM = 15
|
||||
|
||||
;; Number of orgs that are displayed on profile page
|
||||
;ORG_PAGING_NUM = 15
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[ui.meta]
|
||||
|
22
go.mod
22
go.mod
@ -28,7 +28,6 @@ require (
|
||||
github.com/PuerkitoBio/goquery v1.10.0
|
||||
github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.3
|
||||
github.com/alecthomas/chroma/v2 v2.14.0
|
||||
github.com/aws/aws-sdk-go v1.55.5
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.42
|
||||
github.com/aws/aws-sdk-go-v2/service/codecommit v1.27.3
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
||||
@ -48,7 +47,7 @@ require (
|
||||
github.com/ethantkoenig/rupture v1.0.1
|
||||
github.com/felixge/fgprof v0.9.5
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/gliderlabs/ssh v0.3.7
|
||||
github.com/gliderlabs/ssh v0.3.8
|
||||
github.com/go-ap/activitypub v0.0.0-20240910141749-b4b8c8aa484c
|
||||
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73
|
||||
github.com/go-chi/chi/v5 v5.1.0
|
||||
@ -61,7 +60,6 @@ require (
|
||||
github.com/go-redsync/redsync/v4 v4.13.0
|
||||
github.com/go-sql-driver/mysql v1.8.1
|
||||
github.com/go-swagger/go-swagger v0.31.0
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.11.0
|
||||
github.com/go-webauthn/webauthn v0.11.2
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
|
||||
@ -121,13 +119,13 @@ require (
|
||||
github.com/yuin/goldmark v1.7.8
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||
github.com/yuin/goldmark-meta v1.1.0
|
||||
golang.org/x/crypto v0.28.0
|
||||
golang.org/x/crypto v0.31.0
|
||||
golang.org/x/image v0.21.0
|
||||
golang.org/x/net v0.30.0
|
||||
golang.org/x/net v0.33.0
|
||||
golang.org/x/oauth2 v0.23.0
|
||||
golang.org/x/sync v0.8.0
|
||||
golang.org/x/sys v0.26.0
|
||||
golang.org/x/text v0.19.0
|
||||
golang.org/x/sync v0.10.0
|
||||
golang.org/x/sys v0.28.0
|
||||
golang.org/x/text v0.21.0
|
||||
golang.org/x/tools v0.26.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
google.golang.org/protobuf v1.35.1
|
||||
@ -145,8 +143,6 @@ require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/ClickHouse/ch-go v0.63.1 // indirect
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.24.0 // indirect
|
||||
github.com/DataDog/zstd v1.5.6 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
@ -204,8 +200,6 @@ require (
|
||||
github.com/go-ap/errors v0.0.0-20240910140019-1e9d33cc1568 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-enry/go-oniguruma v1.2.1 // indirect
|
||||
github.com/go-faster/city v1.0.1 // indirect
|
||||
github.com/go-faster/errors v0.7.1 // indirect
|
||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
@ -270,7 +264,6 @@ require (
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/paulmach/orb v0.11.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
@ -285,7 +278,6 @@ require (
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.6.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/segmentio/asm v1.2.0 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
@ -310,8 +302,6 @@ require (
|
||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
go.etcd.io/bbolt v1.3.11 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.1 // indirect
|
||||
go.opentelemetry.io/otel v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
|
85
go.sum
85
go.sum
@ -59,10 +59,6 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/ClickHouse/ch-go v0.63.1 h1:s2JyZvWLTCSAGdtjMBBmAgQQHMco6pawLJMOXi0FODM=
|
||||
github.com/ClickHouse/ch-go v0.63.1/go.mod h1:I1kJJCL3WJcBMGe1m+HVK0+nREaG+JOYYBWjrDrF3R0=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.24.0 h1:L/n/pVVpk95KtkHOiKuSnO7cu2ckeW4gICbbOh5qs74=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.24.0/go.mod h1:iDTViXk2Fgvf1jn2dbJd1ys+fBkdD1UMRnXlwmhijhQ=
|
||||
github.com/DataDog/zstd v1.5.6 h1:LbEglqepa/ipmmQJUDnSsfvA8e8IStVcGaFWDuxvGOY=
|
||||
github.com/DataDog/zstd v1.5.6/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
||||
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
|
||||
@ -109,8 +105,6 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
|
||||
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.3 h1:T0dRlFBKcdaUPGNtkBSwHZxrtis8CQU17UpNBZYd0wk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.3/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.42 h1:sBP0RPjBU4neGpIYyx8mkU2QqLPl5u9cmdTWVzIpHkM=
|
||||
@ -237,8 +231,6 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
|
||||
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
|
||||
github.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw=
|
||||
github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21 h1:PdsjTl0Cg+ZJgOx/CFV5NNgO1ThTreqdgKYiDCMHJwA=
|
||||
@ -293,8 +285,8 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1 h1:mtDjlmloH7ytdblogrMz1/8Hqua1y8B4ID+bh3rvod0=
|
||||
github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1/go.mod h1:fenKRzpXDjNpsIBhuhUzvjCKlDjKam0boRAenTE0Q6A=
|
||||
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
|
||||
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
|
||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/go-ap/activitypub v0.0.0-20240910141749-b4b8c8aa484c h1:82lzmsy5Nr6JA6HcLRVxGfbdSoWfW45C6jnY3zFS7Ks=
|
||||
@ -317,10 +309,6 @@ github.com/go-enry/go-enry/v2 v2.9.1 h1:G9iDteJ/Mc0F4Di5NeQknf83R2OkRbwY9cAYmcqV
|
||||
github.com/go-enry/go-enry/v2 v2.9.1/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
|
||||
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
||||
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
|
||||
github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
|
||||
github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg=
|
||||
github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo=
|
||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8=
|
||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
@ -372,8 +360,6 @@ github.com/go-swagger/go-swagger v0.31.0/go.mod h1:WSigRRWEig8zV6t6Sm8Y+EmUjlzA/
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
||||
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.11.0 h1:XxQr8AnPORcZkyNd7go5UNLPD3dULN8ixYISlzrlfEQ=
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.11.0/go.mod h1:THmudHF1Ixq++J2/UodcJpxUphfyEd77m83TvDtryqE=
|
||||
github.com/go-webauthn/webauthn v0.11.2 h1:Fgx0/wlmkClTKlnOsdOQ+K5HcHDsDcYIvtYmfhEOSUc=
|
||||
github.com/go-webauthn/webauthn v0.11.2/go.mod h1:aOtudaF94pM71g3jRwTYYwQTG1KyTILTcZqN1srkmD0=
|
||||
github.com/go-webauthn/x v0.1.15 h1:eG1OhggBJTkDE8gUeOlGRbRe8E/PSVG26YG4AyFbwkU=
|
||||
@ -385,7 +371,6 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
|
||||
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
|
||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
|
||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JPCjlxoJd6K8ALZqSDDhk2ymieAZOVaDg0=
|
||||
@ -410,7 +395,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
@ -497,22 +481,6 @@ github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI
|
||||
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w=
|
||||
github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
|
||||
github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw=
|
||||
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA=
|
||||
github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
|
||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA=
|
||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
@ -533,10 +501,6 @@ github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bB
|
||||
github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc=
|
||||
github.com/jhillyerd/enmime v1.3.0 h1:LV5kzfLidiOr8qRGIpYYmUZCnhrPbcFAnAFUnWn99rw=
|
||||
github.com/jhillyerd/enmime v1.3.0/go.mod h1:6c6jg5HdRRV2FtvVL69LjiX1M8oE0xDX9VEhV3oy4gs=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
@ -550,11 +514,8 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+4tLukHoB9iqHOu3LmLhRmgUxZo6Vp4=
|
||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
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.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
@ -629,7 +590,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 h1:j2kD3MT1z4PXCiUllUJF9mWUESr9TWKS7iEKsQ/IipM=
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
@ -670,9 +630,6 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU=
|
||||
github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
@ -735,8 +692,6 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6Ng
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
|
||||
github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg=
|
||||
github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI=
|
||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||
github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
|
||||
@ -783,7 +738,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
@ -797,7 +751,6 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
|
||||
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
|
||||
@ -823,9 +776,6 @@ github.com/xanzy/go-gitlab v0.112.0 h1:6Z0cqEooCvBMfBIHw+CgO4AKGRV8na/9781xOb0+D
|
||||
github.com/xanzy/go-gitlab v0.112.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@ -842,9 +792,7 @@ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZ
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
|
||||
github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
@ -863,13 +811,8 @@ github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
|
||||
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
|
||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
go.mongodb.org/mongo-driver v1.17.1 h1:Wic5cJIwJgSpBhe3lx3+/RybR5PiYRMpVFgO7cOHyIM=
|
||||
go.mongodb.org/mongo-driver v1.17.1/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
|
||||
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
@ -893,8 +836,9 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
|
||||
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
|
||||
@ -931,8 +875,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -940,14 +884,14 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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=
|
||||
@ -982,8 +926,9 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@ -996,8 +941,9 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@ -1009,18 +955,17 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
@ -1041,8 +986,6 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -37,6 +37,7 @@ type ActionRun struct {
|
||||
TriggerUser *user_model.User `xorm:"-"`
|
||||
ScheduleID int64
|
||||
Ref string `xorm:"index"` // the commit/tag/… that caused the run
|
||||
IsRefDeleted bool `xorm:"-"`
|
||||
CommitSHA string
|
||||
IsForkPullRequest bool // If this is triggered by a PR from a forked repository or an untrusted user, we need to check if it is approved and limit permissions when running the workflow.
|
||||
NeedApproval bool // may need approval if it's a fork pull request
|
||||
@ -274,7 +275,7 @@ func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWork
|
||||
return err
|
||||
}
|
||||
run.Index = index
|
||||
run.Title, _ = util.SplitStringAtByteN(run.Title, 255)
|
||||
run.Title = util.EllipsisDisplayString(run.Title, 255)
|
||||
|
||||
if err := db.Insert(ctx, run); err != nil {
|
||||
return err
|
||||
@ -307,7 +308,7 @@ func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWork
|
||||
} else {
|
||||
hasWaiting = true
|
||||
}
|
||||
job.Name, _ = util.SplitStringAtByteN(job.Name, 255)
|
||||
job.Name = util.EllipsisDisplayString(job.Name, 255)
|
||||
runJobs = append(runJobs, &ActionRunJob{
|
||||
RunID: run.ID,
|
||||
RepoID: run.RepoID,
|
||||
@ -401,7 +402,7 @@ func UpdateRun(ctx context.Context, run *ActionRun, cols ...string) error {
|
||||
if len(cols) > 0 {
|
||||
sess.Cols(cols...)
|
||||
}
|
||||
run.Title, _ = util.SplitStringAtByteN(run.Title, 255)
|
||||
run.Title = util.EllipsisDisplayString(run.Title, 255)
|
||||
affected, err := sess.Update(run)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -137,7 +137,7 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
run.Status = aggregateJobStatus(jobs)
|
||||
run.Status = AggregateJobStatus(jobs)
|
||||
if run.Started.IsZero() && run.Status.IsRunning() {
|
||||
run.Started = timeutil.TimeStampNow()
|
||||
}
|
||||
@ -152,29 +152,35 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
|
||||
return affected, nil
|
||||
}
|
||||
|
||||
func aggregateJobStatus(jobs []*ActionRunJob) Status {
|
||||
allDone := true
|
||||
allWaiting := true
|
||||
hasFailure := false
|
||||
func AggregateJobStatus(jobs []*ActionRunJob) Status {
|
||||
allSuccessOrSkipped := len(jobs) != 0
|
||||
allSkipped := len(jobs) != 0
|
||||
var hasFailure, hasCancelled, hasWaiting, hasRunning, hasBlocked bool
|
||||
for _, job := range jobs {
|
||||
if !job.Status.IsDone() {
|
||||
allDone = false
|
||||
}
|
||||
if job.Status != StatusWaiting && !job.Status.IsDone() {
|
||||
allWaiting = false
|
||||
}
|
||||
if job.Status == StatusFailure || job.Status == StatusCancelled {
|
||||
hasFailure = true
|
||||
}
|
||||
allSuccessOrSkipped = allSuccessOrSkipped && (job.Status == StatusSuccess || job.Status == StatusSkipped)
|
||||
allSkipped = allSkipped && job.Status == StatusSkipped
|
||||
hasFailure = hasFailure || job.Status == StatusFailure
|
||||
hasCancelled = hasCancelled || job.Status == StatusCancelled
|
||||
hasWaiting = hasWaiting || job.Status == StatusWaiting
|
||||
hasRunning = hasRunning || job.Status == StatusRunning
|
||||
hasBlocked = hasBlocked || job.Status == StatusBlocked
|
||||
}
|
||||
if allDone {
|
||||
if hasFailure {
|
||||
return StatusFailure
|
||||
}
|
||||
switch {
|
||||
case allSkipped:
|
||||
return StatusSkipped
|
||||
case allSuccessOrSkipped:
|
||||
return StatusSuccess
|
||||
}
|
||||
if allWaiting {
|
||||
case hasCancelled:
|
||||
return StatusCancelled
|
||||
case hasFailure:
|
||||
return StatusFailure
|
||||
case hasRunning:
|
||||
return StatusRunning
|
||||
case hasWaiting:
|
||||
return StatusWaiting
|
||||
case hasBlocked:
|
||||
return StatusBlocked
|
||||
default:
|
||||
return StatusUnknown // it shouldn't happen
|
||||
}
|
||||
return StatusRunning
|
||||
}
|
||||
|
85
models/actions/run_job_status_test.go
Normal file
85
models/actions/run_job_status_test.go
Normal file
@ -0,0 +1,85 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package actions
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAggregateJobStatus(t *testing.T) {
|
||||
testStatuses := func(expected Status, statuses []Status) {
|
||||
t.Helper()
|
||||
var jobs []*ActionRunJob
|
||||
for _, v := range statuses {
|
||||
jobs = append(jobs, &ActionRunJob{Status: v})
|
||||
}
|
||||
actual := AggregateJobStatus(jobs)
|
||||
if !assert.Equal(t, expected, actual) {
|
||||
var statusStrings []string
|
||||
for _, s := range statuses {
|
||||
statusStrings = append(statusStrings, s.String())
|
||||
}
|
||||
t.Errorf("AggregateJobStatus(%v) = %v, want %v", statusStrings, statusNames[actual], statusNames[expected])
|
||||
}
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
statuses []Status
|
||||
expected Status
|
||||
}{
|
||||
// unknown cases, maybe it shouldn't happen in real world
|
||||
{[]Status{}, StatusUnknown},
|
||||
{[]Status{StatusUnknown, StatusSuccess}, StatusUnknown},
|
||||
{[]Status{StatusUnknown, StatusSkipped}, StatusUnknown},
|
||||
{[]Status{StatusUnknown, StatusFailure}, StatusFailure},
|
||||
{[]Status{StatusUnknown, StatusCancelled}, StatusCancelled},
|
||||
{[]Status{StatusUnknown, StatusWaiting}, StatusWaiting},
|
||||
{[]Status{StatusUnknown, StatusRunning}, StatusRunning},
|
||||
{[]Status{StatusUnknown, StatusBlocked}, StatusBlocked},
|
||||
|
||||
// success with other status
|
||||
{[]Status{StatusSuccess}, StatusSuccess},
|
||||
{[]Status{StatusSuccess, StatusSkipped}, StatusSuccess}, // skipped doesn't affect success
|
||||
{[]Status{StatusSuccess, StatusFailure}, StatusFailure},
|
||||
{[]Status{StatusSuccess, StatusCancelled}, StatusCancelled},
|
||||
{[]Status{StatusSuccess, StatusWaiting}, StatusWaiting},
|
||||
{[]Status{StatusSuccess, StatusRunning}, StatusRunning},
|
||||
{[]Status{StatusSuccess, StatusBlocked}, StatusBlocked},
|
||||
|
||||
// any cancelled, then cancelled
|
||||
{[]Status{StatusCancelled}, StatusCancelled},
|
||||
{[]Status{StatusCancelled, StatusSuccess}, StatusCancelled},
|
||||
{[]Status{StatusCancelled, StatusSkipped}, StatusCancelled},
|
||||
{[]Status{StatusCancelled, StatusFailure}, StatusCancelled},
|
||||
{[]Status{StatusCancelled, StatusWaiting}, StatusCancelled},
|
||||
{[]Status{StatusCancelled, StatusRunning}, StatusCancelled},
|
||||
{[]Status{StatusCancelled, StatusBlocked}, StatusCancelled},
|
||||
|
||||
// failure with other status, fail fast
|
||||
// Should "running" win? Maybe no: old code does make "running" win, but GitHub does fail fast.
|
||||
{[]Status{StatusFailure}, StatusFailure},
|
||||
{[]Status{StatusFailure, StatusSuccess}, StatusFailure},
|
||||
{[]Status{StatusFailure, StatusSkipped}, StatusFailure},
|
||||
{[]Status{StatusFailure, StatusCancelled}, StatusCancelled},
|
||||
{[]Status{StatusFailure, StatusWaiting}, StatusFailure},
|
||||
{[]Status{StatusFailure, StatusRunning}, StatusFailure},
|
||||
{[]Status{StatusFailure, StatusBlocked}, StatusFailure},
|
||||
|
||||
// skipped with other status
|
||||
// "all skipped" is also considered as "mergeable" by "services/actions.toCommitStatus", the same as GitHub
|
||||
{[]Status{StatusSkipped}, StatusSkipped},
|
||||
{[]Status{StatusSkipped, StatusSuccess}, StatusSuccess},
|
||||
{[]Status{StatusSkipped, StatusFailure}, StatusFailure},
|
||||
{[]Status{StatusSkipped, StatusCancelled}, StatusCancelled},
|
||||
{[]Status{StatusSkipped, StatusWaiting}, StatusWaiting},
|
||||
{[]Status{StatusSkipped, StatusRunning}, StatusRunning},
|
||||
{[]Status{StatusSkipped, StatusBlocked}, StatusBlocked},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
testStatuses(c.expected, c.statuses)
|
||||
}
|
||||
}
|
@ -252,7 +252,7 @@ func GetRunnerByID(ctx context.Context, id int64) (*ActionRunner, error) {
|
||||
// UpdateRunner updates runner's information.
|
||||
func UpdateRunner(ctx context.Context, r *ActionRunner, cols ...string) error {
|
||||
e := db.GetEngine(ctx)
|
||||
r.Name, _ = util.SplitStringAtByteN(r.Name, 255)
|
||||
r.Name = util.EllipsisDisplayString(r.Name, 255)
|
||||
var err error
|
||||
if len(cols) == 0 {
|
||||
_, err = e.ID(r.ID).AllCols().Update(r)
|
||||
@ -279,7 +279,7 @@ func CreateRunner(ctx context.Context, t *ActionRunner) error {
|
||||
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
|
||||
t.OwnerID = 0
|
||||
}
|
||||
t.Name, _ = util.SplitStringAtByteN(t.Name, 255)
|
||||
t.Name = util.EllipsisDisplayString(t.Name, 255)
|
||||
return db.Insert(ctx, t)
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ func GetRunnerToken(ctx context.Context, token string) (*ActionRunnerToken, erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, fmt.Errorf("runner token %q: %w", token, util.ErrNotExist)
|
||||
return nil, fmt.Errorf(`runner token "%s...": %w`, util.TruncateRunes(token, 3), util.ErrNotExist)
|
||||
}
|
||||
return &runnerToken, nil
|
||||
}
|
||||
@ -68,19 +68,15 @@ func UpdateRunnerToken(ctx context.Context, r *ActionRunnerToken, cols ...string
|
||||
return err
|
||||
}
|
||||
|
||||
// NewRunnerToken creates a new active runner token and invalidate all old tokens
|
||||
// NewRunnerTokenWithValue creates a new active runner token and invalidate all old tokens
|
||||
// ownerID will be ignored and treated as 0 if repoID is non-zero.
|
||||
func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
|
||||
func NewRunnerTokenWithValue(ctx context.Context, ownerID, repoID int64, token string) (*ActionRunnerToken, error) {
|
||||
if ownerID != 0 && repoID != 0 {
|
||||
// It's trying to create a runner token that belongs to a repository, but OwnerID has been set accidentally.
|
||||
// Remove OwnerID to avoid confusion; it's not worth returning an error here.
|
||||
ownerID = 0
|
||||
}
|
||||
|
||||
token, err := util.CryptoRandomString(40)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runnerToken := &ActionRunnerToken{
|
||||
OwnerID: ownerID,
|
||||
RepoID: repoID,
|
||||
@ -95,11 +91,19 @@ func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerTo
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = db.GetEngine(ctx).Insert(runnerToken)
|
||||
_, err := db.GetEngine(ctx).Insert(runnerToken)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
|
||||
token, err := util.CryptoRandomString(40)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewRunnerTokenWithValue(ctx, ownerID, repoID, token)
|
||||
}
|
||||
|
||||
// GetLatestRunnerToken returns the latest runner token
|
||||
func GetLatestRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
|
||||
if ownerID != 0 && repoID != 0 {
|
||||
|
@ -17,7 +17,7 @@ func TestGetLatestRunnerToken(t *testing.T) {
|
||||
token := unittest.AssertExistsAndLoadBean(t, &ActionRunnerToken{ID: 3})
|
||||
expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, token, expectedToken)
|
||||
assert.EqualValues(t, expectedToken, token)
|
||||
}
|
||||
|
||||
func TestNewRunnerToken(t *testing.T) {
|
||||
@ -26,7 +26,7 @@ func TestNewRunnerToken(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, token, expectedToken)
|
||||
assert.EqualValues(t, expectedToken, token)
|
||||
}
|
||||
|
||||
func TestUpdateRunnerToken(t *testing.T) {
|
||||
@ -36,5 +36,5 @@ func TestUpdateRunnerToken(t *testing.T) {
|
||||
assert.NoError(t, UpdateRunnerToken(db.DefaultContext, token))
|
||||
expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, token, expectedToken)
|
||||
assert.EqualValues(t, expectedToken, token)
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
|
||||
|
||||
// Loop through each schedule row
|
||||
for _, row := range rows {
|
||||
row.Title, _ = util.SplitStringAtByteN(row.Title, 255)
|
||||
row.Title = util.EllipsisDisplayString(row.Title, 255)
|
||||
// Create new schedule row
|
||||
if err = db.Insert(ctx, row); err != nil {
|
||||
return err
|
||||
|
@ -298,7 +298,7 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
|
||||
if len(workflowJob.Steps) > 0 {
|
||||
steps := make([]*ActionTaskStep, len(workflowJob.Steps))
|
||||
for i, v := range workflowJob.Steps {
|
||||
name, _ := util.SplitStringAtByteN(v.String(), 255)
|
||||
name := util.EllipsisDisplayString(v.String(), 255)
|
||||
steps[i] = &ActionTaskStep{
|
||||
Name: name,
|
||||
TaskID: task.ID,
|
||||
|
@ -20,12 +20,12 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm/schemas"
|
||||
@ -226,7 +226,7 @@ func (a *Action) GetActUserName(ctx context.Context) string {
|
||||
// ShortActUserName gets the action's user name trimmed to max 20
|
||||
// chars.
|
||||
func (a *Action) ShortActUserName(ctx context.Context) string {
|
||||
return base.EllipsisString(a.GetActUserName(ctx), 20)
|
||||
return util.EllipsisDisplayString(a.GetActUserName(ctx), 20)
|
||||
}
|
||||
|
||||
// GetActDisplayName gets the action's display name based on DEFAULT_SHOW_FULL_NAME, or falls back to the username if it is blank.
|
||||
@ -260,7 +260,7 @@ func (a *Action) GetRepoUserName(ctx context.Context) string {
|
||||
// ShortRepoUserName returns the name of the action repository owner
|
||||
// trimmed to max 20 chars.
|
||||
func (a *Action) ShortRepoUserName(ctx context.Context) string {
|
||||
return base.EllipsisString(a.GetRepoUserName(ctx), 20)
|
||||
return util.EllipsisDisplayString(a.GetRepoUserName(ctx), 20)
|
||||
}
|
||||
|
||||
// GetRepoName returns the name of the action repository.
|
||||
@ -275,7 +275,7 @@ func (a *Action) GetRepoName(ctx context.Context) string {
|
||||
// ShortRepoName returns the name of the action repository
|
||||
// trimmed to max 33 chars.
|
||||
func (a *Action) ShortRepoName(ctx context.Context) string {
|
||||
return base.EllipsisString(a.GetRepoName(ctx), 33)
|
||||
return util.EllipsisDisplayString(a.GetRepoName(ctx), 33)
|
||||
}
|
||||
|
||||
// GetRepoPath returns the virtual path to the action repository.
|
||||
@ -511,7 +511,7 @@ func ActivityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder.
|
||||
}
|
||||
|
||||
if opts.RequestedTeam != nil {
|
||||
env := organization.OrgFromUser(opts.RequestedUser).AccessibleTeamReposEnv(ctx, opts.RequestedTeam)
|
||||
env := repo_model.AccessibleTeamReposEnv(ctx, organization.OrgFromUser(opts.RequestedUser), opts.RequestedTeam)
|
||||
teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetTeamRepositories: %w", err)
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
@ -337,8 +338,10 @@ func newlyCreatedIssues(ctx context.Context, repoID int64, fromTime time.Time) *
|
||||
func activeIssues(ctx context.Context, repoID int64, fromTime time.Time) *xorm.Session {
|
||||
sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID).
|
||||
And("issue.is_pull = ?", false).
|
||||
And("issue.created_unix >= ?", fromTime.Unix()).
|
||||
Or("issue.closed_unix >= ?", fromTime.Unix())
|
||||
And(builder.Or(
|
||||
builder.Gte{"issue.created_unix": fromTime.Unix()},
|
||||
builder.Gte{"issue.closed_unix": fromTime.Unix()},
|
||||
))
|
||||
|
||||
return sess
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
package activities_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -65,11 +64,9 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tc.userID})
|
||||
|
||||
doer := &user_model.User{ID: tc.doerID}
|
||||
_, err := unittest.LoadBeanIfExists(doer)
|
||||
assert.NoError(t, err)
|
||||
if tc.doerID == 0 {
|
||||
doer = nil
|
||||
var doer *user_model.User
|
||||
if tc.doerID != 0 {
|
||||
doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tc.doerID})
|
||||
}
|
||||
|
||||
// get the action for comparison
|
||||
@ -91,11 +88,11 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, actions, contributions, "invalid action count: did the test data became too old?")
|
||||
assert.Equal(t, count, int64(contributions))
|
||||
assert.Equal(t, tc.CountResult, contributions, fmt.Sprintf("testcase '%s'", tc.desc))
|
||||
assert.Equal(t, tc.CountResult, contributions, "testcase '%s'", tc.desc)
|
||||
|
||||
// Test JSON rendering
|
||||
jsonData, err := json.Marshal(heatmap)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.JSONResult, string(jsonData))
|
||||
assert.JSONEq(t, tc.JSONResult, string(jsonData))
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +217,7 @@ func (err ErrGPGKeyAccessDenied) Unwrap() error {
|
||||
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
|
||||
type ErrKeyAccessDenied struct {
|
||||
UserID int64
|
||||
RepoID int64
|
||||
KeyID int64
|
||||
Note string
|
||||
}
|
||||
@ -228,8 +229,8 @@ func IsErrKeyAccessDenied(err error) bool {
|
||||
}
|
||||
|
||||
func (err ErrKeyAccessDenied) Error() string {
|
||||
return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d, note: %s]",
|
||||
err.UserID, err.KeyID, err.Note)
|
||||
return fmt.Sprintf("user does not have access to the key [user_id: %d, repo_id: %d, key_id: %d, note: %s]",
|
||||
err.UserID, err.RepoID, err.KeyID, err.Note)
|
||||
}
|
||||
|
||||
func (err ErrKeyAccessDenied) Unwrap() error {
|
||||
|
@ -18,7 +18,7 @@ func TestOAuth2Application_GenerateClientSecret(t *testing.T) {
|
||||
app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
|
||||
secret, err := app.GenerateClientSecret(db.DefaultContext)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, len(secret) > 0)
|
||||
assert.NotEmpty(t, secret)
|
||||
unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1, ClientSecret: app.ClientSecret})
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) {
|
||||
code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, code)
|
||||
assert.True(t, len(code.Code) > 32) // secret length > 32
|
||||
assert.Greater(t, len(code.Code), 32) // secret length > 32
|
||||
}
|
||||
|
||||
func TestOAuth2Grant_TableName(t *testing.T) {
|
||||
|
@ -13,6 +13,8 @@ import (
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
@ -54,7 +56,8 @@ func TestDumpAuthSource(t *testing.T) {
|
||||
|
||||
sb := new(strings.Builder)
|
||||
|
||||
db.DumpTables([]*schemas.Table{authSourceSchema}, sb)
|
||||
|
||||
// TODO: this test is quite hacky, it should use a low-level "select" (without model processors) but not a database dump
|
||||
engine := db.GetEngine(db.DefaultContext).(*xorm.Engine)
|
||||
require.NoError(t, engine.DumpTables([]*schemas.Table{authSourceSchema}, sb))
|
||||
assert.Contains(t, sb.String(), `"Provider":"ConvertibleSourceName"`)
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ func TestWebAuthnCredential_UpdateSignCount(t *testing.T) {
|
||||
cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1})
|
||||
cred.SignCount = 1
|
||||
assert.NoError(t, cred.UpdateSignCount(db.DefaultContext))
|
||||
unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, SignCount: 1})
|
||||
unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1, SignCount: 1})
|
||||
}
|
||||
|
||||
func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) {
|
||||
@ -52,7 +52,7 @@ func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) {
|
||||
cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1})
|
||||
cred.SignCount = 0xffffffff
|
||||
assert.NoError(t, cred.UpdateSignCount(db.DefaultContext))
|
||||
unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, SignCount: 0xffffffff})
|
||||
unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1, SignCount: 0xffffffff})
|
||||
}
|
||||
|
||||
func TestCreateCredential(t *testing.T) {
|
||||
@ -63,5 +63,5 @@ func TestCreateCredential(t *testing.T) {
|
||||
assert.Equal(t, "WebAuthn Created Credential", res.Name)
|
||||
assert.Equal(t, []byte("Test"), res.CredentialID)
|
||||
|
||||
unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1})
|
||||
unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1})
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ func CheckCollations(x *xorm.Engine) (*CheckCollationsResult, error) {
|
||||
}
|
||||
|
||||
func CheckCollationsDefaultEngine() (*CheckCollationsResult, error) {
|
||||
return CheckCollations(x)
|
||||
return CheckCollations(xormEngine)
|
||||
}
|
||||
|
||||
func alterDatabaseCollation(x *xorm.Engine, collation string) error {
|
||||
|
@ -94,7 +94,7 @@ func GetEngine(ctx context.Context) Engine {
|
||||
if e := getExistingEngine(ctx); e != nil {
|
||||
return e
|
||||
}
|
||||
return x.Context(ctx)
|
||||
return xormEngine.Context(ctx)
|
||||
}
|
||||
|
||||
// getExistingEngine gets an existing db Engine/Statement from this context or returns nil
|
||||
@ -155,7 +155,7 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) {
|
||||
return newContext(parentCtx, sess), &halfCommitter{committer: sess}, nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
sess := xormEngine.NewSession()
|
||||
if err := sess.Begin(); err != nil {
|
||||
_ = sess.Close()
|
||||
return nil, nil, err
|
||||
@ -179,7 +179,7 @@ func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error
|
||||
}
|
||||
|
||||
func txWithNoCheck(parentCtx context.Context, f func(ctx context.Context) error) error {
|
||||
sess := x.NewSession()
|
||||
sess := xormEngine.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
@ -322,7 +322,7 @@ func CountByBean(ctx context.Context, bean any) (int64, error) {
|
||||
|
||||
// TableName returns the table name according a bean object
|
||||
func TableName(bean any) string {
|
||||
return x.TableName(bean)
|
||||
return xormEngine.TableName(bean)
|
||||
}
|
||||
|
||||
// InTransaction returns true if the engine is in a transaction otherwise return false
|
||||
|
@ -4,7 +4,7 @@
|
||||
package db // it's not db_test, because this file is for testing the private type halfCommitter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -80,7 +80,7 @@ func Test_halfCommitter(t *testing.T) {
|
||||
testWithCommitter(mockCommitter, func(committer Committer) error {
|
||||
defer committer.Close()
|
||||
if true {
|
||||
return fmt.Errorf("error")
|
||||
return errors.New("error")
|
||||
}
|
||||
return committer.Commit()
|
||||
})
|
||||
@ -94,7 +94,7 @@ func Test_halfCommitter(t *testing.T) {
|
||||
testWithCommitter(mockCommitter, func(committer Committer) error {
|
||||
committer.Close()
|
||||
committer.Commit()
|
||||
return fmt.Errorf("error")
|
||||
return errors.New("error")
|
||||
})
|
||||
|
||||
mockCommitter.Assert(t)
|
||||
|
@ -16,30 +16,30 @@ import (
|
||||
|
||||
// ConvertDatabaseTable converts database and tables from utf8 to utf8mb4 if it's mysql and set ROW_FORMAT=dynamic
|
||||
func ConvertDatabaseTable() error {
|
||||
if x.Dialect().URI().DBType != schemas.MYSQL {
|
||||
if xormEngine.Dialect().URI().DBType != schemas.MYSQL {
|
||||
return nil
|
||||
}
|
||||
|
||||
r, err := CheckCollations(x)
|
||||
r, err := CheckCollations(xormEngine)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = x.Exec(fmt.Sprintf("ALTER DATABASE `%s` CHARACTER SET utf8mb4 COLLATE %s", setting.Database.Name, r.ExpectedCollation))
|
||||
_, err = xormEngine.Exec(fmt.Sprintf("ALTER DATABASE `%s` CHARACTER SET utf8mb4 COLLATE %s", setting.Database.Name, r.ExpectedCollation))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tables, err := x.DBMetas()
|
||||
tables, err := xormEngine.DBMetas()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, table := range tables {
|
||||
if _, err := x.Exec(fmt.Sprintf("ALTER TABLE `%s` ROW_FORMAT=dynamic", table.Name)); err != nil {
|
||||
if _, err := xormEngine.Exec(fmt.Sprintf("ALTER TABLE `%s` ROW_FORMAT=dynamic", table.Name)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := x.Exec(fmt.Sprintf("ALTER TABLE `%s` CONVERT TO CHARACTER SET utf8mb4 COLLATE %s", table.Name, r.ExpectedCollation)); err != nil {
|
||||
if _, err := xormEngine.Exec(fmt.Sprintf("ALTER TABLE `%s` CONVERT TO CHARACTER SET utf8mb4 COLLATE %s", table.Name, r.ExpectedCollation)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -49,11 +49,11 @@ func ConvertDatabaseTable() error {
|
||||
|
||||
// ConvertVarcharToNVarchar converts database and tables from varchar to nvarchar if it's mssql
|
||||
func ConvertVarcharToNVarchar() error {
|
||||
if x.Dialect().URI().DBType != schemas.MSSQL {
|
||||
if xormEngine.Dialect().URI().DBType != schemas.MSSQL {
|
||||
return nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
sess := xormEngine.NewSession()
|
||||
defer sess.Close()
|
||||
res, err := sess.QuerySliceString(`SELECT 'ALTER TABLE ' + OBJECT_NAME(SC.object_id) + ' MODIFY SC.name NVARCHAR(' + CONVERT(VARCHAR(5),SC.max_length) + ')'
|
||||
FROM SYS.columns SC
|
||||
|
@ -8,17 +8,10 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/contexts"
|
||||
"xorm.io/xorm/names"
|
||||
"xorm.io/xorm/schemas"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql" // Needed for the MySQL driver
|
||||
@ -27,9 +20,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
x *xorm.Engine
|
||||
tables []any
|
||||
initFuncs []func() error
|
||||
xormEngine *xorm.Engine
|
||||
registeredModels []any
|
||||
registeredInitFuncs []func() error
|
||||
)
|
||||
|
||||
// Engine represents a xorm engine or session.
|
||||
@ -70,167 +63,38 @@ type Engine interface {
|
||||
|
||||
// TableInfo returns table's information via an object
|
||||
func TableInfo(v any) (*schemas.Table, error) {
|
||||
return x.TableInfo(v)
|
||||
return xormEngine.TableInfo(v)
|
||||
}
|
||||
|
||||
// DumpTables dump tables information
|
||||
func DumpTables(tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) error {
|
||||
return x.DumpTables(tables, w, tp...)
|
||||
}
|
||||
|
||||
// RegisterModel registers model, if initfunc provided, it will be invoked after data model sync
|
||||
// RegisterModel registers model, if initFuncs provided, it will be invoked after data model sync
|
||||
func RegisterModel(bean any, initFunc ...func() error) {
|
||||
tables = append(tables, bean)
|
||||
if len(initFuncs) > 0 && initFunc[0] != nil {
|
||||
initFuncs = append(initFuncs, initFunc[0])
|
||||
registeredModels = append(registeredModels, bean)
|
||||
if len(registeredInitFuncs) > 0 && initFunc[0] != nil {
|
||||
registeredInitFuncs = append(registeredInitFuncs, initFunc[0])
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
gonicNames := []string{"SSL", "UID"}
|
||||
for _, name := range gonicNames {
|
||||
names.LintGonicMapper[name] = true
|
||||
}
|
||||
}
|
||||
|
||||
// newXORMEngine returns a new XORM engine from the configuration
|
||||
func newXORMEngine() (*xorm.Engine, error) {
|
||||
connStr, err := setting.DBConnStr()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var engine *xorm.Engine
|
||||
|
||||
if setting.Database.Type.IsPostgreSQL() && len(setting.Database.Schema) > 0 {
|
||||
// OK whilst we sort out our schema issues - create a schema aware postgres
|
||||
registerPostgresSchemaDriver()
|
||||
engine, err = xorm.NewEngine("postgresschema", connStr)
|
||||
} else {
|
||||
engine, err = xorm.NewEngine(setting.Database.Type.String(), connStr)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if setting.Database.Type == "mysql" {
|
||||
engine.Dialect().SetParams(map[string]string{"rowFormat": "DYNAMIC"})
|
||||
} else if setting.Database.Type == "mssql" {
|
||||
engine.Dialect().SetParams(map[string]string{"DEFAULT_VARCHAR": "nvarchar"})
|
||||
}
|
||||
engine.SetSchema(setting.Database.Schema)
|
||||
return engine, nil
|
||||
}
|
||||
|
||||
// SyncAllTables sync the schemas of all tables, is required by unit test code
|
||||
func SyncAllTables() error {
|
||||
_, err := x.StoreEngine("InnoDB").SyncWithOptions(xorm.SyncOptions{
|
||||
_, err := xormEngine.StoreEngine("InnoDB").SyncWithOptions(xorm.SyncOptions{
|
||||
WarnIfDatabaseColumnMissed: true,
|
||||
}, tables...)
|
||||
}, registeredModels...)
|
||||
return err
|
||||
}
|
||||
|
||||
// InitEngine initializes the xorm.Engine and sets it as db.DefaultContext
|
||||
func InitEngine(ctx context.Context) error {
|
||||
xormEngine, err := newXORMEngine()
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "SQLite3 support") {
|
||||
return fmt.Errorf(`sqlite3 requires: -tags sqlite,sqlite_unlock_notify%s%w`, "\n", err)
|
||||
}
|
||||
return fmt.Errorf("failed to connect to database: %w", err)
|
||||
}
|
||||
|
||||
xormEngine.SetMapper(names.GonicMapper{})
|
||||
// WARNING: for serv command, MUST remove the output to os.stdout,
|
||||
// so use log file to instead print to stdout.
|
||||
xormEngine.SetLogger(NewXORMLogger(setting.Database.LogSQL))
|
||||
xormEngine.ShowSQL(setting.Database.LogSQL)
|
||||
xormEngine.SetMaxOpenConns(setting.Database.MaxOpenConns)
|
||||
xormEngine.SetMaxIdleConns(setting.Database.MaxIdleConns)
|
||||
xormEngine.SetConnMaxLifetime(setting.Database.ConnMaxLifetime)
|
||||
xormEngine.SetDefaultContext(ctx)
|
||||
|
||||
if setting.Database.SlowQueryThreshold > 0 {
|
||||
xormEngine.AddHook(&SlowQueryHook{
|
||||
Threshold: setting.Database.SlowQueryThreshold,
|
||||
Logger: log.GetLogger("xorm"),
|
||||
})
|
||||
}
|
||||
|
||||
SetDefaultEngine(ctx, xormEngine)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetDefaultEngine sets the default engine for db
|
||||
func SetDefaultEngine(ctx context.Context, eng *xorm.Engine) {
|
||||
x = eng
|
||||
DefaultContext = &Context{Context: ctx, engine: x}
|
||||
}
|
||||
|
||||
// UnsetDefaultEngine closes and unsets the default engine
|
||||
// We hope the SetDefaultEngine and UnsetDefaultEngine can be paired, but it's impossible now,
|
||||
// there are many calls to InitEngine -> SetDefaultEngine directly to overwrite the `x` and DefaultContext without close
|
||||
// Global database engine related functions are all racy and there is no graceful close right now.
|
||||
func UnsetDefaultEngine() {
|
||||
if x != nil {
|
||||
_ = x.Close()
|
||||
x = nil
|
||||
}
|
||||
DefaultContext = nil
|
||||
}
|
||||
|
||||
// InitEngineWithMigration initializes a new xorm.Engine and sets it as the db.DefaultContext
|
||||
// This function must never call .Sync() if the provided migration function fails.
|
||||
// When called from the "doctor" command, the migration function is a version check
|
||||
// that prevents the doctor from fixing anything in the database if the migration level
|
||||
// is different from the expected value.
|
||||
func InitEngineWithMigration(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err error) {
|
||||
if err = InitEngine(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = x.Ping(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
preprocessDatabaseCollation(x)
|
||||
|
||||
// We have to run migrateFunc here in case the user is re-running installation on a previously created DB.
|
||||
// If we do not then table schemas will be changed and there will be conflicts when the migrations run properly.
|
||||
//
|
||||
// Installation should only be being re-run if users want to recover an old database.
|
||||
// However, we should think carefully about should we support re-install on an installed instance,
|
||||
// as there may be other problems due to secret reinitialization.
|
||||
if err = migrateFunc(x); err != nil {
|
||||
return fmt.Errorf("migrate: %w", err)
|
||||
}
|
||||
|
||||
if err = SyncAllTables(); err != nil {
|
||||
return fmt.Errorf("sync database struct error: %w", err)
|
||||
}
|
||||
|
||||
for _, initFunc := range initFuncs {
|
||||
if err := initFunc(); err != nil {
|
||||
return fmt.Errorf("initFunc failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NamesToBean return a list of beans or an error
|
||||
func NamesToBean(names ...string) ([]any, error) {
|
||||
beans := []any{}
|
||||
if len(names) == 0 {
|
||||
beans = append(beans, tables...)
|
||||
beans = append(beans, registeredModels...)
|
||||
return beans, nil
|
||||
}
|
||||
// Need to map provided names to beans...
|
||||
beanMap := make(map[string]any)
|
||||
for _, bean := range tables {
|
||||
for _, bean := range registeredModels {
|
||||
beanMap[strings.ToLower(reflect.Indirect(reflect.ValueOf(bean)).Type().Name())] = bean
|
||||
beanMap[strings.ToLower(x.TableName(bean))] = bean
|
||||
beanMap[strings.ToLower(x.TableName(bean, true))] = bean
|
||||
beanMap[strings.ToLower(xormEngine.TableName(bean))] = bean
|
||||
beanMap[strings.ToLower(xormEngine.TableName(bean, true))] = bean
|
||||
}
|
||||
|
||||
gotBean := make(map[any]bool)
|
||||
@ -247,36 +111,9 @@ func NamesToBean(names ...string) ([]any, error) {
|
||||
return beans, nil
|
||||
}
|
||||
|
||||
// DumpDatabase dumps all data from database according the special database SQL syntax to file system.
|
||||
func DumpDatabase(filePath, dbType string) error {
|
||||
var tbs []*schemas.Table
|
||||
for _, t := range tables {
|
||||
t, err := x.TableInfo(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tbs = append(tbs, t)
|
||||
}
|
||||
|
||||
type Version struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Version int64
|
||||
}
|
||||
t, err := x.TableInfo(&Version{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tbs = append(tbs, t)
|
||||
|
||||
if len(dbType) > 0 {
|
||||
return x.DumpTablesToFile(tbs, filePath, schemas.DBType(dbType))
|
||||
}
|
||||
return x.DumpTablesToFile(tbs, filePath)
|
||||
}
|
||||
|
||||
// MaxBatchInsertSize returns the table's max batch insert size
|
||||
func MaxBatchInsertSize(bean any) int {
|
||||
t, err := x.TableInfo(bean)
|
||||
t, err := xormEngine.TableInfo(bean)
|
||||
if err != nil {
|
||||
return 50
|
||||
}
|
||||
@ -285,18 +122,18 @@ func MaxBatchInsertSize(bean any) int {
|
||||
|
||||
// IsTableNotEmpty returns true if table has at least one record
|
||||
func IsTableNotEmpty(beanOrTableName any) (bool, error) {
|
||||
return x.Table(beanOrTableName).Exist()
|
||||
return xormEngine.Table(beanOrTableName).Exist()
|
||||
}
|
||||
|
||||
// DeleteAllRecords will delete all the records of this table
|
||||
func DeleteAllRecords(tableName string) error {
|
||||
_, err := x.Exec(fmt.Sprintf("DELETE FROM %s", tableName))
|
||||
_, err := xormEngine.Exec(fmt.Sprintf("DELETE FROM %s", tableName))
|
||||
return err
|
||||
}
|
||||
|
||||
// GetMaxID will return max id of the table
|
||||
func GetMaxID(beanOrTableName any) (maxID int64, err error) {
|
||||
_, err = x.Select("MAX(id)").Table(beanOrTableName).Get(&maxID)
|
||||
_, err = xormEngine.Select("MAX(id)").Table(beanOrTableName).Get(&maxID)
|
||||
return maxID, err
|
||||
}
|
||||
|
||||
@ -308,24 +145,3 @@ func SetLogSQL(ctx context.Context, on bool) {
|
||||
sess.Engine().ShowSQL(on)
|
||||
}
|
||||
}
|
||||
|
||||
type SlowQueryHook struct {
|
||||
Threshold time.Duration
|
||||
Logger log.Logger
|
||||
}
|
||||
|
||||
var _ contexts.Hook = &SlowQueryHook{}
|
||||
|
||||
func (SlowQueryHook) BeforeProcess(c *contexts.ContextHook) (context.Context, error) {
|
||||
return c.Ctx, nil
|
||||
}
|
||||
|
||||
func (h *SlowQueryHook) AfterProcess(c *contexts.ContextHook) error {
|
||||
if c.ExecuteTime >= h.Threshold {
|
||||
// 8 is the amount of skips passed to runtime.Caller, so that in the log the correct function
|
||||
// is being displayed (the function that ultimately wants to execute the query in the code)
|
||||
// instead of the function of the slow query hook being called.
|
||||
h.Logger.Log(8, log.WARN, "[Slow SQL Query] %s %v - %v", c.SQL, c.Args, c.ExecuteTime)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
33
models/db/engine_dump.go
Normal file
33
models/db/engine_dump.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package db
|
||||
|
||||
import "xorm.io/xorm/schemas"
|
||||
|
||||
// DumpDatabase dumps all data from database according the special database SQL syntax to file system.
|
||||
func DumpDatabase(filePath, dbType string) error {
|
||||
var tbs []*schemas.Table
|
||||
for _, t := range registeredModels {
|
||||
t, err := xormEngine.TableInfo(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tbs = append(tbs, t)
|
||||
}
|
||||
|
||||
type Version struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
Version int64
|
||||
}
|
||||
t, err := xormEngine.TableInfo(&Version{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tbs = append(tbs, t)
|
||||
|
||||
if dbType != "" {
|
||||
return xormEngine.DumpTablesToFile(tbs, filePath, schemas.DBType(dbType))
|
||||
}
|
||||
return xormEngine.DumpTablesToFile(tbs, filePath)
|
||||
}
|
34
models/db/engine_hook.go
Normal file
34
models/db/engine_hook.go
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"xorm.io/xorm/contexts"
|
||||
)
|
||||
|
||||
type SlowQueryHook struct {
|
||||
Threshold time.Duration
|
||||
Logger log.Logger
|
||||
}
|
||||
|
||||
var _ contexts.Hook = (*SlowQueryHook)(nil)
|
||||
|
||||
func (*SlowQueryHook) BeforeProcess(c *contexts.ContextHook) (context.Context, error) {
|
||||
return c.Ctx, nil
|
||||
}
|
||||
|
||||
func (h *SlowQueryHook) AfterProcess(c *contexts.ContextHook) error {
|
||||
if c.ExecuteTime >= h.Threshold {
|
||||
// 8 is the amount of skips passed to runtime.Caller, so that in the log the correct function
|
||||
// is being displayed (the function that ultimately wants to execute the query in the code)
|
||||
// instead of the function of the slow query hook being called.
|
||||
h.Logger.Log(8, log.WARN, "[Slow SQL Query] %s %v - %v", c.SQL, c.Args, c.ExecuteTime)
|
||||
}
|
||||
return nil
|
||||
}
|
140
models/db/engine_init.go
Normal file
140
models/db/engine_init.go
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/names"
|
||||
)
|
||||
|
||||
func init() {
|
||||
gonicNames := []string{"SSL", "UID"}
|
||||
for _, name := range gonicNames {
|
||||
names.LintGonicMapper[name] = true
|
||||
}
|
||||
}
|
||||
|
||||
// newXORMEngine returns a new XORM engine from the configuration
|
||||
func newXORMEngine() (*xorm.Engine, error) {
|
||||
connStr, err := setting.DBConnStr()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var engine *xorm.Engine
|
||||
|
||||
if setting.Database.Type.IsPostgreSQL() && len(setting.Database.Schema) > 0 {
|
||||
// OK whilst we sort out our schema issues - create a schema aware postgres
|
||||
registerPostgresSchemaDriver()
|
||||
engine, err = xorm.NewEngine("postgresschema", connStr)
|
||||
} else {
|
||||
engine, err = xorm.NewEngine(setting.Database.Type.String(), connStr)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if setting.Database.Type == "mysql" {
|
||||
engine.Dialect().SetParams(map[string]string{"rowFormat": "DYNAMIC"})
|
||||
} else if setting.Database.Type == "mssql" {
|
||||
engine.Dialect().SetParams(map[string]string{"DEFAULT_VARCHAR": "nvarchar"})
|
||||
}
|
||||
engine.SetSchema(setting.Database.Schema)
|
||||
return engine, nil
|
||||
}
|
||||
|
||||
// InitEngine initializes the xorm.Engine and sets it as db.DefaultContext
|
||||
func InitEngine(ctx context.Context) error {
|
||||
xe, err := newXORMEngine()
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "SQLite3 support") {
|
||||
return fmt.Errorf(`sqlite3 requires: -tags sqlite,sqlite_unlock_notify%s%w`, "\n", err)
|
||||
}
|
||||
return fmt.Errorf("failed to connect to database: %w", err)
|
||||
}
|
||||
|
||||
xe.SetMapper(names.GonicMapper{})
|
||||
// WARNING: for serv command, MUST remove the output to os.stdout,
|
||||
// so use log file to instead print to stdout.
|
||||
xe.SetLogger(NewXORMLogger(setting.Database.LogSQL))
|
||||
xe.ShowSQL(setting.Database.LogSQL)
|
||||
xe.SetMaxOpenConns(setting.Database.MaxOpenConns)
|
||||
xe.SetMaxIdleConns(setting.Database.MaxIdleConns)
|
||||
xe.SetConnMaxLifetime(setting.Database.ConnMaxLifetime)
|
||||
xe.SetDefaultContext(ctx)
|
||||
|
||||
if setting.Database.SlowQueryThreshold > 0 {
|
||||
xe.AddHook(&SlowQueryHook{
|
||||
Threshold: setting.Database.SlowQueryThreshold,
|
||||
Logger: log.GetLogger("xorm"),
|
||||
})
|
||||
}
|
||||
|
||||
SetDefaultEngine(ctx, xe)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetDefaultEngine sets the default engine for db
|
||||
func SetDefaultEngine(ctx context.Context, eng *xorm.Engine) {
|
||||
xormEngine = eng
|
||||
DefaultContext = &Context{Context: ctx, engine: xormEngine}
|
||||
}
|
||||
|
||||
// UnsetDefaultEngine closes and unsets the default engine
|
||||
// We hope the SetDefaultEngine and UnsetDefaultEngine can be paired, but it's impossible now,
|
||||
// there are many calls to InitEngine -> SetDefaultEngine directly to overwrite the `xormEngine` and DefaultContext without close
|
||||
// Global database engine related functions are all racy and there is no graceful close right now.
|
||||
func UnsetDefaultEngine() {
|
||||
if xormEngine != nil {
|
||||
_ = xormEngine.Close()
|
||||
xormEngine = nil
|
||||
}
|
||||
DefaultContext = nil
|
||||
}
|
||||
|
||||
// InitEngineWithMigration initializes a new xorm.Engine and sets it as the db.DefaultContext
|
||||
// This function must never call .Sync() if the provided migration function fails.
|
||||
// When called from the "doctor" command, the migration function is a version check
|
||||
// that prevents the doctor from fixing anything in the database if the migration level
|
||||
// is different from the expected value.
|
||||
func InitEngineWithMigration(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err error) {
|
||||
if err = InitEngine(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = xormEngine.Ping(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
preprocessDatabaseCollation(xormEngine)
|
||||
|
||||
// We have to run migrateFunc here in case the user is re-running installation on a previously created DB.
|
||||
// If we do not then table schemas will be changed and there will be conflicts when the migrations run properly.
|
||||
//
|
||||
// Installation should only be being re-run if users want to recover an old database.
|
||||
// However, we should think carefully about should we support re-install on an installed instance,
|
||||
// as there may be other problems due to secret reinitialization.
|
||||
if err = migrateFunc(xormEngine); err != nil {
|
||||
return fmt.Errorf("migrate: %w", err)
|
||||
}
|
||||
|
||||
if err = SyncAllTables(); err != nil {
|
||||
return fmt.Errorf("sync database struct error: %w", err)
|
||||
}
|
||||
|
||||
for _, initFunc := range registeredInitFuncs {
|
||||
if err := initFunc(); err != nil {
|
||||
return fmt.Errorf("initFunc failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -38,8 +38,6 @@ func TestIterate(t *testing.T) {
|
||||
if !has {
|
||||
return db.ErrNotExist{Resource: "repo_unit", ID: repoUnit.ID}
|
||||
}
|
||||
assert.EqualValues(t, repoUnit.RepoID, repoUnit.RepoID)
|
||||
assert.EqualValues(t, repoUnit.CreatedUnix, repoUnit.CreatedUnix)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
@ -16,7 +16,7 @@ var (
|
||||
// ErrNameEmpty name is empty error
|
||||
ErrNameEmpty = util.SilentWrap{Message: "name is empty", Err: util.ErrInvalidArgument}
|
||||
|
||||
// AlphaDashDotPattern characters prohibited in a user name (anything except A-Za-z0-9_.-)
|
||||
// AlphaDashDotPattern characters prohibited in a username (anything except A-Za-z0-9_.-)
|
||||
AlphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
|
||||
)
|
||||
|
||||
|
@ -26,8 +26,10 @@ const (
|
||||
SearchOrderByForksReverse SearchOrderBy = "num_forks DESC"
|
||||
)
|
||||
|
||||
const (
|
||||
// Which means a condition to filter the records which don't match any id.
|
||||
// It's different from zero which means the condition could be ignored.
|
||||
NoConditionID = -1
|
||||
)
|
||||
// NoConditionID means a condition to filter the records which don't match any id.
|
||||
// eg: "milestone_id=-1" means "find the items without any milestone.
|
||||
const NoConditionID int64 = -1
|
||||
|
||||
// NonExistingID means a condition to match no result (eg: a non-existing user)
|
||||
// It doesn't use -1 or -2 because they are used as builtin users.
|
||||
const NonExistingID int64 = -1000000
|
||||
|
@ -17,11 +17,11 @@ func CountBadSequences(_ context.Context) (int64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
sess := xormEngine.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
var sequences []string
|
||||
schema := x.Dialect().URI().Schema
|
||||
schema := xormEngine.Dialect().URI().Schema
|
||||
|
||||
sess.Engine().SetSchema("")
|
||||
if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE 'tmp_recreate__%_id_seq%' AND sequence_catalog = ?", setting.Database.Name).Find(&sequences); err != nil {
|
||||
@ -38,7 +38,7 @@ func FixBadSequences(_ context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
sess := xormEngine.NewSession()
|
||||
defer sess.Close()
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
|
552
models/error.go
552
models/error.go
@ -1,552 +0,0 @@
|
||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
|
||||
type ErrUserOwnRepos struct {
|
||||
UID int64
|
||||
}
|
||||
|
||||
// IsErrUserOwnRepos checks if an error is a ErrUserOwnRepos.
|
||||
func IsErrUserOwnRepos(err error) bool {
|
||||
_, ok := err.(ErrUserOwnRepos)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserOwnRepos) Error() string {
|
||||
return fmt.Sprintf("user still has ownership of repositories [uid: %d]", err.UID)
|
||||
}
|
||||
|
||||
// ErrUserHasOrgs represents a "UserHasOrgs" kind of error.
|
||||
type ErrUserHasOrgs struct {
|
||||
UID int64
|
||||
}
|
||||
|
||||
// IsErrUserHasOrgs checks if an error is a ErrUserHasOrgs.
|
||||
func IsErrUserHasOrgs(err error) bool {
|
||||
_, ok := err.(ErrUserHasOrgs)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserHasOrgs) Error() string {
|
||||
return fmt.Sprintf("user still has membership of organizations [uid: %d]", err.UID)
|
||||
}
|
||||
|
||||
// ErrUserOwnPackages notifies that the user (still) owns the packages.
|
||||
type ErrUserOwnPackages struct {
|
||||
UID int64
|
||||
}
|
||||
|
||||
// IsErrUserOwnPackages checks if an error is an ErrUserOwnPackages.
|
||||
func IsErrUserOwnPackages(err error) bool {
|
||||
_, ok := err.(ErrUserOwnPackages)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserOwnPackages) Error() string {
|
||||
return fmt.Sprintf("user still has ownership of packages [uid: %d]", err.UID)
|
||||
}
|
||||
|
||||
// ErrDeleteLastAdminUser represents a "DeleteLastAdminUser" kind of error.
|
||||
type ErrDeleteLastAdminUser struct {
|
||||
UID int64
|
||||
}
|
||||
|
||||
// IsErrDeleteLastAdminUser checks if an error is a ErrDeleteLastAdminUser.
|
||||
func IsErrDeleteLastAdminUser(err error) bool {
|
||||
_, ok := err.(ErrDeleteLastAdminUser)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrDeleteLastAdminUser) Error() string {
|
||||
return fmt.Sprintf("can not delete the last admin user [uid: %d]", err.UID)
|
||||
}
|
||||
|
||||
// ErrNoPendingRepoTransfer is an error type for repositories without a pending
|
||||
// transfer request
|
||||
type ErrNoPendingRepoTransfer struct {
|
||||
RepoID int64
|
||||
}
|
||||
|
||||
func (err ErrNoPendingRepoTransfer) Error() string {
|
||||
return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", err.RepoID)
|
||||
}
|
||||
|
||||
// IsErrNoPendingTransfer is an error type when a repository has no pending
|
||||
// transfers
|
||||
func IsErrNoPendingTransfer(err error) bool {
|
||||
_, ok := err.(ErrNoPendingRepoTransfer)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrNoPendingRepoTransfer) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrRepoTransferInProgress represents the state of a repository that has an
|
||||
// ongoing transfer
|
||||
type ErrRepoTransferInProgress struct {
|
||||
Uname string
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsErrRepoTransferInProgress checks if an error is a ErrRepoTransferInProgress.
|
||||
func IsErrRepoTransferInProgress(err error) bool {
|
||||
_, ok := err.(ErrRepoTransferInProgress)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrRepoTransferInProgress) Error() string {
|
||||
return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name)
|
||||
}
|
||||
|
||||
func (err ErrRepoTransferInProgress) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
|
||||
type ErrInvalidCloneAddr struct {
|
||||
Host string
|
||||
IsURLError bool
|
||||
IsInvalidPath bool
|
||||
IsProtocolInvalid bool
|
||||
IsPermissionDenied bool
|
||||
LocalPath bool
|
||||
}
|
||||
|
||||
// IsErrInvalidCloneAddr checks if an error is a ErrInvalidCloneAddr.
|
||||
func IsErrInvalidCloneAddr(err error) bool {
|
||||
_, ok := err.(*ErrInvalidCloneAddr)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err *ErrInvalidCloneAddr) Error() string {
|
||||
if err.IsInvalidPath {
|
||||
return fmt.Sprintf("migration/cloning from '%s' is not allowed: the provided path is invalid", err.Host)
|
||||
}
|
||||
if err.IsProtocolInvalid {
|
||||
return fmt.Sprintf("migration/cloning from '%s' is not allowed: the provided url protocol is not allowed", err.Host)
|
||||
}
|
||||
if err.IsPermissionDenied {
|
||||
return fmt.Sprintf("migration/cloning from '%s' is not allowed.", err.Host)
|
||||
}
|
||||
if err.IsURLError {
|
||||
return fmt.Sprintf("migration/cloning from '%s' is not allowed: the provided url is invalid", err.Host)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("migration/cloning from '%s' is not allowed", err.Host)
|
||||
}
|
||||
|
||||
func (err *ErrInvalidCloneAddr) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrUpdateTaskNotExist represents a "UpdateTaskNotExist" kind of error.
|
||||
type ErrUpdateTaskNotExist struct {
|
||||
UUID string
|
||||
}
|
||||
|
||||
// IsErrUpdateTaskNotExist checks if an error is a ErrUpdateTaskNotExist.
|
||||
func IsErrUpdateTaskNotExist(err error) bool {
|
||||
_, ok := err.(ErrUpdateTaskNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUpdateTaskNotExist) Error() string {
|
||||
return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID)
|
||||
}
|
||||
|
||||
func (err ErrUpdateTaskNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrInvalidTagName represents a "InvalidTagName" kind of error.
|
||||
type ErrInvalidTagName struct {
|
||||
TagName string
|
||||
}
|
||||
|
||||
// IsErrInvalidTagName checks if an error is a ErrInvalidTagName.
|
||||
func IsErrInvalidTagName(err error) bool {
|
||||
_, ok := err.(ErrInvalidTagName)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrInvalidTagName) Error() string {
|
||||
return fmt.Sprintf("release tag name is not valid [tag_name: %s]", err.TagName)
|
||||
}
|
||||
|
||||
func (err ErrInvalidTagName) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrProtectedTagName represents a "ProtectedTagName" kind of error.
|
||||
type ErrProtectedTagName struct {
|
||||
TagName string
|
||||
}
|
||||
|
||||
// IsErrProtectedTagName checks if an error is a ErrProtectedTagName.
|
||||
func IsErrProtectedTagName(err error) bool {
|
||||
_, ok := err.(ErrProtectedTagName)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrProtectedTagName) Error() string {
|
||||
return fmt.Sprintf("release tag name is protected [tag_name: %s]", err.TagName)
|
||||
}
|
||||
|
||||
func (err ErrProtectedTagName) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrRepoFileAlreadyExists represents a "RepoFileAlreadyExist" kind of error.
|
||||
type ErrRepoFileAlreadyExists struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// IsErrRepoFileAlreadyExists checks if an error is a ErrRepoFileAlreadyExists.
|
||||
func IsErrRepoFileAlreadyExists(err error) bool {
|
||||
_, ok := err.(ErrRepoFileAlreadyExists)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrRepoFileAlreadyExists) Error() string {
|
||||
return fmt.Sprintf("repository file already exists [path: %s]", err.Path)
|
||||
}
|
||||
|
||||
func (err ErrRepoFileAlreadyExists) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrRepoFileDoesNotExist represents a "RepoFileDoesNotExist" kind of error.
|
||||
type ErrRepoFileDoesNotExist struct {
|
||||
Path string
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsErrRepoFileDoesNotExist checks if an error is a ErrRepoDoesNotExist.
|
||||
func IsErrRepoFileDoesNotExist(err error) bool {
|
||||
_, ok := err.(ErrRepoFileDoesNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrRepoFileDoesNotExist) Error() string {
|
||||
return fmt.Sprintf("repository file does not exist [path: %s]", err.Path)
|
||||
}
|
||||
|
||||
func (err ErrRepoFileDoesNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrFilenameInvalid represents a "FilenameInvalid" kind of error.
|
||||
type ErrFilenameInvalid struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// IsErrFilenameInvalid checks if an error is an ErrFilenameInvalid.
|
||||
func IsErrFilenameInvalid(err error) bool {
|
||||
_, ok := err.(ErrFilenameInvalid)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrFilenameInvalid) Error() string {
|
||||
return fmt.Sprintf("path contains a malformed path component [path: %s]", err.Path)
|
||||
}
|
||||
|
||||
func (err ErrFilenameInvalid) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrUserCannotCommit represents "UserCannotCommit" kind of error.
|
||||
type ErrUserCannotCommit struct {
|
||||
UserName string
|
||||
}
|
||||
|
||||
// IsErrUserCannotCommit checks if an error is an ErrUserCannotCommit.
|
||||
func IsErrUserCannotCommit(err error) bool {
|
||||
_, ok := err.(ErrUserCannotCommit)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserCannotCommit) Error() string {
|
||||
return fmt.Sprintf("user cannot commit to repo [user: %s]", err.UserName)
|
||||
}
|
||||
|
||||
func (err ErrUserCannotCommit) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrFilePathInvalid represents a "FilePathInvalid" kind of error.
|
||||
type ErrFilePathInvalid struct {
|
||||
Message string
|
||||
Path string
|
||||
Name string
|
||||
Type git.EntryMode
|
||||
}
|
||||
|
||||
// IsErrFilePathInvalid checks if an error is an ErrFilePathInvalid.
|
||||
func IsErrFilePathInvalid(err error) bool {
|
||||
_, ok := err.(ErrFilePathInvalid)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrFilePathInvalid) Error() string {
|
||||
if err.Message != "" {
|
||||
return err.Message
|
||||
}
|
||||
return fmt.Sprintf("path is invalid [path: %s]", err.Path)
|
||||
}
|
||||
|
||||
func (err ErrFilePathInvalid) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrFilePathProtected represents a "FilePathProtected" kind of error.
|
||||
type ErrFilePathProtected struct {
|
||||
Message string
|
||||
Path string
|
||||
}
|
||||
|
||||
// IsErrFilePathProtected checks if an error is an ErrFilePathProtected.
|
||||
func IsErrFilePathProtected(err error) bool {
|
||||
_, ok := err.(ErrFilePathProtected)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrFilePathProtected) Error() string {
|
||||
if err.Message != "" {
|
||||
return err.Message
|
||||
}
|
||||
return fmt.Sprintf("path is protected and can not be changed [path: %s]", err.Path)
|
||||
}
|
||||
|
||||
func (err ErrFilePathProtected) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrDisallowedToMerge represents an error that a branch is protected and the current user is not allowed to modify it.
|
||||
type ErrDisallowedToMerge struct {
|
||||
Reason string
|
||||
}
|
||||
|
||||
// IsErrDisallowedToMerge checks if an error is an ErrDisallowedToMerge.
|
||||
func IsErrDisallowedToMerge(err error) bool {
|
||||
_, ok := err.(ErrDisallowedToMerge)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrDisallowedToMerge) Error() string {
|
||||
return fmt.Sprintf("not allowed to merge [reason: %s]", err.Reason)
|
||||
}
|
||||
|
||||
func (err ErrDisallowedToMerge) Unwrap() error {
|
||||
return util.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// ErrTagAlreadyExists represents an error that tag with such name already exists.
|
||||
type ErrTagAlreadyExists struct {
|
||||
TagName string
|
||||
}
|
||||
|
||||
// IsErrTagAlreadyExists checks if an error is an ErrTagAlreadyExists.
|
||||
func IsErrTagAlreadyExists(err error) bool {
|
||||
_, ok := err.(ErrTagAlreadyExists)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrTagAlreadyExists) Error() string {
|
||||
return fmt.Sprintf("tag already exists [name: %s]", err.TagName)
|
||||
}
|
||||
|
||||
func (err ErrTagAlreadyExists) Unwrap() error {
|
||||
return util.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// ErrSHADoesNotMatch represents a "SHADoesNotMatch" kind of error.
|
||||
type ErrSHADoesNotMatch struct {
|
||||
Path string
|
||||
GivenSHA string
|
||||
CurrentSHA string
|
||||
}
|
||||
|
||||
// IsErrSHADoesNotMatch checks if an error is a ErrSHADoesNotMatch.
|
||||
func IsErrSHADoesNotMatch(err error) bool {
|
||||
_, ok := err.(ErrSHADoesNotMatch)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrSHADoesNotMatch) Error() string {
|
||||
return fmt.Sprintf("sha does not match [given: %s, expected: %s]", err.GivenSHA, err.CurrentSHA)
|
||||
}
|
||||
|
||||
// ErrSHANotFound represents a "SHADoesNotMatch" kind of error.
|
||||
type ErrSHANotFound struct {
|
||||
SHA string
|
||||
}
|
||||
|
||||
// IsErrSHANotFound checks if an error is a ErrSHANotFound.
|
||||
func IsErrSHANotFound(err error) bool {
|
||||
_, ok := err.(ErrSHANotFound)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrSHANotFound) Error() string {
|
||||
return fmt.Sprintf("sha not found [%s]", err.SHA)
|
||||
}
|
||||
|
||||
func (err ErrSHANotFound) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// ErrCommitIDDoesNotMatch represents a "CommitIDDoesNotMatch" kind of error.
|
||||
type ErrCommitIDDoesNotMatch struct {
|
||||
GivenCommitID string
|
||||
CurrentCommitID string
|
||||
}
|
||||
|
||||
// IsErrCommitIDDoesNotMatch checks if an error is a ErrCommitIDDoesNotMatch.
|
||||
func IsErrCommitIDDoesNotMatch(err error) bool {
|
||||
_, ok := err.(ErrCommitIDDoesNotMatch)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrCommitIDDoesNotMatch) Error() string {
|
||||
return fmt.Sprintf("file CommitID does not match [given: %s, expected: %s]", err.GivenCommitID, err.CurrentCommitID)
|
||||
}
|
||||
|
||||
// ErrSHAOrCommitIDNotProvided represents a "SHAOrCommitIDNotProvided" kind of error.
|
||||
type ErrSHAOrCommitIDNotProvided struct{}
|
||||
|
||||
// IsErrSHAOrCommitIDNotProvided checks if an error is a ErrSHAOrCommitIDNotProvided.
|
||||
func IsErrSHAOrCommitIDNotProvided(err error) bool {
|
||||
_, ok := err.(ErrSHAOrCommitIDNotProvided)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrSHAOrCommitIDNotProvided) Error() string {
|
||||
return "a SHA or commit ID must be proved when updating a file"
|
||||
}
|
||||
|
||||
// ErrInvalidMergeStyle represents an error if merging with disabled merge strategy
|
||||
type ErrInvalidMergeStyle struct {
|
||||
ID int64
|
||||
Style repo_model.MergeStyle
|
||||
}
|
||||
|
||||
// IsErrInvalidMergeStyle checks if an error is a ErrInvalidMergeStyle.
|
||||
func IsErrInvalidMergeStyle(err error) bool {
|
||||
_, ok := err.(ErrInvalidMergeStyle)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrInvalidMergeStyle) Error() string {
|
||||
return fmt.Sprintf("merge strategy is not allowed or is invalid [repo_id: %d, strategy: %s]",
|
||||
err.ID, err.Style)
|
||||
}
|
||||
|
||||
func (err ErrInvalidMergeStyle) Unwrap() error {
|
||||
return util.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// ErrMergeConflicts represents an error if merging fails with a conflict
|
||||
type ErrMergeConflicts struct {
|
||||
Style repo_model.MergeStyle
|
||||
StdOut string
|
||||
StdErr string
|
||||
Err error
|
||||
}
|
||||
|
||||
// IsErrMergeConflicts checks if an error is a ErrMergeConflicts.
|
||||
func IsErrMergeConflicts(err error) bool {
|
||||
_, ok := err.(ErrMergeConflicts)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrMergeConflicts) Error() string {
|
||||
return fmt.Sprintf("Merge Conflict Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
|
||||
}
|
||||
|
||||
// ErrMergeUnrelatedHistories represents an error if merging fails due to unrelated histories
|
||||
type ErrMergeUnrelatedHistories struct {
|
||||
Style repo_model.MergeStyle
|
||||
StdOut string
|
||||
StdErr string
|
||||
Err error
|
||||
}
|
||||
|
||||
// IsErrMergeUnrelatedHistories checks if an error is a ErrMergeUnrelatedHistories.
|
||||
func IsErrMergeUnrelatedHistories(err error) bool {
|
||||
_, ok := err.(ErrMergeUnrelatedHistories)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrMergeUnrelatedHistories) Error() string {
|
||||
return fmt.Sprintf("Merge UnrelatedHistories Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
|
||||
}
|
||||
|
||||
// ErrMergeDivergingFastForwardOnly represents an error if a fast-forward-only merge fails because the branches diverge
|
||||
type ErrMergeDivergingFastForwardOnly struct {
|
||||
StdOut string
|
||||
StdErr string
|
||||
Err error
|
||||
}
|
||||
|
||||
// IsErrMergeDivergingFastForwardOnly checks if an error is a ErrMergeDivergingFastForwardOnly.
|
||||
func IsErrMergeDivergingFastForwardOnly(err error) bool {
|
||||
_, ok := err.(ErrMergeDivergingFastForwardOnly)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrMergeDivergingFastForwardOnly) Error() string {
|
||||
return fmt.Sprintf("Merge DivergingFastForwardOnly Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
|
||||
}
|
||||
|
||||
// ErrRebaseConflicts represents an error if rebase fails with a conflict
|
||||
type ErrRebaseConflicts struct {
|
||||
Style repo_model.MergeStyle
|
||||
CommitSHA string
|
||||
StdOut string
|
||||
StdErr string
|
||||
Err error
|
||||
}
|
||||
|
||||
// IsErrRebaseConflicts checks if an error is a ErrRebaseConflicts.
|
||||
func IsErrRebaseConflicts(err error) bool {
|
||||
_, ok := err.(ErrRebaseConflicts)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrRebaseConflicts) Error() string {
|
||||
return fmt.Sprintf("Rebase Error: %v: Whilst Rebasing: %s\n%s\n%s", err.Err, err.CommitSHA, err.StdErr, err.StdOut)
|
||||
}
|
||||
|
||||
// ErrPullRequestHasMerged represents a "PullRequestHasMerged"-error
|
||||
type ErrPullRequestHasMerged struct {
|
||||
ID int64
|
||||
IssueID int64
|
||||
HeadRepoID int64
|
||||
BaseRepoID int64
|
||||
HeadBranch string
|
||||
BaseBranch string
|
||||
}
|
||||
|
||||
// IsErrPullRequestHasMerged checks if an error is a ErrPullRequestHasMerged.
|
||||
func IsErrPullRequestHasMerged(err error) bool {
|
||||
_, ok := err.(ErrPullRequestHasMerged)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Error does pretty-printing :D
|
||||
func (err ErrPullRequestHasMerged) Error() string {
|
||||
return fmt.Sprintf("pull request has merged [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]",
|
||||
err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch)
|
||||
}
|
@ -36,3 +36,41 @@
|
||||
updated: 1683636626
|
||||
need_approval: 0
|
||||
approved_by: 0
|
||||
-
|
||||
id: 793
|
||||
title: "job output"
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
workflow_id: "test.yaml"
|
||||
index: 189
|
||||
trigger_user_id: 1
|
||||
ref: "refs/heads/master"
|
||||
commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
|
||||
event: "push"
|
||||
is_fork_pull_request: 0
|
||||
status: 1
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
created: 1683636108
|
||||
updated: 1683636626
|
||||
need_approval: 0
|
||||
approved_by: 0
|
||||
-
|
||||
id: 794
|
||||
title: "job output"
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
workflow_id: "test.yaml"
|
||||
index: 190
|
||||
trigger_user_id: 1
|
||||
ref: "refs/heads/test"
|
||||
commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
|
||||
event: "push"
|
||||
is_fork_pull_request: 0
|
||||
status: 1
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
created: 1683636108
|
||||
updated: 1683636626
|
||||
need_approval: 0
|
||||
approved_by: 0
|
||||
|
@ -26,3 +26,46 @@
|
||||
status: 1
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
-
|
||||
id: 194
|
||||
run_id: 793
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: 0
|
||||
name: job1 (1)
|
||||
attempt: 1
|
||||
job_id: job1
|
||||
task_id: 49
|
||||
status: 1
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
-
|
||||
id: 195
|
||||
run_id: 793
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: 0
|
||||
name: job1 (2)
|
||||
attempt: 1
|
||||
job_id: job1
|
||||
task_id: 50
|
||||
status: 1
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
-
|
||||
id: 196
|
||||
run_id: 793
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: 0
|
||||
name: job2
|
||||
attempt: 1
|
||||
job_id: job2
|
||||
needs: '["job1"]'
|
||||
task_id: 51
|
||||
status: 5
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
|
@ -57,3 +57,63 @@
|
||||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: 0
|
||||
-
|
||||
id: 49
|
||||
job_id: 194
|
||||
attempt: 1
|
||||
runner_id: 1
|
||||
status: 1 # success
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: 0
|
||||
token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784220
|
||||
token_salt: ffffffffff
|
||||
token_last_eight: ffffffff
|
||||
log_filename: artifact-test2/2f/47.log
|
||||
log_in_storage: 1
|
||||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: 0
|
||||
-
|
||||
id: 50
|
||||
job_id: 195
|
||||
attempt: 1
|
||||
runner_id: 1
|
||||
status: 1 # success
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: 0
|
||||
token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784221
|
||||
token_salt: ffffffffff
|
||||
token_last_eight: ffffffff
|
||||
log_filename: artifact-test2/2f/47.log
|
||||
log_in_storage: 1
|
||||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: 0
|
||||
-
|
||||
id: 51
|
||||
job_id: 196
|
||||
attempt: 1
|
||||
runner_id: 1
|
||||
status: 6 # running
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: 0
|
||||
token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784222
|
||||
token_salt: ffffffffff
|
||||
token_last_eight: ffffffff
|
||||
log_filename: artifact-test2/2f/47.log
|
||||
log_in_storage: 1
|
||||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: 0
|
||||
|
20
models/fixtures/action_task_output.yml
Normal file
20
models/fixtures/action_task_output.yml
Normal file
@ -0,0 +1,20 @@
|
||||
-
|
||||
id: 1
|
||||
task_id: 49
|
||||
output_key: output_a
|
||||
output_value: abc
|
||||
-
|
||||
id: 2
|
||||
task_id: 49
|
||||
output_key: output_b
|
||||
output_value: ''
|
||||
-
|
||||
id: 3
|
||||
task_id: 50
|
||||
output_key: output_a
|
||||
output_value: ''
|
||||
-
|
||||
id: 4
|
||||
task_id: 50
|
||||
output_key: output_b
|
||||
output_value: bbb
|
@ -81,3 +81,15 @@
|
||||
is_deleted: false
|
||||
deleted_by_id: 0
|
||||
deleted_unix: 0
|
||||
|
||||
-
|
||||
id: 15
|
||||
repo_id: 4
|
||||
name: 'master'
|
||||
commit_id: 'c7cd3cd144e6d23c9d6f3d07e52b2c1a956e0338'
|
||||
commit_message: 'add Readme'
|
||||
commit_time: 1588147171
|
||||
pusher_id: 13
|
||||
is_deleted: false
|
||||
deleted_by_id: 0
|
||||
deleted_unix: 0
|
||||
|
@ -96,3 +96,14 @@
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
archived_unix: 0
|
||||
|
||||
-
|
||||
id: 10
|
||||
repo_id: 3
|
||||
org_id: 0
|
||||
name: repo3label1
|
||||
color: '#112233'
|
||||
exclusive: false
|
||||
num_issues: 0
|
||||
num_closed_issues: 0
|
||||
archived_unix: 0
|
||||
|
@ -2,23 +2,23 @@
|
||||
id: 1
|
||||
repo_id: 4
|
||||
name_pattern: /v.+/
|
||||
allowlist_user_i_ds: []
|
||||
allowlist_team_i_ds: []
|
||||
allowlist_user_i_ds: "[]"
|
||||
allowlist_team_i_ds: "[]"
|
||||
created_unix: 1715596037
|
||||
updated_unix: 1715596037
|
||||
-
|
||||
id: 2
|
||||
repo_id: 1
|
||||
name_pattern: v-*
|
||||
allowlist_user_i_ds: []
|
||||
allowlist_team_i_ds: []
|
||||
allowlist_user_i_ds: "[]"
|
||||
allowlist_team_i_ds: "[]"
|
||||
created_unix: 1715596037
|
||||
updated_unix: 1715596037
|
||||
-
|
||||
id: 3
|
||||
repo_id: 1
|
||||
name_pattern: v-1.1
|
||||
allowlist_user_i_ds: [2]
|
||||
allowlist_team_i_ds: []
|
||||
allowlist_user_i_ds: "[2]"
|
||||
allowlist_team_i_ds: "[]"
|
||||
created_unix: 1715596037
|
||||
updated_unix: 1715596037
|
||||
|
@ -4,6 +4,7 @@
|
||||
reviewer_id: 1
|
||||
issue_id: 2
|
||||
content: "Demo Review"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684810
|
||||
created_unix: 946684810
|
||||
-
|
||||
@ -12,6 +13,7 @@
|
||||
reviewer_id: 534543
|
||||
issue_id: 534543
|
||||
content: "Invalid Review #1"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684810
|
||||
created_unix: 946684810
|
||||
-
|
||||
@ -20,6 +22,7 @@
|
||||
reviewer_id: 1
|
||||
issue_id: 343545
|
||||
content: "Invalid Review #2"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684810
|
||||
created_unix: 946684810
|
||||
-
|
||||
@ -28,6 +31,7 @@
|
||||
reviewer_id: 1
|
||||
issue_id: 2
|
||||
content: "Pending Review"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684810
|
||||
created_unix: 946684810
|
||||
-
|
||||
@ -36,6 +40,7 @@
|
||||
reviewer_id: 1
|
||||
issue_id: 3
|
||||
content: "New review 1"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684810
|
||||
created_unix: 946684810
|
||||
-
|
||||
@ -61,8 +66,8 @@
|
||||
type: 1
|
||||
reviewer_id: 4
|
||||
issue_id: 3
|
||||
original_author_id: 0
|
||||
content: "New review 5"
|
||||
original_author_id: 0
|
||||
commit_id: 8091a55037cd59e47293aca02981b5a67076b364
|
||||
stale: true
|
||||
updated_unix: 946684813
|
||||
@ -73,9 +78,9 @@
|
||||
reviewer_id: 2
|
||||
issue_id: 3
|
||||
content: "New review 3 rejected"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684814
|
||||
created_unix: 946684814
|
||||
original_author_id: 0
|
||||
|
||||
-
|
||||
id: 10
|
||||
@ -83,6 +88,7 @@
|
||||
reviewer_id: 100
|
||||
issue_id: 3
|
||||
content: "a deleted user's review"
|
||||
original_author_id: 0
|
||||
official: true
|
||||
updated_unix: 946684815
|
||||
created_unix: 946684815
|
||||
@ -112,6 +118,7 @@
|
||||
reviewer_id: 5
|
||||
issue_id: 11
|
||||
content: "old review from user5"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684820
|
||||
created_unix: 946684820
|
||||
|
||||
@ -121,6 +128,7 @@
|
||||
reviewer_id: 5
|
||||
issue_id: 11
|
||||
content: "duplicate review from user5 (latest)"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684830
|
||||
created_unix: 946684830
|
||||
|
||||
@ -130,6 +138,7 @@
|
||||
reviewer_id: 6
|
||||
issue_id: 11
|
||||
content: "singular review from org6 and final review for this pr"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684831
|
||||
created_unix: 946684831
|
||||
|
||||
@ -139,6 +148,7 @@
|
||||
reviewer_id: 20
|
||||
issue_id: 20
|
||||
content: "review request for user20"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684832
|
||||
created_unix: 946684832
|
||||
|
||||
@ -148,6 +158,7 @@
|
||||
reviewer_id: 20
|
||||
issue_id: 20
|
||||
content: "review approved by user20"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684833
|
||||
created_unix: 946684833
|
||||
|
||||
@ -158,6 +169,7 @@
|
||||
reviewer_team_id: 5
|
||||
issue_id: 20
|
||||
content: "review request for team5"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684834
|
||||
created_unix: 946684834
|
||||
|
||||
@ -168,6 +180,7 @@
|
||||
reviewer_team_id: 0
|
||||
issue_id: 20
|
||||
content: "review request for user15"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684835
|
||||
created_unix: 946684835
|
||||
|
||||
@ -177,6 +190,7 @@
|
||||
reviewer_id: 1
|
||||
issue_id: 2
|
||||
content: "Review Comment"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684810
|
||||
created_unix: 946684810
|
||||
|
||||
@ -186,6 +200,7 @@
|
||||
reviewer_id: 5
|
||||
issue_id: 3
|
||||
content: "reviewed by user5"
|
||||
original_author_id: 0
|
||||
commit_id: 4a357436d925b5c974181ff12a994538ddc5a269
|
||||
updated_unix: 946684816
|
||||
created_unix: 946684816
|
||||
@ -196,5 +211,6 @@
|
||||
reviewer_id: 5
|
||||
issue_id: 3
|
||||
content: "review request for user5"
|
||||
original_author_id: 0
|
||||
updated_unix: 946684817
|
||||
created_unix: 946684817
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
@ -169,9 +170,22 @@ func GetBranch(ctx context.Context, repoID int64, branchName string) (*Branch, e
|
||||
return &branch, nil
|
||||
}
|
||||
|
||||
func GetBranches(ctx context.Context, repoID int64, branchNames []string) ([]*Branch, error) {
|
||||
func GetBranches(ctx context.Context, repoID int64, branchNames []string, includeDeleted bool) ([]*Branch, error) {
|
||||
branches := make([]*Branch, 0, len(branchNames))
|
||||
return branches, db.GetEngine(ctx).Where("repo_id=?", repoID).In("name", branchNames).Find(&branches)
|
||||
|
||||
sess := db.GetEngine(ctx).Where("repo_id=?", repoID).In("name", branchNames)
|
||||
if !includeDeleted {
|
||||
sess.And("is_deleted=?", false)
|
||||
}
|
||||
return branches, sess.Find(&branches)
|
||||
}
|
||||
|
||||
func BranchesToNamesSet(branches []*Branch) container.Set[string] {
|
||||
names := make(container.Set[string], len(branches))
|
||||
for _, branch := range branches {
|
||||
names.Add(branch.Name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
func AddBranches(ctx context.Context, branches []*Branch) error {
|
||||
|
@ -34,7 +34,7 @@ func TestGetCommitStatuses(t *testing.T) {
|
||||
SHA: sha1,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int(maxResults), 5)
|
||||
assert.Equal(t, 5, int(maxResults))
|
||||
assert.Len(t, statuses, 5)
|
||||
|
||||
assert.Equal(t, "ci/awesomeness", statuses[0].Context)
|
||||
@ -63,7 +63,7 @@ func TestGetCommitStatuses(t *testing.T) {
|
||||
SHA: sha1,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int(maxResults), 5)
|
||||
assert.Equal(t, 5, int(maxResults))
|
||||
assert.Empty(t, statuses)
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
@ -76,7 +75,7 @@ func TestBranchRuleMatch(t *testing.T) {
|
||||
infact = " not"
|
||||
}
|
||||
assert.EqualValues(t, kase.ExpectedMatch, pb.Match(kase.BranchName),
|
||||
fmt.Sprintf("%s should%s match %s but it is%s", kase.BranchName, should, kase.Rule, infact),
|
||||
"%s should%s match %s but it is%s", kase.BranchName, should, kase.Rule, infact,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +197,20 @@ func (t CommentType) HasMailReplySupport() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t CommentType) CountedAsConversation() bool {
|
||||
for _, ct := range ConversationCountedCommentType() {
|
||||
if t == ct {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ConversationCountedCommentType returns the comment types that are counted as a conversation
|
||||
func ConversationCountedCommentType() []CommentType {
|
||||
return []CommentType{CommentTypeComment, CommentTypeReview}
|
||||
}
|
||||
|
||||
// RoleInRepo presents the user's participation in the repo
|
||||
type RoleInRepo string
|
||||
|
||||
@ -592,26 +606,26 @@ func (c *Comment) LoadAttachments(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateAttachments update attachments by UUIDs for the comment
|
||||
func (c *Comment) UpdateAttachments(ctx context.Context, uuids []string) error {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
// UpdateCommentAttachments update attachments by UUIDs for the comment
|
||||
func UpdateCommentAttachments(ctx context.Context, c *Comment, uuids []string) error {
|
||||
if len(uuids) == 0 {
|
||||
return nil
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", uuids, err)
|
||||
}
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
attachments[i].IssueID = c.IssueID
|
||||
attachments[i].CommentID = c.ID
|
||||
if err := repo_model.UpdateAttachment(ctx, attachments[i]); err != nil {
|
||||
return fmt.Errorf("update attachment [id: %d]: %w", attachments[i].ID, err)
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, uuids)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", uuids, err)
|
||||
}
|
||||
}
|
||||
return committer.Commit()
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
attachments[i].IssueID = c.IssueID
|
||||
attachments[i].CommentID = c.ID
|
||||
if err := repo_model.UpdateAttachment(ctx, attachments[i]); err != nil {
|
||||
return fmt.Errorf("update attachment [id: %d]: %w", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
c.Attachments = attachments
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// LoadAssigneeUserAndTeam if comment.Type is CommentTypeAssignees, then load assignees
|
||||
@ -878,7 +892,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
|
||||
// Check comment type.
|
||||
switch opts.Type {
|
||||
case CommentTypeCode:
|
||||
if err = updateAttachments(ctx, opts, comment); err != nil {
|
||||
if err = UpdateCommentAttachments(ctx, comment, opts.Attachments); err != nil {
|
||||
return err
|
||||
}
|
||||
if comment.ReviewID != 0 {
|
||||
@ -893,12 +907,12 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
|
||||
}
|
||||
fallthrough
|
||||
case CommentTypeComment:
|
||||
if _, err = db.Exec(ctx, "UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", opts.Issue.ID); err != nil {
|
||||
if err := UpdateIssueNumComments(ctx, opts.Issue.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
fallthrough
|
||||
case CommentTypeReview:
|
||||
if err = updateAttachments(ctx, opts, comment); err != nil {
|
||||
if err = UpdateCommentAttachments(ctx, comment, opts.Attachments); err != nil {
|
||||
return err
|
||||
}
|
||||
case CommentTypeReopen, CommentTypeClose:
|
||||
@ -910,23 +924,6 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
|
||||
return UpdateIssueCols(ctx, opts.Issue, "updated_unix")
|
||||
}
|
||||
|
||||
func updateAttachments(ctx context.Context, opts *CreateCommentOptions, comment *Comment) error {
|
||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", opts.Attachments, err)
|
||||
}
|
||||
for i := range attachments {
|
||||
attachments[i].IssueID = opts.Issue.ID
|
||||
attachments[i].CommentID = comment.ID
|
||||
// No assign value could be 0, so ignore AllCols().
|
||||
if _, err = db.GetEngine(ctx).ID(attachments[i].ID).Update(attachments[i]); err != nil {
|
||||
return fmt.Errorf("update attachment [%d]: %w", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
comment.Attachments = attachments
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDeadlineComment(ctx context.Context, doer *user_model.User, issue *Issue, newDeadlineUnix timeutil.TimeStamp) (*Comment, error) {
|
||||
var content string
|
||||
var commentType CommentType
|
||||
@ -1182,8 +1179,8 @@ func DeleteComment(ctx context.Context, comment *Comment) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if comment.Type == CommentTypeComment {
|
||||
if _, err := e.ID(comment.IssueID).Decr("num_comments").Update(new(Issue)); err != nil {
|
||||
if comment.Type.CountedAsConversation() {
|
||||
if err := UpdateIssueNumComments(ctx, comment.IssueID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -1300,6 +1297,21 @@ func (c *Comment) HasOriginalAuthor() bool {
|
||||
return c.OriginalAuthor != "" && c.OriginalAuthorID != 0
|
||||
}
|
||||
|
||||
func UpdateIssueNumCommentsBuilder(issueID int64) *builder.Builder {
|
||||
subQuery := builder.Select("COUNT(*)").From("`comment`").Where(
|
||||
builder.Eq{"issue_id": issueID}.And(
|
||||
builder.In("`type`", ConversationCountedCommentType()),
|
||||
))
|
||||
|
||||
return builder.Update(builder.Eq{"num_comments": subQuery}).
|
||||
From("`issue`").Where(builder.Eq{"id": issueID})
|
||||
}
|
||||
|
||||
func UpdateIssueNumComments(ctx context.Context, issueID int64) error {
|
||||
_, err := db.GetEngine(ctx).Exec(UpdateIssueNumCommentsBuilder(issueID))
|
||||
return err
|
||||
}
|
||||
|
||||
// InsertIssueComments inserts many comments of issues.
|
||||
func InsertIssueComments(ctx context.Context, comments []*Comment) error {
|
||||
if len(comments) == 0 {
|
||||
@ -1332,8 +1344,7 @@ func InsertIssueComments(ctx context.Context, comments []*Comment) error {
|
||||
}
|
||||
|
||||
for _, issueID := range issueIDs {
|
||||
if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?",
|
||||
issueID, CommentTypeComment, issueID); err != nil {
|
||||
if err := UpdateIssueNumComments(ctx, issueID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,24 @@ func TestCreateComment(t *testing.T) {
|
||||
unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix))
|
||||
}
|
||||
|
||||
func Test_UpdateCommentAttachment(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 1})
|
||||
attachment := repo_model.Attachment{
|
||||
Name: "test.txt",
|
||||
}
|
||||
assert.NoError(t, db.Insert(db.DefaultContext, &attachment))
|
||||
|
||||
err := issues_model.UpdateCommentAttachments(db.DefaultContext, comment, []string{attachment.UUID})
|
||||
assert.NoError(t, err)
|
||||
|
||||
attachment2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: attachment.ID})
|
||||
assert.EqualValues(t, attachment.Name, attachment2.Name)
|
||||
assert.EqualValues(t, comment.ID, attachment2.CommentID)
|
||||
assert.EqualValues(t, comment.IssueID, attachment2.IssueID)
|
||||
}
|
||||
|
||||
func TestFetchCodeComments(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
@ -64,7 +82,7 @@ func TestFetchCodeComments(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAsCommentType(t *testing.T) {
|
||||
assert.Equal(t, issues_model.CommentType(0), issues_model.CommentTypeComment)
|
||||
assert.Equal(t, issues_model.CommentTypeComment, issues_model.CommentType(0))
|
||||
assert.Equal(t, issues_model.CommentTypeUndefined, issues_model.AsCommentType(""))
|
||||
assert.Equal(t, issues_model.CommentTypeUndefined, issues_model.AsCommentType("nonsense"))
|
||||
assert.Equal(t, issues_model.CommentTypeComment, issues_model.AsCommentType("comment"))
|
||||
@ -97,3 +115,12 @@ func TestMigrate_InsertIssueComments(t *testing.T) {
|
||||
|
||||
unittest.CheckConsistencyFor(t, &issues_model.Issue{})
|
||||
}
|
||||
|
||||
func Test_UpdateIssueNumComments(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
|
||||
|
||||
assert.NoError(t, issues_model.UpdateIssueNumComments(db.DefaultContext, issue2.ID))
|
||||
issue2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
|
||||
assert.EqualValues(t, 1, issue2.NumComments)
|
||||
}
|
||||
|
@ -49,9 +49,13 @@ func TestCreateIssueDependency(t *testing.T) {
|
||||
assert.False(t, left)
|
||||
|
||||
// Close #2 and check again
|
||||
_, err = issues_model.ChangeIssueStatus(db.DefaultContext, issue2, user1, true)
|
||||
_, err = issues_model.CloseIssue(db.DefaultContext, issue2, user1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
issue2Closed, err := issues_model.GetIssueByID(db.DefaultContext, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, issue2Closed.IsClosed)
|
||||
|
||||
left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, left)
|
||||
@ -59,4 +63,11 @@ func TestCreateIssueDependency(t *testing.T) {
|
||||
// Test removing the dependency
|
||||
err = issues_model.RemoveIssueDependency(db.DefaultContext, user1, issue1, issue2, issues_model.DependencyTypeBlockedBy)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = issues_model.ReopenIssue(db.DefaultContext, issue2, user1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
issue2Reopened, err := issues_model.GetIssueByID(db.DefaultContext, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, issue2Reopened.IsClosed)
|
||||
}
|
||||
|
@ -125,8 +125,11 @@ type Issue struct {
|
||||
IsPull bool `xorm:"INDEX"` // Indicates whether is a pull request or not.
|
||||
PullRequest *PullRequest `xorm:"-"`
|
||||
NumComments int
|
||||
Ref string
|
||||
PinOrder int `xorm:"DEFAULT 0"`
|
||||
|
||||
// TODO: RemoveIssueRef: see "repo/issue/branch_selector_field.tmpl"
|
||||
Ref string
|
||||
|
||||
PinOrder int `xorm:"DEFAULT 0"`
|
||||
|
||||
DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"`
|
||||
|
||||
|
@ -18,12 +18,12 @@ func RecalculateIssueIndexForRepo(ctx context.Context, repoID int64) error {
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
var max int64
|
||||
if _, err = db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil {
|
||||
var maxIndex int64
|
||||
if _, err = db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&maxIndex); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = db.SyncMaxResourceIndex(ctx, "issue_index", repoID, max); err != nil {
|
||||
if err = db.SyncMaxResourceIndex(ctx, "issue_index", repoID, maxIndex); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,8 @@ type IssuesOptions struct { //nolint
|
||||
RepoIDs []int64 // overwrites RepoCond if the length is not 0
|
||||
AllPublic bool // include also all public repositories
|
||||
RepoCond builder.Cond
|
||||
AssigneeID int64
|
||||
PosterID int64
|
||||
AssigneeID optional.Option[int64]
|
||||
PosterID optional.Option[int64]
|
||||
MentionedID int64
|
||||
ReviewRequestedID int64
|
||||
ReviewedID int64
|
||||
@ -231,15 +231,8 @@ func applyConditions(sess *xorm.Session, opts *IssuesOptions) {
|
||||
sess.And("issue.is_closed=?", opts.IsClosed.Value())
|
||||
}
|
||||
|
||||
if opts.AssigneeID > 0 {
|
||||
applyAssigneeCondition(sess, opts.AssigneeID)
|
||||
} else if opts.AssigneeID == db.NoConditionID {
|
||||
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_assignees)")
|
||||
}
|
||||
|
||||
if opts.PosterID > 0 {
|
||||
applyPosterCondition(sess, opts.PosterID)
|
||||
}
|
||||
applyAssigneeCondition(sess, opts.AssigneeID)
|
||||
applyPosterCondition(sess, opts.PosterID)
|
||||
|
||||
if opts.MentionedID > 0 {
|
||||
applyMentionedCondition(sess, opts.MentionedID)
|
||||
@ -359,13 +352,27 @@ func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organizati
|
||||
return cond
|
||||
}
|
||||
|
||||
func applyAssigneeCondition(sess *xorm.Session, assigneeID int64) {
|
||||
sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
|
||||
And("issue_assignees.assignee_id = ?", assigneeID)
|
||||
func applyAssigneeCondition(sess *xorm.Session, assigneeID optional.Option[int64]) {
|
||||
// old logic: 0 is also treated as "not filtering assignee", because the "assignee" was read as FormInt64
|
||||
if !assigneeID.Has() || assigneeID.Value() == 0 {
|
||||
return
|
||||
}
|
||||
if assigneeID.Value() == db.NoConditionID {
|
||||
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_assignees)")
|
||||
} else {
|
||||
sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
|
||||
And("issue_assignees.assignee_id = ?", assigneeID.Value())
|
||||
}
|
||||
}
|
||||
|
||||
func applyPosterCondition(sess *xorm.Session, posterID int64) {
|
||||
sess.And("issue.poster_id=?", posterID)
|
||||
func applyPosterCondition(sess *xorm.Session, posterID optional.Option[int64]) {
|
||||
if !posterID.Has() {
|
||||
return
|
||||
}
|
||||
// poster doesn't need to support db.NoConditionID(-1), so just use the value as-is
|
||||
if posterID.Has() {
|
||||
sess.And("issue.poster_id=?", posterID.Value())
|
||||
}
|
||||
}
|
||||
|
||||
func applyMentionedCondition(sess *xorm.Session, mentionedID int64) {
|
||||
|
@ -151,15 +151,9 @@ func applyIssuesOptions(sess *xorm.Session, opts *IssuesOptions, issueIDs []int6
|
||||
|
||||
applyProjectCondition(sess, opts)
|
||||
|
||||
if opts.AssigneeID > 0 {
|
||||
applyAssigneeCondition(sess, opts.AssigneeID)
|
||||
} else if opts.AssigneeID == db.NoConditionID {
|
||||
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_assignees)")
|
||||
}
|
||||
applyAssigneeCondition(sess, opts.AssigneeID)
|
||||
|
||||
if opts.PosterID > 0 {
|
||||
applyPosterCondition(sess, opts.PosterID)
|
||||
}
|
||||
applyPosterCondition(sess, opts.PosterID)
|
||||
|
||||
if opts.MentionedID > 0 {
|
||||
applyMentionedCondition(sess, opts.MentionedID)
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -155,7 +156,7 @@ func TestIssues(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
issues_model.IssuesOptions{
|
||||
AssigneeID: 1,
|
||||
AssigneeID: optional.Some(int64(1)),
|
||||
SortType: "oldest",
|
||||
},
|
||||
[]int64{1, 6},
|
||||
@ -433,7 +434,7 @@ func assertCreateIssues(t *testing.T, isPull bool) {
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
|
||||
milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
|
||||
assert.EqualValues(t, milestone.ID, 1)
|
||||
assert.EqualValues(t, 1, milestone.ID)
|
||||
reaction := &issues_model.Reaction{
|
||||
Type: "heart",
|
||||
UserID: owner.ID,
|
||||
|
@ -34,7 +34,7 @@ func UpdateIssueCols(ctx context.Context, issue *Issue, cols ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func changeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isClosed, isMergePull bool) (*Comment, error) {
|
||||
func ChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isClosed, isMergePull bool) (*Comment, error) {
|
||||
// Reload the issue
|
||||
currentIssue, err := GetIssueByID(ctx, issue.ID)
|
||||
if err != nil {
|
||||
@ -119,8 +119,8 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use
|
||||
})
|
||||
}
|
||||
|
||||
// ChangeIssueStatus changes issue status to open or closed.
|
||||
func ChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isClosed bool) (*Comment, error) {
|
||||
// CloseIssue changes issue status to closed.
|
||||
func CloseIssue(ctx context.Context, issue *Issue, doer *user_model.User) (*Comment, error) {
|
||||
if err := issue.LoadRepo(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -128,7 +128,45 @@ func ChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return changeIssueStatus(ctx, issue, doer, isClosed, false)
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
comment, err := ChangeIssueStatus(ctx, issue, doer, true, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := committer.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return comment, nil
|
||||
}
|
||||
|
||||
// ReopenIssue changes issue status to open.
|
||||
func ReopenIssue(ctx context.Context, issue *Issue, doer *user_model.User) (*Comment, error) {
|
||||
if err := issue.LoadRepo(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := issue.LoadPoster(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
comment, err := ChangeIssueStatus(ctx, issue, doer, false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := committer.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return comment, nil
|
||||
}
|
||||
|
||||
// ChangeIssueTitle changes the title of this issue, as the given user.
|
||||
@ -139,7 +177,7 @@ func ChangeIssueTitle(ctx context.Context, issue *Issue, doer *user_model.User,
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
|
||||
issue.Title = util.EllipsisDisplayString(issue.Title, 255)
|
||||
if err = UpdateIssueCols(ctx, issue, "name"); err != nil {
|
||||
return fmt.Errorf("updateIssueCols: %w", err)
|
||||
}
|
||||
@ -367,19 +405,10 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
|
||||
return err
|
||||
}
|
||||
|
||||
if len(opts.Attachments) > 0 {
|
||||
attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, opts.Attachments)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getAttachmentsByUUIDs [uuids: %v]: %w", opts.Attachments, err)
|
||||
}
|
||||
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
attachments[i].IssueID = opts.Issue.ID
|
||||
if _, err = e.ID(attachments[i].ID).Update(attachments[i]); err != nil {
|
||||
return fmt.Errorf("update attachment [id: %d]: %w", attachments[i].ID, err)
|
||||
}
|
||||
}
|
||||
if err := UpdateIssueAttachments(ctx, opts.Issue.ID, opts.Attachments); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = opts.Issue.LoadAttributes(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -402,7 +431,7 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, la
|
||||
}
|
||||
|
||||
issue.Index = idx
|
||||
issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
|
||||
issue.Title = util.EllipsisDisplayString(issue.Title, 255)
|
||||
|
||||
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
|
||||
Repo: repo,
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_NewIssueUsers(t *testing.T) {
|
||||
@ -27,9 +28,8 @@ func Test_NewIssueUsers(t *testing.T) {
|
||||
}
|
||||
|
||||
// artificially insert new issue
|
||||
unittest.AssertSuccessfulInsert(t, newIssue)
|
||||
|
||||
assert.NoError(t, issues_model.NewIssueUsers(db.DefaultContext, repo, newIssue))
|
||||
require.NoError(t, db.Insert(db.DefaultContext, newIssue))
|
||||
require.NoError(t, issues_model.NewIssueUsers(db.DefaultContext, repo, newIssue))
|
||||
|
||||
// issue_user table should now have entries for new issue
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: newIssue.ID, UID: newIssue.PosterID})
|
||||
|
@ -48,17 +48,17 @@ func TestGetIssueWatchers(t *testing.T) {
|
||||
iws, err := issues_model.GetIssueWatchers(db.DefaultContext, 1, db.ListOptions{})
|
||||
assert.NoError(t, err)
|
||||
// Watcher is inactive, thus 0
|
||||
assert.Len(t, iws, 0)
|
||||
assert.Empty(t, iws)
|
||||
|
||||
iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 2, db.ListOptions{})
|
||||
assert.NoError(t, err)
|
||||
// Watcher is explicit not watching
|
||||
assert.Len(t, iws, 0)
|
||||
assert.Empty(t, iws)
|
||||
|
||||
iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 5, db.ListOptions{})
|
||||
assert.NoError(t, err)
|
||||
// Issue has no Watchers
|
||||
assert.Len(t, iws, 0)
|
||||
assert.Empty(t, iws)
|
||||
|
||||
iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 7, db.ListOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
@ -98,7 +98,7 @@ func TestXRef_ResolveCrossReferences(t *testing.T) {
|
||||
i1 := testCreateIssue(t, 1, 2, "title1", "content1", false)
|
||||
i2 := testCreateIssue(t, 1, 2, "title2", "content2", false)
|
||||
i3 := testCreateIssue(t, 1, 2, "title3", "content3", false)
|
||||
_, err := issues_model.ChangeIssueStatus(db.DefaultContext, i3, d, true)
|
||||
_, err := issues_model.CloseIssue(db.DefaultContext, i3, d)
|
||||
assert.NoError(t, err)
|
||||
|
||||
pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index))
|
||||
|
@ -349,6 +349,17 @@ func GetLabelIDsInRepoByNames(ctx context.Context, repoID int64, labelNames []st
|
||||
Find(&labelIDs)
|
||||
}
|
||||
|
||||
// GetLabelIDsInOrgByNames returns a list of labelIDs by names in a given org.
|
||||
func GetLabelIDsInOrgByNames(ctx context.Context, orgID int64, labelNames []string) ([]int64, error) {
|
||||
labelIDs := make([]int64, 0, len(labelNames))
|
||||
return labelIDs, db.GetEngine(ctx).Table("label").
|
||||
Where("org_id = ?", orgID).
|
||||
In("name", labelNames).
|
||||
Asc("name").
|
||||
Cols("id").
|
||||
Find(&labelIDs)
|
||||
}
|
||||
|
||||
// BuildLabelNamesIssueIDsCondition returns a builder where get issue ids match label names
|
||||
func BuildLabelNamesIssueIDsCondition(labelNames []string) *builder.Builder {
|
||||
return builder.Select("issue_label.issue_id").
|
||||
|
@ -31,12 +31,12 @@ func TestLabel_LoadSelectedLabelsAfterClick(t *testing.T) {
|
||||
// First test : with negative and scope
|
||||
label.LoadSelectedLabelsAfterClick([]int64{1, -8}, []string{"", "scope"})
|
||||
assert.Equal(t, "1", label.QueryString)
|
||||
assert.Equal(t, true, label.IsSelected)
|
||||
assert.True(t, label.IsSelected)
|
||||
|
||||
// Second test : with duplicates
|
||||
label.LoadSelectedLabelsAfterClick([]int64{1, 7, 1, 7, 7}, []string{"", "scope", "", "scope", "scope"})
|
||||
assert.Equal(t, "1,8", label.QueryString)
|
||||
assert.Equal(t, false, label.IsSelected)
|
||||
assert.False(t, label.IsSelected)
|
||||
|
||||
// Third test : empty set
|
||||
label.LoadSelectedLabelsAfterClick([]int64{}, []string{})
|
||||
@ -248,7 +248,7 @@ func TestGetLabelsByIssueID(t *testing.T) {
|
||||
|
||||
labels, err = issues_model.GetLabelsByIssueID(db.DefaultContext, unittest.NonexistentID)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, labels, 0)
|
||||
assert.Empty(t, labels)
|
||||
}
|
||||
|
||||
func TestUpdateLabel(t *testing.T) {
|
||||
@ -271,7 +271,7 @@ func TestUpdateLabel(t *testing.T) {
|
||||
assert.EqualValues(t, label.Color, newLabel.Color)
|
||||
assert.EqualValues(t, label.Name, newLabel.Name)
|
||||
assert.EqualValues(t, label.Description, newLabel.Description)
|
||||
assert.EqualValues(t, newLabel.ArchivedUnix, 0)
|
||||
assert.EqualValues(t, 0, newLabel.ArchivedUnix)
|
||||
unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{})
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ func TestDeleteIssueLabel(t *testing.T) {
|
||||
|
||||
expectedNumIssues := label.NumIssues
|
||||
expectedNumClosedIssues := label.NumClosedIssues
|
||||
if unittest.BeanExists(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) {
|
||||
if unittest.GetBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) != nil {
|
||||
expectedNumIssues--
|
||||
if issue.IsClosed {
|
||||
expectedNumClosedIssues--
|
||||
|
@ -87,7 +87,7 @@ func TestGetMilestonesByRepoID(t *testing.T) {
|
||||
IsClosed: optional.Some(false),
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, milestones, 0)
|
||||
assert.Empty(t, milestones)
|
||||
}
|
||||
|
||||
func TestGetMilestones(t *testing.T) {
|
||||
|
@ -499,65 +499,6 @@ func (pr *PullRequest) IsFromFork() bool {
|
||||
return pr.HeadRepoID != pr.BaseRepoID
|
||||
}
|
||||
|
||||
// SetMerged sets a pull request to merged and closes the corresponding issue
|
||||
func (pr *PullRequest) SetMerged(ctx context.Context) (bool, error) {
|
||||
if pr.HasMerged {
|
||||
return false, fmt.Errorf("PullRequest[%d] already merged", pr.Index)
|
||||
}
|
||||
if pr.MergedCommitID == "" || pr.MergedUnix == 0 || pr.Merger == nil {
|
||||
return false, fmt.Errorf("Unable to merge PullRequest[%d], some required fields are empty", pr.Index)
|
||||
}
|
||||
|
||||
pr.HasMerged = true
|
||||
sess := db.GetEngine(ctx)
|
||||
|
||||
if _, err := sess.Exec("UPDATE `issue` SET `repo_id` = `repo_id` WHERE `id` = ?", pr.IssueID); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("UPDATE `pull_request` SET `issue_id` = `issue_id` WHERE `id` = ?", pr.ID); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
pr.Issue = nil
|
||||
if err := pr.LoadIssue(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if tmpPr, err := GetPullRequestByID(ctx, pr.ID); err != nil {
|
||||
return false, err
|
||||
} else if tmpPr.HasMerged {
|
||||
if pr.Issue.IsClosed {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("PullRequest[%d] already merged but it's associated issue [%d] is not closed", pr.Index, pr.IssueID)
|
||||
} else if pr.Issue.IsClosed {
|
||||
return false, fmt.Errorf("PullRequest[%d] already closed", pr.Index)
|
||||
}
|
||||
|
||||
if err := pr.Issue.LoadRepo(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if err := pr.Issue.Repo.LoadOwner(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if _, err := changeIssueStatus(ctx, pr.Issue, pr.Merger, true, true); err != nil {
|
||||
return false, fmt.Errorf("Issue.changeStatus: %w", err)
|
||||
}
|
||||
|
||||
// reset the conflicted files as there cannot be any if we're merged
|
||||
pr.ConflictedFiles = []string{}
|
||||
|
||||
// We need to save all of the data used to compute this merge as it may have already been changed by TestPatch. FIXME: need to set some state to prevent TestPatch from running whilst we are merging.
|
||||
if _, err := sess.Where("id = ?", pr.ID).Cols("has_merged, status, merge_base, merged_commit_id, merger_id, merged_unix, conflicted_files").Update(pr); err != nil {
|
||||
return false, fmt.Errorf("Failed to update pr[%d]: %w", pr.ID, err)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// NewPullRequest creates new pull request with labels for repository.
|
||||
func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
@ -572,7 +513,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Iss
|
||||
}
|
||||
|
||||
issue.Index = idx
|
||||
issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
|
||||
issue.Title = util.EllipsisDisplayString(issue.Title, 255)
|
||||
|
||||
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
|
||||
Repo: repo,
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
@ -240,6 +241,64 @@ func (prs PullRequestList) GetIssueIDs() []int64 {
|
||||
})
|
||||
}
|
||||
|
||||
func (prs PullRequestList) LoadReviewCommentsCounts(ctx context.Context) (map[int64]int, error) {
|
||||
issueIDs := prs.GetIssueIDs()
|
||||
countsMap := make(map[int64]int, len(issueIDs))
|
||||
counts := make([]struct {
|
||||
IssueID int64
|
||||
Count int
|
||||
}, 0, len(issueIDs))
|
||||
if err := db.GetEngine(ctx).Select("issue_id, count(*) as count").
|
||||
Table("comment").In("issue_id", issueIDs).And("type = ?", CommentTypeReview).
|
||||
GroupBy("issue_id").Find(&counts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, c := range counts {
|
||||
countsMap[c.IssueID] = c.Count
|
||||
}
|
||||
return countsMap, nil
|
||||
}
|
||||
|
||||
func (prs PullRequestList) LoadReviews(ctx context.Context) (ReviewList, error) {
|
||||
issueIDs := prs.GetIssueIDs()
|
||||
reviews := make([]*Review, 0, len(issueIDs))
|
||||
|
||||
subQuery := builder.Select("max(id) as id").
|
||||
From("review").
|
||||
Where(builder.In("issue_id", issueIDs)).
|
||||
And(builder.In("`type`", ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest)).
|
||||
And(builder.Eq{
|
||||
"dismissed": false,
|
||||
"original_author_id": 0,
|
||||
"reviewer_team_id": 0,
|
||||
}).
|
||||
GroupBy("issue_id, reviewer_id")
|
||||
// Get latest review of each reviewer, sorted in order they were made
|
||||
if err := db.GetEngine(ctx).In("id", subQuery).OrderBy("review.updated_unix ASC").Find(&reviews); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
teamReviewRequests := make([]*Review, 0, 5)
|
||||
subQueryTeam := builder.Select("max(id) as id").
|
||||
From("review").
|
||||
Where(builder.In("issue_id", issueIDs)).
|
||||
And(builder.Eq{
|
||||
"original_author_id": 0,
|
||||
}).And(builder.Neq{
|
||||
"reviewer_team_id": 0,
|
||||
}).
|
||||
GroupBy("issue_id, reviewer_team_id")
|
||||
if err := db.GetEngine(ctx).In("id", subQueryTeam).OrderBy("review.updated_unix ASC").Find(&teamReviewRequests); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(teamReviewRequests) > 0 {
|
||||
reviews = append(reviews, teamReviewRequests...)
|
||||
}
|
||||
|
||||
return reviews, nil
|
||||
}
|
||||
|
||||
// HasMergedPullRequestInRepo returns whether the user(poster) has merged pull-request in the repo
|
||||
func HasMergedPullRequestInRepo(ctx context.Context, repoID, posterID int64) (bool, error) {
|
||||
return db.GetEngine(ctx).
|
||||
|
64
models/issues/pull_list_test.go
Normal file
64
models/issues/pull_list_test.go
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package issues_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPullRequestList_LoadAttributes(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
prs := []*issues_model.PullRequest{
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
|
||||
}
|
||||
assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes(db.DefaultContext))
|
||||
for _, pr := range prs {
|
||||
assert.NotNil(t, pr.Issue)
|
||||
assert.Equal(t, pr.IssueID, pr.Issue.ID)
|
||||
}
|
||||
|
||||
assert.NoError(t, issues_model.PullRequestList([]*issues_model.PullRequest{}).LoadAttributes(db.DefaultContext))
|
||||
}
|
||||
|
||||
func TestPullRequestList_LoadReviewCommentsCounts(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
prs := []*issues_model.PullRequest{
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
|
||||
}
|
||||
reviewComments, err := issues_model.PullRequestList(prs).LoadReviewCommentsCounts(db.DefaultContext)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, reviewComments, 2)
|
||||
for _, pr := range prs {
|
||||
assert.EqualValues(t, 1, reviewComments[pr.IssueID])
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullRequestList_LoadReviews(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
prs := []*issues_model.PullRequest{
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
|
||||
}
|
||||
reviewList, err := issues_model.PullRequestList(prs).LoadReviews(db.DefaultContext)
|
||||
assert.NoError(t, err)
|
||||
// 1, 7, 8, 9, 10, 22
|
||||
assert.Len(t, reviewList, 6)
|
||||
assert.EqualValues(t, 1, reviewList[0].ID)
|
||||
assert.EqualValues(t, 7, reviewList[1].ID)
|
||||
assert.EqualValues(t, 8, reviewList[2].ID)
|
||||
assert.EqualValues(t, 9, reviewList[3].ID)
|
||||
assert.EqualValues(t, 10, reviewList[4].ID)
|
||||
assert.EqualValues(t, 22, reviewList[5].ID)
|
||||
}
|
@ -79,11 +79,11 @@ func TestPullRequestsNewest(t *testing.T) {
|
||||
func TestLoadRequestedReviewers(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
|
||||
pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
|
||||
assert.NoError(t, pull.LoadIssue(db.DefaultContext))
|
||||
issue := pull.Issue
|
||||
assert.NoError(t, issue.LoadRepo(db.DefaultContext))
|
||||
assert.Len(t, pull.RequestedReviewers, 0)
|
||||
assert.Empty(t, pull.RequestedReviewers)
|
||||
|
||||
user1, err := user_model.GetUserByID(db.DefaultContext, 1)
|
||||
assert.NoError(t, err)
|
||||
@ -93,7 +93,7 @@ func TestLoadRequestedReviewers(t *testing.T) {
|
||||
assert.NotNil(t, comment)
|
||||
|
||||
assert.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext))
|
||||
assert.Len(t, pull.RequestedReviewers, 1)
|
||||
assert.Len(t, pull.RequestedReviewers, 6)
|
||||
|
||||
comment, err = issues_model.RemoveReviewRequest(db.DefaultContext, issue, user1, &user_model.User{})
|
||||
assert.NoError(t, err)
|
||||
@ -234,22 +234,6 @@ func TestPullRequest_UpdateCols(t *testing.T) {
|
||||
unittest.CheckConsistencyFor(t, pr)
|
||||
}
|
||||
|
||||
func TestPullRequestList_LoadAttributes(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
prs := []*issues_model.PullRequest{
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
|
||||
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
|
||||
}
|
||||
assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes(db.DefaultContext))
|
||||
for _, pr := range prs {
|
||||
assert.NotNil(t, pr.Issue)
|
||||
assert.Equal(t, pr.IssueID, pr.Issue.ID)
|
||||
}
|
||||
|
||||
assert.NoError(t, issues_model.PullRequestList([]*issues_model.PullRequest{}).LoadAttributes(db.DefaultContext))
|
||||
}
|
||||
|
||||
// TODO TestAddTestPullRequestTask
|
||||
|
||||
func TestPullRequest_IsWorkInProgress(t *testing.T) {
|
||||
|
@ -639,6 +639,10 @@ func InsertReviews(ctx context.Context, reviews []*Review) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := UpdateIssueNumComments(ctx, review.IssueID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
|
@ -47,14 +47,9 @@ func (reviews ReviewList) LoadReviewersTeams(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
teamsMap := make(map[int64]*organization_model.Team, 0)
|
||||
for _, teamID := range reviewersTeamsIDs {
|
||||
team, err := organization_model.GetTeamByID(ctx, teamID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
teamsMap[teamID] = team
|
||||
teamsMap, err := organization_model.GetTeamsByIDs(ctx, reviewersTeamsIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, review := range reviews {
|
||||
|
@ -126,42 +126,48 @@ func TestGetReviewersByIssueID(t *testing.T) {
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
|
||||
user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||
user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
|
||||
|
||||
expectedReviews := []*issues_model.Review{}
|
||||
expectedReviews = append(expectedReviews,
|
||||
&issues_model.Review{
|
||||
ID: 7,
|
||||
Reviewer: org3,
|
||||
Type: issues_model.ReviewTypeReject,
|
||||
UpdatedUnix: 946684812,
|
||||
},
|
||||
&issues_model.Review{
|
||||
ID: 8,
|
||||
Reviewer: user4,
|
||||
Type: issues_model.ReviewTypeApprove,
|
||||
UpdatedUnix: 946684813,
|
||||
},
|
||||
&issues_model.Review{
|
||||
ID: 9,
|
||||
Reviewer: user2,
|
||||
Type: issues_model.ReviewTypeReject,
|
||||
UpdatedUnix: 946684814,
|
||||
})
|
||||
},
|
||||
&issues_model.Review{
|
||||
ID: 10,
|
||||
Reviewer: user_model.NewGhostUser(),
|
||||
Type: issues_model.ReviewTypeReject,
|
||||
UpdatedUnix: 946684815,
|
||||
},
|
||||
&issues_model.Review{
|
||||
ID: 22,
|
||||
Reviewer: user5,
|
||||
Type: issues_model.ReviewTypeRequest,
|
||||
UpdatedUnix: 946684817,
|
||||
},
|
||||
)
|
||||
|
||||
allReviews, err := issues_model.GetReviewsByIssueID(db.DefaultContext, issue.ID)
|
||||
assert.NoError(t, err)
|
||||
for _, review := range allReviews {
|
||||
assert.NoError(t, review.LoadReviewer(db.DefaultContext))
|
||||
}
|
||||
if assert.Len(t, allReviews, 3) {
|
||||
for i, review := range allReviews {
|
||||
assert.Equal(t, expectedReviews[i].Reviewer, review.Reviewer)
|
||||
assert.Equal(t, expectedReviews[i].Type, review.Type)
|
||||
assert.Equal(t, expectedReviews[i].UpdatedUnix, review.UpdatedUnix)
|
||||
}
|
||||
}
|
||||
|
||||
allReviews, err = issues_model.GetReviewsByIssueID(db.DefaultContext, issue.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, allReviews.LoadReviewers(db.DefaultContext))
|
||||
if assert.Len(t, allReviews, 3) {
|
||||
if assert.Len(t, allReviews, 5) {
|
||||
for i, review := range allReviews {
|
||||
assert.Equal(t, expectedReviews[i].Reviewer, review.Reviewer)
|
||||
assert.Equal(t, expectedReviews[i].Type, review.Type)
|
||||
|
@ -32,7 +32,7 @@ func TestCancelStopwatch(t *testing.T) {
|
||||
|
||||
_ = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeCancelTracking, PosterID: user1.ID, IssueID: issue1.ID})
|
||||
|
||||
assert.Nil(t, issues_model.CancelStopwatch(db.DefaultContext, user1, issue2))
|
||||
assert.NoError(t, issues_model.CancelStopwatch(db.DefaultContext, user1, issue2))
|
||||
}
|
||||
|
||||
func TestStopwatchExists(t *testing.T) {
|
||||
|
@ -50,7 +50,7 @@ func TestGetTrackedTimes(t *testing.T) {
|
||||
|
||||
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: -1})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, times, 0)
|
||||
assert.Empty(t, times)
|
||||
|
||||
// by User
|
||||
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 1})
|
||||
@ -60,7 +60,7 @@ func TestGetTrackedTimes(t *testing.T) {
|
||||
|
||||
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 3})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, times, 0)
|
||||
assert.Empty(t, times)
|
||||
|
||||
// by Repo
|
||||
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 2})
|
||||
@ -69,7 +69,7 @@ func TestGetTrackedTimes(t *testing.T) {
|
||||
assert.Equal(t, int64(1), times[0].Time)
|
||||
issue, err := issues_model.GetIssueByID(db.DefaultContext, times[0].IssueID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, issue.RepoID, int64(2))
|
||||
assert.Equal(t, int64(2), issue.RepoID)
|
||||
|
||||
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 1})
|
||||
assert.NoError(t, err)
|
||||
@ -77,7 +77,7 @@ func TestGetTrackedTimes(t *testing.T) {
|
||||
|
||||
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 10})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, times, 0)
|
||||
assert.Empty(t, times)
|
||||
}
|
||||
|
||||
func TestTotalTimesForEachUser(t *testing.T) {
|
||||
|
@ -13,9 +13,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
"code.gitea.io/gitea/modules/testlogger"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -76,7 +76,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu
|
||||
t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err)
|
||||
return x, deferFn
|
||||
}
|
||||
if err := unittest.LoadFixtures(x); err != nil {
|
||||
if err := unittest.LoadFixtures(); err != nil {
|
||||
t.Errorf("error whilst loading fixtures from %s: %v", fixturesDir, err)
|
||||
return x, deferFn
|
||||
}
|
||||
@ -92,10 +92,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu
|
||||
func MainTest(m *testing.M) {
|
||||
testlogger.Init()
|
||||
|
||||
giteaRoot := base.SetupGiteaRoot()
|
||||
if giteaRoot == "" {
|
||||
testlogger.Fatalf("Environment variable $GITEA_ROOT not set\n")
|
||||
}
|
||||
giteaRoot := test.SetupGiteaRoot()
|
||||
giteaBinary := "gitea"
|
||||
if runtime.GOOS == "windows" {
|
||||
giteaBinary += ".exe"
|
||||
|
@ -56,8 +56,8 @@ func Test_AddRepoIDForAttachment(t *testing.T) {
|
||||
err := x.Table("attachment").Where("issue_id > 0").Find(&issueAttachments)
|
||||
assert.NoError(t, err)
|
||||
for _, attach := range issueAttachments {
|
||||
assert.Greater(t, attach.RepoID, int64(0))
|
||||
assert.Greater(t, attach.IssueID, int64(0))
|
||||
assert.Positive(t, attach.RepoID)
|
||||
assert.Positive(t, attach.IssueID)
|
||||
var issue Issue
|
||||
has, err := x.ID(attach.IssueID).Get(&issue)
|
||||
assert.NoError(t, err)
|
||||
@ -69,8 +69,8 @@ func Test_AddRepoIDForAttachment(t *testing.T) {
|
||||
err = x.Table("attachment").Where("release_id > 0").Find(&releaseAttachments)
|
||||
assert.NoError(t, err)
|
||||
for _, attach := range releaseAttachments {
|
||||
assert.Greater(t, attach.RepoID, int64(0))
|
||||
assert.Greater(t, attach.ReleaseID, int64(0))
|
||||
assert.Positive(t, attach.RepoID)
|
||||
assert.Positive(t, attach.ReleaseID)
|
||||
var release Release
|
||||
has, err := x.ID(attach.ReleaseID).Get(&release)
|
||||
assert.NoError(t, err)
|
||||
|
@ -107,12 +107,12 @@ func Test_RepositoryFormat(t *testing.T) {
|
||||
repo = new(Repository)
|
||||
ok, err := x.ID(2).Get(repo)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, true, ok)
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, "sha1", repo.ObjectFormatName)
|
||||
|
||||
repo = new(Repository)
|
||||
ok, err = x.ID(id).Get(repo)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, true, ok)
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, "sha256", repo.ObjectFormatName)
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ func Test_AddUniqueIndexForProjectIssue(t *testing.T) {
|
||||
|
||||
tables, err := x.DBMetas()
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, len(tables))
|
||||
assert.Len(t, tables, 1)
|
||||
found := false
|
||||
for _, index := range tables[0].Indexes {
|
||||
if index.Type == schemas.UniqueType {
|
||||
|
@ -9,11 +9,8 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
secret_model "code.gitea.io/gitea/models/secret"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@ -407,33 +404,6 @@ func GetOrgByName(ctx context.Context, name string) (*Organization, error) {
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// DeleteOrganization deletes models associated to an organization.
|
||||
func DeleteOrganization(ctx context.Context, org *Organization) error {
|
||||
if org.Type != user_model.UserTypeOrganization {
|
||||
return fmt.Errorf("%s is a user not an organization", org.Name)
|
||||
}
|
||||
|
||||
if err := db.DeleteBeans(ctx,
|
||||
&Team{OrgID: org.ID},
|
||||
&OrgUser{OrgID: org.ID},
|
||||
&TeamUser{OrgID: org.ID},
|
||||
&TeamUnit{OrgID: org.ID},
|
||||
&TeamInvite{OrgID: org.ID},
|
||||
&secret_model.Secret{OwnerID: org.ID},
|
||||
&user_model.Blocking{BlockerID: org.ID},
|
||||
&actions_model.ActionRunner{OwnerID: org.ID},
|
||||
&actions_model.ActionRunnerToken{OwnerID: org.ID},
|
||||
); err != nil {
|
||||
return fmt.Errorf("DeleteBeans: %w", err)
|
||||
}
|
||||
|
||||
if _, err := db.GetEngine(ctx).ID(org.ID).Delete(new(user_model.User)); err != nil {
|
||||
return fmt.Errorf("Delete: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetOrgUserMaxAuthorizeLevel returns highest authorize level of user in an organization
|
||||
func (org *Organization) GetOrgUserMaxAuthorizeLevel(ctx context.Context, uid int64) (perm.AccessMode, error) {
|
||||
var authorize perm.AccessMode
|
||||
@ -604,7 +574,9 @@ func RemoveOrgRepo(ctx context.Context, orgID, repoID int64) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (org *Organization) getUserTeams(ctx context.Context, userID int64, cols ...string) ([]*Team, error) {
|
||||
// GetUserTeams returns all teams that belong to user,
|
||||
// and that the user has joined.
|
||||
func (org *Organization) GetUserTeams(ctx context.Context, userID int64, cols ...string) ([]*Team, error) {
|
||||
teams := make([]*Team, 0, org.NumTeams)
|
||||
return teams, db.GetEngine(ctx).
|
||||
Where("`team_user`.org_id = ?", org.ID).
|
||||
@ -616,7 +588,8 @@ func (org *Organization) getUserTeams(ctx context.Context, userID int64, cols ..
|
||||
Find(&teams)
|
||||
}
|
||||
|
||||
func (org *Organization) getUserTeamIDs(ctx context.Context, userID int64) ([]int64, error) {
|
||||
// GetUserTeamIDs returns of all team IDs of the organization that user is member of.
|
||||
func (org *Organization) GetUserTeamIDs(ctx context.Context, userID int64) ([]int64, error) {
|
||||
teamIDs := make([]int64, 0, org.NumTeams)
|
||||
return teamIDs, db.GetEngine(ctx).
|
||||
Table("team").
|
||||
@ -640,175 +613,3 @@ func getUserTeamIDsQueryBuilder(orgID, userID int64) *builder.Builder {
|
||||
func (org *Organization) TeamsWithAccessToRepo(ctx context.Context, repoID int64, mode perm.AccessMode) ([]*Team, error) {
|
||||
return GetTeamsWithAccessToRepo(ctx, org.ID, repoID, mode)
|
||||
}
|
||||
|
||||
// GetUserTeamIDs returns of all team IDs of the organization that user is member of.
|
||||
func (org *Organization) GetUserTeamIDs(ctx context.Context, userID int64) ([]int64, error) {
|
||||
return org.getUserTeamIDs(ctx, userID)
|
||||
}
|
||||
|
||||
// GetUserTeams returns all teams that belong to user,
|
||||
// and that the user has joined.
|
||||
func (org *Organization) GetUserTeams(ctx context.Context, userID int64) ([]*Team, error) {
|
||||
return org.getUserTeams(ctx, userID)
|
||||
}
|
||||
|
||||
// AccessibleReposEnvironment operations involving the repositories that are
|
||||
// accessible to a particular user
|
||||
type AccessibleReposEnvironment interface {
|
||||
CountRepos() (int64, error)
|
||||
RepoIDs(page, pageSize int) ([]int64, error)
|
||||
Repos(page, pageSize int) (repo_model.RepositoryList, error)
|
||||
MirrorRepos() (repo_model.RepositoryList, error)
|
||||
AddKeyword(keyword string)
|
||||
SetSort(db.SearchOrderBy)
|
||||
}
|
||||
|
||||
type accessibleReposEnv struct {
|
||||
org *Organization
|
||||
user *user_model.User
|
||||
team *Team
|
||||
teamIDs []int64
|
||||
ctx context.Context
|
||||
keyword string
|
||||
orderBy db.SearchOrderBy
|
||||
}
|
||||
|
||||
// AccessibleReposEnv builds an AccessibleReposEnvironment for the repositories in `org`
|
||||
// that are accessible to the specified user.
|
||||
func AccessibleReposEnv(ctx context.Context, org *Organization, userID int64) (AccessibleReposEnvironment, error) {
|
||||
var user *user_model.User
|
||||
|
||||
if userID > 0 {
|
||||
u, err := user_model.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user = u
|
||||
}
|
||||
|
||||
teamIDs, err := org.getUserTeamIDs(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &accessibleReposEnv{
|
||||
org: org,
|
||||
user: user,
|
||||
teamIDs: teamIDs,
|
||||
ctx: ctx,
|
||||
orderBy: db.SearchOrderByRecentUpdated,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AccessibleTeamReposEnv an AccessibleReposEnvironment for the repositories in `org`
|
||||
// that are accessible to the specified team.
|
||||
func (org *Organization) AccessibleTeamReposEnv(ctx context.Context, team *Team) AccessibleReposEnvironment {
|
||||
return &accessibleReposEnv{
|
||||
org: org,
|
||||
team: team,
|
||||
ctx: ctx,
|
||||
orderBy: db.SearchOrderByRecentUpdated,
|
||||
}
|
||||
}
|
||||
|
||||
func (env *accessibleReposEnv) cond() builder.Cond {
|
||||
cond := builder.NewCond()
|
||||
if env.team != nil {
|
||||
cond = cond.And(builder.Eq{"team_repo.team_id": env.team.ID})
|
||||
} else {
|
||||
if env.user == nil || !env.user.IsRestricted {
|
||||
cond = cond.Or(builder.Eq{
|
||||
"`repository`.owner_id": env.org.ID,
|
||||
"`repository`.is_private": false,
|
||||
})
|
||||
}
|
||||
if len(env.teamIDs) > 0 {
|
||||
cond = cond.Or(builder.In("team_repo.team_id", env.teamIDs))
|
||||
}
|
||||
}
|
||||
if env.keyword != "" {
|
||||
cond = cond.And(builder.Like{"`repository`.lower_name", strings.ToLower(env.keyword)})
|
||||
}
|
||||
return cond
|
||||
}
|
||||
|
||||
func (env *accessibleReposEnv) CountRepos() (int64, error) {
|
||||
repoCount, err := db.GetEngine(env.ctx).
|
||||
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
|
||||
Where(env.cond()).
|
||||
Distinct("`repository`.id").
|
||||
Count(&repo_model.Repository{})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("count user repositories in organization: %w", err)
|
||||
}
|
||||
return repoCount, nil
|
||||
}
|
||||
|
||||
func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) {
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
repoIDs := make([]int64, 0, pageSize)
|
||||
return repoIDs, db.GetEngine(env.ctx).
|
||||
Table("repository").
|
||||
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
|
||||
Where(env.cond()).
|
||||
GroupBy("`repository`.id,`repository`."+strings.Fields(string(env.orderBy))[0]).
|
||||
OrderBy(string(env.orderBy)).
|
||||
Limit(pageSize, (page-1)*pageSize).
|
||||
Cols("`repository`.id").
|
||||
Find(&repoIDs)
|
||||
}
|
||||
|
||||
func (env *accessibleReposEnv) Repos(page, pageSize int) (repo_model.RepositoryList, error) {
|
||||
repoIDs, err := env.RepoIDs(page, pageSize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserRepositoryIDs: %w", err)
|
||||
}
|
||||
|
||||
repos := make([]*repo_model.Repository, 0, len(repoIDs))
|
||||
if len(repoIDs) == 0 {
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
return repos, db.GetEngine(env.ctx).
|
||||
In("`repository`.id", repoIDs).
|
||||
OrderBy(string(env.orderBy)).
|
||||
Find(&repos)
|
||||
}
|
||||
|
||||
func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) {
|
||||
repoIDs := make([]int64, 0, 10)
|
||||
return repoIDs, db.GetEngine(env.ctx).
|
||||
Table("repository").
|
||||
Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true).
|
||||
Where(env.cond()).
|
||||
GroupBy("`repository`.id, `repository`.updated_unix").
|
||||
OrderBy(string(env.orderBy)).
|
||||
Cols("`repository`.id").
|
||||
Find(&repoIDs)
|
||||
}
|
||||
|
||||
func (env *accessibleReposEnv) MirrorRepos() (repo_model.RepositoryList, error) {
|
||||
repoIDs, err := env.MirrorRepoIDs()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("MirrorRepoIDs: %w", err)
|
||||
}
|
||||
|
||||
repos := make([]*repo_model.Repository, 0, len(repoIDs))
|
||||
if len(repoIDs) == 0 {
|
||||
return repos, nil
|
||||
}
|
||||
|
||||
return repos, db.GetEngine(env.ctx).
|
||||
In("`repository`.id", repoIDs).
|
||||
Find(&repos)
|
||||
}
|
||||
|
||||
func (env *accessibleReposEnv) AddKeyword(keyword string) {
|
||||
env.keyword = keyword
|
||||
}
|
||||
|
||||
func (env *accessibleReposEnv) SetSort(orderBy db.SearchOrderBy) {
|
||||
env.orderBy = orderBy
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func TestFindOrgs(t *testing.T) {
|
||||
IncludePrivate: false,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, orgs, 0)
|
||||
assert.Empty(t, orgs)
|
||||
|
||||
total, err := db.Count[organization.Organization](db.DefaultContext, organization.FindOrgOptions{
|
||||
UserID: 4,
|
||||
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package organization
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
)
|
||||
|
||||
// GetOrgRepositories get repos belonging to the given organization
|
||||
func GetOrgRepositories(ctx context.Context, orgID int64) (repo_model.RepositoryList, error) {
|
||||
var orgRepos []*repo_model.Repository
|
||||
return orgRepos, db.GetEngine(ctx).Where("owner_id = ?", orgID).Find(&orgRepos)
|
||||
}
|
@ -283,7 +283,7 @@ func TestGetOrgUsersByOrgID(t *testing.T) {
|
||||
OrgID: unittest.NonexistentID,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, orgUsers, 0)
|
||||
assert.Empty(t, orgUsers)
|
||||
}
|
||||
|
||||
func TestChangeOrgUserStatus(t *testing.T) {
|
||||
@ -318,7 +318,7 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
|
||||
testSuccess := func(userID, expectedCount int64) {
|
||||
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||
env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||
assert.NoError(t, err)
|
||||
count, err := env.CountRepos()
|
||||
assert.NoError(t, err)
|
||||
@ -332,7 +332,7 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
|
||||
testSuccess := func(userID int64, expectedRepoIDs []int64) {
|
||||
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||
env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||
assert.NoError(t, err)
|
||||
repoIDs, err := env.RepoIDs(1, 100)
|
||||
assert.NoError(t, err)
|
||||
@ -346,7 +346,7 @@ func TestAccessibleReposEnv_Repos(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
|
||||
testSuccess := func(userID int64, expectedRepoIDs []int64) {
|
||||
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||
env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||
assert.NoError(t, err)
|
||||
repos, err := env.Repos(1, 100)
|
||||
assert.NoError(t, err)
|
||||
@ -365,7 +365,7 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
|
||||
testSuccess := func(userID int64, expectedRepoIDs []int64) {
|
||||
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||
env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||
assert.NoError(t, err)
|
||||
repos, err := env.MirrorRepos()
|
||||
assert.NoError(t, err)
|
||||
|
@ -36,6 +36,21 @@ func init() {
|
||||
db.RegisterModel(new(OrgUser))
|
||||
}
|
||||
|
||||
// ErrUserHasOrgs represents a "UserHasOrgs" kind of error.
|
||||
type ErrUserHasOrgs struct {
|
||||
UID int64
|
||||
}
|
||||
|
||||
// IsErrUserHasOrgs checks if an error is a ErrUserHasOrgs.
|
||||
func IsErrUserHasOrgs(err error) bool {
|
||||
_, ok := err.(ErrUserHasOrgs)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserHasOrgs) Error() string {
|
||||
return fmt.Sprintf("user still has membership of organizations [uid: %d]", err.UID)
|
||||
}
|
||||
|
||||
// GetOrganizationCount returns count of membership of organization of the user.
|
||||
func GetOrganizationCount(ctx context.Context, u *user_model.User) (int64, error) {
|
||||
return db.GetEngine(ctx).
|
||||
|
@ -131,7 +131,7 @@ func TestAddOrgUser(t *testing.T) {
|
||||
testSuccess := func(orgID, userID int64, isPublic bool) {
|
||||
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID})
|
||||
expectedNumMembers := org.NumMembers
|
||||
if !unittest.BeanExists(t, &organization.OrgUser{OrgID: orgID, UID: userID}) {
|
||||
if unittest.GetBean(t, &organization.OrgUser{OrgID: orgID, UID: userID}) == nil {
|
||||
expectedNumMembers++
|
||||
}
|
||||
assert.NoError(t, organization.AddOrgUser(db.DefaultContext, orgID, userID))
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@ -78,9 +77,8 @@ type Team struct {
|
||||
LowerName string
|
||||
Name string
|
||||
Description string
|
||||
AccessMode perm.AccessMode `xorm:"'authorize'"`
|
||||
Repos []*repo_model.Repository `xorm:"-"`
|
||||
Members []*user_model.User `xorm:"-"`
|
||||
AccessMode perm.AccessMode `xorm:"'authorize'"`
|
||||
Members []*user_model.User `xorm:"-"`
|
||||
NumRepos int
|
||||
NumMembers int
|
||||
Units []*TeamUnit `xorm:"-"`
|
||||
@ -155,17 +153,6 @@ func (t *Team) IsMember(ctx context.Context, userID int64) bool {
|
||||
return isMember
|
||||
}
|
||||
|
||||
// LoadRepositories returns paginated repositories in team of organization.
|
||||
func (t *Team) LoadRepositories(ctx context.Context) (err error) {
|
||||
if t.Repos != nil {
|
||||
return nil
|
||||
}
|
||||
t.Repos, err = GetTeamRepositories(ctx, &SearchTeamRepoOptions{
|
||||
TeamID: t.ID,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// LoadMembers returns paginated members in team of organization.
|
||||
func (t *Team) LoadMembers(ctx context.Context) (err error) {
|
||||
t.Members, err = GetTeamMembers(ctx, &SearchMembersOptions{
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
|
||||
"xorm.io/builder"
|
||||
@ -98,11 +97,11 @@ func SearchTeam(ctx context.Context, opts *SearchTeamOptions) (TeamList, int64,
|
||||
}
|
||||
|
||||
// GetRepoTeams gets the list of teams that has access to the repository
|
||||
func GetRepoTeams(ctx context.Context, repo *repo_model.Repository) (teams TeamList, err error) {
|
||||
func GetRepoTeams(ctx context.Context, orgID, repoID int64) (teams TeamList, err error) {
|
||||
return teams, db.GetEngine(ctx).
|
||||
Join("INNER", "team_repo", "team_repo.team_id = team.id").
|
||||
Where("team.org_id = ?", repo.OwnerID).
|
||||
And("team_repo.repo_id=?", repo.ID).
|
||||
Where("team.org_id = ?", orgID).
|
||||
And("team_repo.repo_id=?", repoID).
|
||||
OrderBy("CASE WHEN name LIKE '" + OwnerTeamName + "' THEN '' ELSE name END").
|
||||
Find(&teams)
|
||||
}
|
||||
@ -131,3 +130,8 @@ func GetTeamsByOrgIDs(ctx context.Context, orgIDs []int64) (TeamList, error) {
|
||||
teams := make([]*Team, 0, 10)
|
||||
return teams, db.GetEngine(ctx).Where(builder.In("org_id", orgIDs)).Find(&teams)
|
||||
}
|
||||
|
||||
func GetTeamsByIDs(ctx context.Context, teamIDs []int64) (map[int64]*Team, error) {
|
||||
teams := make(map[int64]*Team, len(teamIDs))
|
||||
return teams, db.GetEngine(ctx).Where(builder.In("`id`", teamIDs)).Find(&teams)
|
||||
}
|
||||
|
25
models/organization/team_list_test.go
Normal file
25
models/organization/team_list_test.go
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package organization_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
org_model "code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_GetTeamsByIDs(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
// 1 owner team, 2 normal team
|
||||
teams, err := org_model.GetTeamsByIDs(db.DefaultContext, []int64{1, 2})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, teams, 2)
|
||||
assert.Equal(t, "Owners", teams[1].Name)
|
||||
assert.Equal(t, "team1", teams[2].Name)
|
||||
}
|
@ -8,10 +8,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// TeamRepo represents an team-repository relation.
|
||||
@ -32,29 +29,6 @@ func HasTeamRepo(ctx context.Context, orgID, teamID, repoID int64) bool {
|
||||
return has
|
||||
}
|
||||
|
||||
type SearchTeamRepoOptions struct {
|
||||
db.ListOptions
|
||||
TeamID int64
|
||||
}
|
||||
|
||||
// GetRepositories returns paginated repositories in team of organization.
|
||||
func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) (repo_model.RepositoryList, error) {
|
||||
sess := db.GetEngine(ctx)
|
||||
if opts.TeamID > 0 {
|
||||
sess = sess.In("id",
|
||||
builder.Select("repo_id").
|
||||
From("team_repo").
|
||||
Where(builder.Eq{"team_id": opts.TeamID}),
|
||||
)
|
||||
}
|
||||
if opts.PageSize > 0 {
|
||||
sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
|
||||
}
|
||||
var repos []*repo_model.Repository
|
||||
return repos, sess.OrderBy("repository.name").
|
||||
Find(&repos)
|
||||
}
|
||||
|
||||
// AddTeamRepo adds a repo for an organization's team
|
||||
func AddTeamRepo(ctx context.Context, orgID, teamID, repoID int64) error {
|
||||
_, err := db.GetEngine(ctx).Insert(&TeamRepo{
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -42,9 +43,12 @@ func TestTeam_GetRepositories(t *testing.T) {
|
||||
|
||||
test := func(teamID int64) {
|
||||
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
|
||||
assert.NoError(t, team.LoadRepositories(db.DefaultContext))
|
||||
assert.Len(t, team.Repos, team.NumRepos)
|
||||
for _, repo := range team.Repos {
|
||||
repos, err := repo_model.GetTeamRepositories(db.DefaultContext, &repo_model.SearchTeamRepoOptions{
|
||||
TeamID: team.ID,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, repos, team.NumRepos)
|
||||
for _, repo := range repos {
|
||||
unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repo.ID})
|
||||
}
|
||||
}
|
||||
|
@ -301,6 +301,21 @@ func FindUnreferencedPackages(ctx context.Context) ([]*Package, error) {
|
||||
Find(&ps)
|
||||
}
|
||||
|
||||
// ErrUserOwnPackages notifies that the user (still) owns the packages.
|
||||
type ErrUserOwnPackages struct {
|
||||
UID int64
|
||||
}
|
||||
|
||||
// IsErrUserOwnPackages checks if an error is an ErrUserOwnPackages.
|
||||
func IsErrUserOwnPackages(err error) bool {
|
||||
_, ok := err.(ErrUserOwnPackages)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrUserOwnPackages) Error() string {
|
||||
return fmt.Sprintf("user still has ownership of packages [uid: %d]", err.UID)
|
||||
}
|
||||
|
||||
// HasOwnerPackages tests if a user/org has accessible packages
|
||||
func HasOwnerPackages(ctx context.Context, ownerID int64) (bool, error) {
|
||||
return db.GetEngine(ctx).
|
||||
|
@ -15,7 +15,7 @@ func TestAccessMode(t *testing.T) {
|
||||
m := ParseAccessMode(name)
|
||||
assert.Equal(t, AccessMode(i), m)
|
||||
}
|
||||
assert.Equal(t, AccessMode(4), AccessModeOwner)
|
||||
assert.Equal(t, AccessModeOwner, AccessMode(4))
|
||||
assert.Equal(t, "owner", AccessModeOwner.ToString())
|
||||
assert.Equal(t, AccessModeNone, ParseAccessMode("owner"))
|
||||
assert.Equal(t, AccessModeNone, ParseAccessMode("invalid"))
|
||||
|
@ -5,7 +5,6 @@ package project
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
@ -66,7 +65,7 @@ func Test_moveIssuesToAnotherColumn(t *testing.T) {
|
||||
|
||||
issues, err = column1.GetIssues(db.DefaultContext)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, issues, 0)
|
||||
assert.Empty(t, issues)
|
||||
|
||||
issues, err = column2.GetIssues(db.DefaultContext)
|
||||
assert.NoError(t, err)
|
||||
@ -123,5 +122,5 @@ func Test_NewColumn(t *testing.T) {
|
||||
ProjectID: project1.ID,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.True(t, strings.Contains(err.Error(), "maximum number of columns reached"))
|
||||
assert.Contains(t, err.Error(), "maximum number of columns reached")
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ func NewProject(ctx context.Context, p *Project) error {
|
||||
return util.NewInvalidArgumentErrorf("project type is not valid")
|
||||
}
|
||||
|
||||
p.Title, _ = util.SplitStringAtByteN(p.Title, 255)
|
||||
p.Title = util.EllipsisDisplayString(p.Title, 255)
|
||||
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
if err := db.Insert(ctx, p); err != nil {
|
||||
@ -311,7 +311,7 @@ func UpdateProject(ctx context.Context, p *Project) error {
|
||||
p.CardType = CardTypeTextOnly
|
||||
}
|
||||
|
||||
p.Title, _ = util.SplitStringAtByteN(p.Title, 255)
|
||||
p.Title = util.EllipsisDisplayString(p.Title, 255)
|
||||
_, err := db.GetEngine(ctx).ID(p.ID).Cols(
|
||||
"title",
|
||||
"description",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user