diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 0af524b143e..00000000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,1005 +0,0 @@ -const vitestPlugin = require('@vitest/eslint-plugin'); -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-wc', - ], - env: { - es2024: true, - node: true, - }, - overrides: [ - { - files: ['**/*.cjs'], - rules: { - 'import-x/no-commonjs': [0], - '@typescript-eslint/no-require-imports': [0], - }, - }, - { - 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'], - plugins: ['@vitest/eslint-plugin'], - globals: vitestPlugin.environments.env.globals, - rules: { - 'github/unescaped-html-literal': [0], - '@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': [2], - '@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/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-unnecessary-type-conversion': [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': [2, {functions: false, classes: true, variables: true, allowNamedExports: true, typedefs: false, enums: false, ignoreTypeReferences: true}], - '@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': [0], // https://github.com/github/eslint-plugin-github/issues/599 - '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': [2], - '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': [0], - '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': [0], // handled by @typescript-eslint/no-implied-eval - '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': [0], // handled by @typescript-eslint/no-use-before-define - '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-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'], - }, -}; diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index c6daee84115..6f8991ed4ee 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -35,11 +35,9 @@ jobs: - uses: astral-sh/setup-uv@v6 - run: uv python install 3.12 - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - run: make deps-py - run: make deps-frontend - run: make lint-templates @@ -62,11 +60,9 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - run: make deps-frontend - run: make lint-swagger @@ -134,11 +130,9 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - run: make deps-frontend - run: make lint-frontend - run: make checks-frontend @@ -184,11 +178,9 @@ jobs: steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - run: make deps-frontend - run: make lint-md diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml index 9f42581e0c8..89b32260ca0 100644 --- a/.github/workflows/pull-e2e-tests.yml +++ b/.github/workflows/pull-e2e-tests.yml @@ -24,11 +24,9 @@ jobs: go-version-file: go.mod check-latest: true - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - run: make deps-frontend frontend deps-backend - run: pnpm exec playwright install --with-deps - run: make test-e2e-sqlite diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index 81041bf564c..3d652e4ad8b 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -21,11 +21,9 @@ jobs: go-version-file: go.mod check-latest: true - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - run: make deps-frontend deps-backend # xgo build - run: make release diff --git a/.github/workflows/release-tag-rc.yml b/.github/workflows/release-tag-rc.yml index f7ca1d0a139..f4776a9ed8c 100644 --- a/.github/workflows/release-tag-rc.yml +++ b/.github/workflows/release-tag-rc.yml @@ -22,11 +22,9 @@ jobs: go-version-file: go.mod check-latest: true - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - run: make deps-frontend deps-backend # xgo build - run: make release diff --git a/.github/workflows/release-tag-version.yml b/.github/workflows/release-tag-version.yml index 43ea6dce2fd..ad0820f31fe 100644 --- a/.github/workflows/release-tag-version.yml +++ b/.github/workflows/release-tag-version.yml @@ -26,11 +26,9 @@ jobs: go-version-file: go.mod check-latest: true - uses: pnpm/action-setup@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: node-version: 24 - cache: pnpm - cache-dependency-path: pnpm-lock.yaml - run: make deps-frontend deps-backend # xgo build - run: make release diff --git a/Makefile b/Makefile index 1fb4a40d716..637e64210ac 100644 --- a/Makefile +++ b/Makefile @@ -162,7 +162,7 @@ TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(DIST) GO_DIRS := build cmd models modules routers services tests WEB_DIRS := web_src/js web_src/css -ESLINT_FILES := web_src/js tools *.ts *.cjs tests/e2e +ESLINT_FILES := web_src/js tools *.ts tests/e2e STYLELINT_FILES := web_src/css web_src/js/components/*.vue SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.md *.yml *.yaml *.toml)) $(filter-out tools/misspellings.csv, $(wildcard tools/*)) EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini @@ -346,12 +346,12 @@ lint-backend-fix: lint-go-fix lint-go-gitea-vet lint-editorconfig ## lint backen .PHONY: lint-js lint-js: node_modules ## lint js files - $(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) + $(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --flag unstable_native_nodejs_ts_config $(ESLINT_FILES) $(NODE_VARS) pnpm exec vue-tsc .PHONY: lint-js-fix lint-js-fix: node_modules ## lint js files and fix issues - $(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) --fix + $(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --flag unstable_native_nodejs_ts_config $(ESLINT_FILES) --fix $(NODE_VARS) pnpm exec vue-tsc .PHONY: lint-css diff --git a/assets/go-licenses.json b/assets/go-licenses.json index d645009d90f..9c19080e246 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -579,11 +579,6 @@ "path": "github.com/go-webauthn/x/revoke/LICENSE", "licenseText": "Copyright (c) 2014 CloudFlare Inc.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\nRedistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, - { - "name": "github.com/gobwas/glob", - "path": "github.com/gobwas/glob/LICENSE", - "licenseText": "The MIT License (MIT)\n\nCopyright (c) 2016 Sergey Kamardin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." - }, { "name": "github.com/goccy/go-json", "path": "github.com/goccy/go-json/LICENSE", diff --git a/cmd/dump.go b/cmd/dump.go index fa135079c09..7f0b23ed984 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -265,6 +265,7 @@ func runDump(ctx context.Context, cmd *cli.Command) error { excludes = append(excludes, setting.LFS.Storage.Path) excludes = append(excludes, setting.Attachment.Storage.Path) excludes = append(excludes, setting.Packages.Storage.Path) + excludes = append(excludes, setting.RepoArchive.Storage.Path) excludes = append(excludes, setting.Log.RootPath) if err := dumper.AddRecursiveExclude("data", setting.AppDataPath, excludes); err != nil { fatal("Failed to include data directory: %v", err) diff --git a/cmd/embedded.go b/cmd/embedded.go index 1908352453f..9180407fd18 100644 --- a/cmd/embedded.go +++ b/cmd/embedded.go @@ -12,6 +12,7 @@ import ( "strings" "code.gitea.io/gitea/modules/assetfs" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/options" "code.gitea.io/gitea/modules/public" @@ -19,7 +20,6 @@ import ( "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/util" - "github.com/gobwas/glob" "github.com/urfave/cli/v3" ) diff --git a/cmd/hook.go b/cmd/hook.go index b741127ca3c..2f866dd396b 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -15,6 +15,7 @@ import ( "time" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" repo_module "code.gitea.io/gitea/modules/repository" @@ -312,7 +313,7 @@ func runHookPostReceive(ctx context.Context, c *cli.Command) error { setup(ctx, c.Bool("debug")) // First of all run update-server-info no matter what - if _, _, err := git.NewCommand("update-server-info").RunStdString(ctx, nil); err != nil { + if _, _, err := gitcmd.NewCommand("update-server-info").RunStdString(ctx, nil); err != nil { return fmt.Errorf("failed to call 'git update-server-info': %w", err) } diff --git a/cmd/serv.go b/cmd/serv.go index 089d0e3bb7c..76d8c81544e 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -21,6 +21,7 @@ import ( "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/lfstransfer" "code.gitea.io/gitea/modules/log" @@ -229,11 +230,6 @@ func runServ(ctx context.Context, c *cli.Command) error { username := repoPathFields[0] reponame := strings.TrimSuffix(repoPathFields[1], ".git") // “the-repo-name" or "the-repo-name.wiki" - // LowerCase and trim the repoPath as that's how they are stored. - // This should be done after splitting the repoPath into username and reponame - // so that username and reponame are not affected. - repoPath = strings.ToLower(strings.TrimSpace(repoPath)) - if !repo.IsValidSSHAccessRepoName(reponame) { return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame) } @@ -280,6 +276,11 @@ func runServ(ctx context.Context, c *cli.Command) error { return fail(ctx, extra.UserMsg, "ServCommand failed: %s", extra.Error) } + // LowerCase and trim the repoPath as that's how they are stored. + // This should be done after splitting the repoPath into username and reponame + // so that username and reponame are not affected. + repoPath = strings.ToLower(results.OwnerName + "/" + results.RepoName + ".git") + // LFS SSH protocol if verb == git.CmdVerbLfsTransfer { token, err := getLFSAuthToken(ctx, lfsVerb, results) @@ -312,30 +313,30 @@ func runServ(ctx context.Context, c *cli.Command) error { return nil } - var gitcmd *exec.Cmd - gitBinPath := filepath.Dir(git.GitExecutable) // e.g. /usr/bin - gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack + var command *exec.Cmd + gitBinPath := filepath.Dir(gitcmd.GitExecutable) // e.g. /usr/bin + gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack if _, err := os.Stat(gitBinVerb); err != nil { // if the command "git-upload-pack" doesn't exist, try to split "git-upload-pack" to use the sub-command with git // ps: Windows only has "git.exe" in the bin path, so Windows always uses this way verbFields := strings.SplitN(verb, "-", 2) if len(verbFields) == 2 { // use git binary with the sub-command part: "C:\...\bin\git.exe", "upload-pack", ... - gitcmd = exec.CommandContext(ctx, git.GitExecutable, verbFields[1], repoPath) + command = exec.CommandContext(ctx, gitcmd.GitExecutable, verbFields[1], repoPath) } } - if gitcmd == nil { + if command == nil { // by default, use the verb (it has been checked above by allowedCommands) - gitcmd = exec.CommandContext(ctx, gitBinVerb, repoPath) + command = exec.CommandContext(ctx, gitBinVerb, repoPath) } - process.SetSysProcAttribute(gitcmd) - gitcmd.Dir = setting.RepoRootPath - gitcmd.Stdout = os.Stdout - gitcmd.Stdin = os.Stdin - gitcmd.Stderr = os.Stderr - gitcmd.Env = append(gitcmd.Env, os.Environ()...) - gitcmd.Env = append(gitcmd.Env, + process.SetSysProcAttribute(command) + command.Dir = setting.RepoRootPath + command.Stdout = os.Stdout + command.Stdin = os.Stdin + command.Stderr = os.Stderr + command.Env = append(command.Env, os.Environ()...) + command.Env = append(command.Env, repo_module.EnvRepoIsWiki+"="+strconv.FormatBool(results.IsWiki), repo_module.EnvRepoName+"="+results.RepoName, repo_module.EnvRepoUsername+"="+results.OwnerName, @@ -350,9 +351,9 @@ func runServ(ctx context.Context, c *cli.Command) error { ) // to avoid breaking, here only use the minimal environment variables for the "gitea serv" command. // it could be re-considered whether to use the same git.CommonGitCmdEnvs() as "git" command later. - gitcmd.Env = append(gitcmd.Env, git.CommonCmdServEnvs()...) + command.Env = append(command.Env, gitcmd.CommonCmdServEnvs()...) - if err = gitcmd.Run(); err != nil { + if err = command.Run(); err != nil { return fail(ctx, "Failed to execute git command", "Failed to execute git command: %v", err) } diff --git a/contrib/backport/README b/contrib/backport/README index 1e84c1bb974..466b79c6d49 100644 --- a/contrib/backport/README +++ b/contrib/backport/README @@ -11,7 +11,7 @@ The default version will read from `docs/config.yml`. You can override this using the option `--version`. The upstream branches will be fetched, using the remote `origin`. This can -be overrided using `--upstream`, and fetching can be avoided using +be overridden using `--upstream`, and fetching can be avoided using `--no-fetch`. By default the branch created will be called `backport-$PR-$VERSION`. You diff --git a/contrib/legal/privacy.html.sample b/contrib/legal/privacy.html.sample index 50972b2a3ec..adb3ea7ad4b 100644 --- a/contrib/legal/privacy.html.sample +++ b/contrib/legal/privacy.html.sample @@ -150,7 +150,7 @@
In general, Your Gitea Instance retains User Personal Information for as long as your account is active, or as needed to provide you service.
-If you would like to cancel your account or delete your User Personal Information, you may do so in your user profile. We retain and use your information as necessary to comply with our legal obligations, resolve disputes, and enforce our agreements, but barring legal requirements, we will delete your full profile (within reason) within 90 days of your request. Feel free to contact our support to request erasure of the data we process on the bassis of consent within 30 days.
+If you would like to cancel your account or delete your User Personal Information, you may do so in your user profile. We retain and use your information as necessary to comply with our legal obligations, resolve disputes, and enforce our agreements, but barring legal requirements, we will delete your full profile (within reason) within 90 days of your request. Feel free to contact our support to request erasure of the data we process on the basis of consent within 30 days.
After an account has been deleted, certain data, such as contributions to other Users' repositories and comments in others' issues, will remain. However, we will delete or de-identify your User Personal Information, including your username and email address, from the author field of issues, pull requests, and comments by associating them with a ghost user.
diff --git a/eslint.config.ts b/eslint.config.ts new file mode 100644 index 00000000000..678a49647c0 --- /dev/null +++ b/eslint.config.ts @@ -0,0 +1,1029 @@ +import arrayFunc from 'eslint-plugin-array-func'; +import comments from '@eslint-community/eslint-plugin-eslint-comments'; +import github from 'eslint-plugin-github'; +import globals from 'globals'; +import importPlugin from 'eslint-plugin-import-x'; +import noUseExtendNative from 'eslint-plugin-no-use-extend-native'; +import playwright from 'eslint-plugin-playwright'; +import regexp from 'eslint-plugin-regexp'; +import sonarjs from 'eslint-plugin-sonarjs'; +import stylistic from '@stylistic/eslint-plugin'; +import typescriptParser from '@typescript-eslint/parser'; +import typescriptPlugin from 'typescript-eslint'; +import unicorn from 'eslint-plugin-unicorn'; +import vitest from '@vitest/eslint-plugin'; +import vue from 'eslint-plugin-vue'; +import vueScopedCss from 'eslint-plugin-vue-scoped-css'; +import wc from 'eslint-plugin-wc'; +import {defineConfig, globalIgnores} from 'eslint/config'; + +const jsExts = ['js', 'mjs', 'cjs'] as const; +const tsExts = ['ts', 'mts', 'cts'] as const; +const restrictedSyntax = ['WithStatement', 'ForInStatement', 'LabeledStatement', 'SequenceExpression']; + +export default defineConfig([ + globalIgnores([ + 'web_src/js/vendor', + 'web_src/fomantic', + 'public/assets/js', + ]), + { + files: [`**/*.{${[...jsExts, ...tsExts].join(',')}}`], + ignores: ['dist/*'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.node, + }, + parser: typescriptParser, + parserOptions: { + sourceType: 'module', + ecmaVersion: 'latest', + ecmaFeatures: { + impliedStrict: true, + }, + project: true, + }, + }, + linterOptions: { + reportUnusedDisableDirectives: 2, + }, + plugins: { + '@eslint-community/eslint-comments': comments, + // @ts-expect-error + '@stylistic': stylistic, + '@typescript-eslint': typescriptPlugin.plugin, + 'array-func': arrayFunc, + // @ts-expect-error -- https://github.com/un-ts/eslint-plugin-import-x/issues/203 + 'import-x': importPlugin, + 'no-use-extend-native': noUseExtendNative, + // @ts-expect-error + regexp, + // @ts-expect-error + sonarjs, + // @ts-expect-error + unicorn, + github, + // @ts-expect-error + wc, + }, + settings: { + 'import-x/extensions': [...jsExts, ...tsExts].map((ext) => `.${ext}`), + 'import-x/parsers': {'@typescript-eslint/parser': [...jsExts, ...tsExts].map((ext) => `.${ext}`)}, + 'import-x/resolver': {'typescript': true}, + }, + 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/array-bracket-newline': [0], + '@stylistic/array-bracket-spacing': [2, 'never'], + '@stylistic/array-element-newline': [0], + '@stylistic/arrow-parens': [2, 'always'], + '@stylistic/arrow-spacing': [2, {before: true, after: true}], + '@stylistic/block-spacing': [0], + '@stylistic/brace-style': [2, '1tbs', {allowSingleLine: true}], + '@stylistic/comma-dangle': [2, 'always-multiline'], + '@stylistic/comma-spacing': [2, {before: false, after: true}], + '@stylistic/comma-style': [2, 'last'], + '@stylistic/computed-property-spacing': [2, 'never'], + '@stylistic/dot-location': [2, 'property'], + '@stylistic/eol-last': [2], + '@stylistic/function-call-argument-newline': [0], + '@stylistic/function-call-spacing': [2, 'never'], + '@stylistic/function-paren-newline': [0], + '@stylistic/generator-star-spacing': [0], + '@stylistic/implicit-arrow-linebreak': [0], + '@stylistic/indent': [2, 2, {ignoreComments: true, SwitchCase: 1}], + '@stylistic/key-spacing': [2], + '@stylistic/keyword-spacing': [2], + '@stylistic/line-comment-position': [0], + '@stylistic/linebreak-style': [2, 'unix'], + '@stylistic/lines-around-comment': [0], + '@stylistic/lines-between-class-members': [0], + '@stylistic/max-len': [0], + '@stylistic/max-statements-per-line': [0], + '@stylistic/multiline-comment-style': [0], + '@stylistic/multiline-ternary': [0], + '@stylistic/new-parens': [2], + '@stylistic/newline-per-chained-call': [0], + '@stylistic/no-confusing-arrow': [0], + '@stylistic/no-extra-parens': [0], + '@stylistic/no-extra-semi': [2], + '@stylistic/no-floating-decimal': [0], + '@stylistic/no-mixed-operators': [0], + '@stylistic/no-mixed-spaces-and-tabs': [2], + '@stylistic/no-multi-spaces': [2, {ignoreEOLComments: true, exceptions: {Property: true}}], + '@stylistic/no-multiple-empty-lines': [2, {max: 1, maxEOF: 0, maxBOF: 0}], + '@stylistic/no-tabs': [2], + '@stylistic/no-trailing-spaces': [2], + '@stylistic/no-whitespace-before-property': [2], + '@stylistic/nonblock-statement-body-position': [2], + '@stylistic/object-curly-newline': [0], + '@stylistic/object-curly-spacing': [2, 'never'], + '@stylistic/object-property-newline': [0], + '@stylistic/one-var-declaration-per-line': [0], + '@stylistic/operator-linebreak': [2, 'after'], + '@stylistic/padded-blocks': [2, 'never'], + '@stylistic/padding-line-between-statements': [0], + '@stylistic/quote-props': [0], + '@stylistic/quotes': [2, 'single', {avoidEscape: true, allowTemplateLiterals: 'always'}], + '@stylistic/rest-spread-spacing': [2, 'never'], + '@stylistic/semi': [2, 'always', {omitLastInOneLineBlock: true}], + '@stylistic/semi-spacing': [2, {before: false, after: true}], + '@stylistic/semi-style': [2, 'last'], + '@stylistic/space-before-blocks': [2, 'always'], + '@stylistic/space-before-function-paren': [2, {anonymous: 'ignore', named: 'never', asyncArrow: 'always'}], + '@stylistic/space-in-parens': [2, 'never'], + '@stylistic/space-infix-ops': [2], + '@stylistic/space-unary-ops': [2], + '@stylistic/spaced-comment': [2, 'always'], + '@stylistic/switch-colon-spacing': [2], + '@stylistic/template-curly-spacing': [2, 'never'], + '@stylistic/template-tag-spacing': [2, 'never'], + '@stylistic/wrap-iife': [2, 'inside'], + '@stylistic/wrap-regex': [0], + '@stylistic/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-unnecessary-type-conversion': [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': [2, {functions: false, classes: true, variables: true, allowNamedExports: true, typedefs: false, enums: false, ignoreTypeReferences: true}], + '@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': [0], // https://github.com/github/eslint-plugin-github/issues/599 + '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': [2], + '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}], // not compatible with eslint 9 + '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': [0], + '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': [0], // handled by @typescript-eslint/no-implied-eval + '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': [0], // handled by @typescript-eslint/no-use-before-define + '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-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-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'], + }, + }, + // @ts-expect-error + { + ...playwright.configs['flat/recommended'], + files: ['tests/e2e/**'], + rules: { + ...playwright.configs['flat/recommended'].rules, + }, + }, + { + files: ['**/*.vue'], + languageOptions: { + parserOptions: { + parser: '@typescript-eslint/parser', + }, + }, + extends: [ + // @ts-expect-error + vue.configs['flat/recommended'], + // @ts-expect-error + vueScopedCss.configs['flat/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: ['web_src/js/modules/fetch.ts', 'web_src/js/standalone/**/*'], + rules: { + 'no-restricted-syntax': [2, ...restrictedSyntax], + }, + }, + { + files: ['**/*.test.ts', 'web_src/js/test/setup.ts'], + // @ts-expect-error - https://github.com/vitest-dev/eslint-plugin-vitest/issues/737 + plugins: {vitest}, + languageOptions: {globals: globals.vitest}, + rules: { + 'github/unescaped-html-literal': [0], + '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': [2], + '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/types.ts'], + 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: ['*.config.*'], + rules: { + 'import-x/no-unused-modules': [0], + }, + }, + { + files: ['web_src/**/*', 'docs/**/*'], + languageOptions: {globals: globals.browser}, + }, + { + files: ['web_src/**/*'], + languageOptions: { + globals: { + ...globals.browser, + __webpack_public_path__: true, + process: false, // https://github.com/webpack/webpack/issues/15833 + }, + }, + }, +]); diff --git a/go.mod b/go.mod index eb871e24ae1..f32c3e08ef4 100644 --- a/go.mod +++ b/go.mod @@ -61,7 +61,6 @@ require ( github.com/go-redsync/redsync/v4 v4.13.0 github.com/go-sql-driver/mysql v1.9.3 github.com/go-webauthn/webauthn v0.13.4 - github.com/gobwas/glob v0.2.3 github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 github.com/golang-jwt/jwt/v5 v5.3.0 diff --git a/go.sum b/go.sum index b69b380cfe2..1853693e90d 100644 --- a/go.sum +++ b/go.sum @@ -364,8 +364,6 @@ github.com/go-webauthn/webauthn v0.13.4 h1:q68qusWPcqHbg9STSxBLBHnsKaLxNO0RnVKaA github.com/go-webauthn/webauthn v0.13.4/go.mod h1:MglN6OH9ECxvhDqoq1wMoF6P6JRYDiQpC9nc5OomQmI= github.com/go-webauthn/x v0.1.24 h1:6LaWf2zzWqbyKT8IyQkhje1/1KCGhlEkMz4V1tDnt/A= github.com/go-webauthn/x v0.1.24/go.mod h1:2o5XKJ+X1AKqYKGgHdKflGnoQFQZ6flJ2IFCBKSbSOw= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= diff --git a/models/asymkey/gpg_key_add.go b/models/asymkey/gpg_key_add.go index 1c7d2c1da26..3969edcc869 100644 --- a/models/asymkey/gpg_key_add.go +++ b/models/asymkey/gpg_key_add.go @@ -72,96 +72,90 @@ func AddGPGKey(ctx context.Context, ownerID int64, content, token, signature str return nil, err } - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return nil, err - } - defer committer.Close() + return db.WithTx2(ctx, func(ctx context.Context) ([]*GPGKey, error) { + keys := make([]*GPGKey, 0, len(ekeys)) - keys := make([]*GPGKey, 0, len(ekeys)) - - verified := false - // Handle provided signature - if signature != "" { - signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature), nil) - if err != nil { - signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature), nil) - } - if err != nil { - signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil) - } - if err != nil { - log.Debug("AddGPGKey CheckArmoredDetachedSignature failed: %v", err) - return nil, ErrGPGInvalidTokenSignature{ - ID: ekeys[0].PrimaryKey.KeyIdString(), - Wrapped: err, + verified := false + // Handle provided signature + if signature != "" { + signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature), nil) + if err != nil { + signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature), nil) } + if err != nil { + signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil) + } + if err != nil { + log.Debug("AddGPGKey CheckArmoredDetachedSignature failed: %v", err) + return nil, ErrGPGInvalidTokenSignature{ + ID: ekeys[0].PrimaryKey.KeyIdString(), + Wrapped: err, + } + } + ekeys = []*openpgp.Entity{signer} + verified = true } - ekeys = []*openpgp.Entity{signer} - verified = true - } - if len(ekeys) > 1 { - id2key := map[string]*openpgp.Entity{} - newEKeys := make([]*openpgp.Entity, 0, len(ekeys)) - for _, ekey := range ekeys { - id := ekey.PrimaryKey.KeyIdString() - if original, has := id2key[id]; has { - // Coalesce this with the other one - for _, subkey := range ekey.Subkeys { - if subkey.PublicKey == nil { - continue - } - found := false - - for _, originalSubkey := range original.Subkeys { - if originalSubkey.PublicKey == nil { + if len(ekeys) > 1 { + id2key := map[string]*openpgp.Entity{} + newEKeys := make([]*openpgp.Entity, 0, len(ekeys)) + for _, ekey := range ekeys { + id := ekey.PrimaryKey.KeyIdString() + if original, has := id2key[id]; has { + // Coalesce this with the other one + for _, subkey := range ekey.Subkeys { + if subkey.PublicKey == nil { continue } - if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId { - found = true - break + found := false + + for _, originalSubkey := range original.Subkeys { + if originalSubkey.PublicKey == nil { + continue + } + if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId { + found = true + break + } + } + if !found { + original.Subkeys = append(original.Subkeys, subkey) } } - if !found { - original.Subkeys = append(original.Subkeys, subkey) + for name, identity := range ekey.Identities { + if _, has := original.Identities[name]; has { + continue + } + original.Identities[name] = identity } + continue } - for name, identity := range ekey.Identities { - if _, has := original.Identities[name]; has { - continue - } - original.Identities[name] = identity - } - continue + id2key[id] = ekey + newEKeys = append(newEKeys, ekey) } - id2key[id] = ekey - newEKeys = append(newEKeys, ekey) - } - ekeys = newEKeys - } - - for _, ekey := range ekeys { - // Key ID cannot be duplicated. - has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()). - Get(new(GPGKey)) - if err != nil { - return nil, err - } else if has { - return nil, ErrGPGKeyIDAlreadyUsed{ekey.PrimaryKey.KeyIdString()} + ekeys = newEKeys } - // Get DB session + for _, ekey := range ekeys { + // Key ID cannot be duplicated. + has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()). + Get(new(GPGKey)) + if err != nil { + return nil, err + } else if has { + return nil, ErrGPGKeyIDAlreadyUsed{ekey.PrimaryKey.KeyIdString()} + } - key, err := parseGPGKey(ctx, ownerID, ekey, verified) - if err != nil { - return nil, err - } + key, err := parseGPGKey(ctx, ownerID, ekey, verified) + if err != nil { + return nil, err + } - if err = addGPGKey(ctx, key, content); err != nil { - return nil, err + if err = addGPGKey(ctx, key, content); err != nil { + return nil, err + } + keys = append(keys, key) } - keys = append(keys, key) - } - return keys, committer.Commit() + return keys, nil + }) } diff --git a/models/asymkey/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go index b85374e0735..375b703f7b3 100644 --- a/models/asymkey/gpg_key_commit_verification.go +++ b/models/asymkey/gpg_key_commit_verification.go @@ -25,7 +25,7 @@ type CommitVerification struct { SigningUser *user_model.User // if Verified, then SigningUser is non-nil CommittingUser *user_model.User // if Verified, then CommittingUser is non-nil SigningEmail string - SigningKey *GPGKey + SigningKey *GPGKey // FIXME: need to refactor it to a new name like "SigningGPGKey", it is also used in some templates SigningSSHKey *PublicKey TrustStatus string } diff --git a/models/asymkey/key_display.go b/models/asymkey/key_display.go new file mode 100644 index 00000000000..ee17553b5b4 --- /dev/null +++ b/models/asymkey/key_display.go @@ -0,0 +1,37 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package asymkey + +import ( + "os" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" +) + +func GetDisplaySigningKey(key *git.SigningKey) string { + if key == nil || key.Format == "" { + return "" + } + + switch key.Format { + case git.SigningKeyFormatOpenPGP: + return key.KeyID + case git.SigningKeyFormatSSH: + content, err := os.ReadFile(key.KeyID) + if err != nil { + log.Error("Unable to read SSH key %s: %v", key.KeyID, err) + return "(Unable to read SSH key)" + } + display, err := CalcFingerprint(string(content)) + if err != nil { + log.Error("Unable to calculate fingerprint for SSH key %s: %v", key.KeyID, err) + return "(Unable to calculate fingerprint for SSH key)" + } + return display + } + setting.PanicInDevOrTesting("Unknown signing key format: %s", key.Format) + return "(Unknown key format)" +} diff --git a/models/db/log.go b/models/db/log.go index a9df6f541db..4f563a4df04 100644 --- a/models/db/log.go +++ b/models/db/log.go @@ -67,7 +67,7 @@ func (l *XORMLogBridge) Warn(v ...any) { l.Log(stackLevel, log.WARN, "%s", fmt.Sprint(v...)) } -// Warnf show warnning log +// Warnf show warning log func (l *XORMLogBridge) Warnf(format string, v ...any) { l.Log(stackLevel, log.WARN, format, v...) } diff --git a/models/fixtures/user_redirect.yml b/models/fixtures/user_redirect.yml index 8ff79933983..c668cb6c3b7 100644 --- a/models/fixtures/user_redirect.yml +++ b/models/fixtures/user_redirect.yml @@ -2,3 +2,7 @@ id: 1 lower_name: olduser1 redirect_user_id: 1 +- + id: 2 + lower_name: olduser2 + redirect_user_id: 2 diff --git a/models/git/branch.go b/models/git/branch.go index 6021e1101f6..54351649cc5 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -334,122 +334,111 @@ func FindRenamedBranch(ctx context.Context, repoID int64, from string) (branch * // RenameBranch rename a branch func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to string, gitAction func(ctx context.Context, isDefault bool) error) (err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() + return db.WithTx(ctx, func(ctx context.Context) error { + sess := db.GetEngine(ctx) - sess := db.GetEngine(ctx) - - // check whether from branch exist - var branch Branch - exist, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, from).Get(&branch) - if err != nil { - return err - } else if !exist || branch.IsDeleted { - return ErrBranchNotExist{ - RepoID: repo.ID, - BranchName: from, - } - } - - // check whether to branch exist or is_deleted - var dstBranch Branch - exist, err = db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, to).Get(&dstBranch) - if err != nil { - return err - } - if exist { - if !dstBranch.IsDeleted { - return ErrBranchAlreadyExists{ - BranchName: to, + // check whether from branch exist + var branch Branch + exist, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, from).Get(&branch) + if err != nil { + return err + } else if !exist || branch.IsDeleted { + return ErrBranchNotExist{ + RepoID: repo.ID, + BranchName: from, } } - if _, err := db.GetEngine(ctx).ID(dstBranch.ID).NoAutoCondition().Delete(&dstBranch); err != nil { - return err - } - } - - // 1. update branch in database - if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Update(&Branch{ - Name: to, - }); err != nil { - return err - } else if n <= 0 { - return ErrBranchNotExist{ - RepoID: repo.ID, - BranchName: from, - } - } - - // 2. update default branch if needed - isDefault := repo.DefaultBranch == from - if isDefault { - repo.DefaultBranch = to - _, err = sess.ID(repo.ID).Cols("default_branch").Update(repo) + // check whether to branch exist or is_deleted + var dstBranch Branch + exist, err = db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, to).Get(&dstBranch) if err != nil { return err } - } + if exist { + if !dstBranch.IsDeleted { + return ErrBranchAlreadyExists{ + BranchName: to, + } + } - // 3. Update protected branch if needed - protectedBranch, err := GetProtectedBranchRuleByName(ctx, repo.ID, from) - if err != nil { - return err - } + if _, err := db.GetEngine(ctx).ID(dstBranch.ID).NoAutoCondition().Delete(&dstBranch); err != nil { + return err + } + } - if protectedBranch != nil { - // there is a protect rule for this branch - protectedBranch.RuleName = to - _, err = sess.ID(protectedBranch.ID).Cols("branch_name").Update(protectedBranch) + // 1. update branch in database + if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Update(&Branch{ + Name: to, + }); err != nil { + return err + } else if n <= 0 { + return ErrBranchNotExist{ + RepoID: repo.ID, + BranchName: from, + } + } + + // 2. update default branch if needed + isDefault := repo.DefaultBranch == from + if isDefault { + repo.DefaultBranch = to + _, err = sess.ID(repo.ID).Cols("default_branch").Update(repo) + if err != nil { + return err + } + } + + // 3. Update protected branch if needed + protectedBranch, err := GetProtectedBranchRuleByName(ctx, repo.ID, from) if err != nil { return err } - } else { - // some glob protect rules may match this branch - protected, err := IsBranchProtected(ctx, repo.ID, from) + + if protectedBranch != nil { + // there is a protect rule for this branch + protectedBranch.RuleName = to + if _, err = sess.ID(protectedBranch.ID).Cols("branch_name").Update(protectedBranch); err != nil { + return err + } + } else { + // some glob protect rules may match this branch + protected, err := IsBranchProtected(ctx, repo.ID, from) + if err != nil { + return err + } + if protected { + return ErrBranchIsProtected + } + } + + // 4. Update all not merged pull request base branch name + _, err = sess.Table("pull_request").Where("base_repo_id=? AND base_branch=? AND has_merged=?", + repo.ID, from, false). + Update(map[string]any{"base_branch": to}) if err != nil { return err } - if protected { - return ErrBranchIsProtected + + // 4.1 Update all not merged pull request head branch name + if _, err = sess.Table("pull_request").Where("head_repo_id=? AND head_branch=? AND has_merged=?", + repo.ID, from, false). + Update(map[string]any{"head_branch": to}); err != nil { + return err } - } - // 4. Update all not merged pull request base branch name - _, err = sess.Table("pull_request").Where("base_repo_id=? AND base_branch=? AND has_merged=?", - repo.ID, from, false). - Update(map[string]any{"base_branch": to}) - if err != nil { - return err - } + // 5. insert renamed branch record + if err = db.Insert(ctx, &RenamedBranch{ + RepoID: repo.ID, + From: from, + To: to, + }); err != nil { + return err + } - // 4.1 Update all not merged pull request head branch name - if _, err = sess.Table("pull_request").Where("head_repo_id=? AND head_branch=? AND has_merged=?", - repo.ID, from, false). - Update(map[string]any{"head_branch": to}); err != nil { - return err - } - - // 5. insert renamed branch record - renamedBranch := &RenamedBranch{ - RepoID: repo.ID, - From: from, - To: to, - } - err = db.Insert(ctx, renamedBranch) - if err != nil { - return err - } - - // 6. do git action - if err = gitAction(ctx, isDefault); err != nil { - return err - } - - return committer.Commit() + // 6. do git action + return gitAction(ctx, isDefault) + }) } type FindRecentlyPushedNewBranchesOptions struct { diff --git a/models/git/lfs.go b/models/git/lfs.go index c471baf5880..8bba060ff97 100644 --- a/models/git/lfs.go +++ b/models/git/lfs.go @@ -180,29 +180,25 @@ func RemoveLFSMetaObjectByOidFn(ctx context.Context, repoID int64, oid string, f return 0, ErrLFSObjectNotExist } - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return 0, err - } - defer committer.Close() + return db.WithTx2(ctx, func(ctx context.Context) (int64, error) { + m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID} + if _, err := db.DeleteByBean(ctx, m); err != nil { + return -1, err + } - m := &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}, RepositoryID: repoID} - if _, err := db.DeleteByBean(ctx, m); err != nil { - return -1, err - } - - count, err := db.CountByBean(ctx, &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}) - if err != nil { - return count, err - } - - if fn != nil { - if err := fn(count); err != nil { + count, err := db.CountByBean(ctx, &LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}) + if err != nil { return count, err } - } - return count, committer.Commit() + if fn != nil { + if err := fn(count); err != nil { + return count, err + } + } + + return count, nil + }) } // GetLFSMetaObjects returns all LFSMetaObjects associated with a repository @@ -243,56 +239,46 @@ func ExistsLFSObject(ctx context.Context, oid string) (bool, error) { // LFSAutoAssociate auto associates accessible LFSMetaObjects func LFSAutoAssociate(ctx context.Context, metas []*LFSMetaObject, user *user_model.User, repoID int64) error { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() + return db.WithTx(ctx, func(ctx context.Context) error { + oids := make([]any, len(metas)) + oidMap := make(map[string]*LFSMetaObject, len(metas)) + for i, meta := range metas { + oids[i] = meta.Oid + oidMap[meta.Oid] = meta + } - sess := db.GetEngine(ctx) + if !user.IsAdmin { + newMetas := make([]*LFSMetaObject, 0, len(metas)) + cond := builder.In( + "`lfs_meta_object`.repository_id", + builder.Select("`repository`.id").From("repository").Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), + ) + if err := db.GetEngine(ctx).Cols("oid").Where(cond).In("oid", oids...).GroupBy("oid").Find(&newMetas); err != nil { + return err + } + if len(newMetas) != len(oidMap) { + return fmt.Errorf("unable collect all LFS objects from database, expected %d, actually %d", len(oidMap), len(newMetas)) + } + for i := range newMetas { + newMetas[i].Size = oidMap[newMetas[i].Oid].Size + newMetas[i].RepositoryID = repoID + } + return db.Insert(ctx, newMetas) + } - oids := make([]any, len(metas)) - oidMap := make(map[string]*LFSMetaObject, len(metas)) - for i, meta := range metas { - oids[i] = meta.Oid - oidMap[meta.Oid] = meta - } - - if !user.IsAdmin { - newMetas := make([]*LFSMetaObject, 0, len(metas)) - cond := builder.In( - "`lfs_meta_object`.repository_id", - builder.Select("`repository`.id").From("repository").Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), - ) - err = sess.Cols("oid").Where(cond).In("oid", oids...).GroupBy("oid").Find(&newMetas) - if err != nil { - return err - } - if len(newMetas) != len(oidMap) { - return fmt.Errorf("unable collect all LFS objects from database, expected %d, actually %d", len(oidMap), len(newMetas)) - } - for i := range newMetas { - newMetas[i].Size = oidMap[newMetas[i].Oid].Size - newMetas[i].RepositoryID = repoID - } - if err = db.Insert(ctx, newMetas); err != nil { - return err - } - } else { // admin can associate any LFS object to any repository, and we do not care about errors (eg: duplicated unique key), // even if error occurs, it won't hurt users and won't make things worse for i := range metas { p := lfs.Pointer{Oid: metas[i].Oid, Size: metas[i].Size} - _, err = sess.Insert(&LFSMetaObject{ + if err := db.Insert(ctx, &LFSMetaObject{ Pointer: p, RepositoryID: repoID, - }) - if err != nil { + }); err != nil { log.Warn("failed to insert LFS meta object %-v for repo_id: %d into database, err=%v", p, repoID, err) } } - } - return committer.Commit() + return nil + }) } // CopyLFS copies LFS data from one repo to another diff --git a/models/git/protected_branch.go b/models/git/protected_branch.go index 55bbe6938cd..511f7563cf5 100644 --- a/models/git/protected_branch.go +++ b/models/git/protected_branch.go @@ -17,12 +17,11 @@ 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/glob" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" - "github.com/gobwas/glob" - "github.com/gobwas/glob/syntax" "xorm.io/builder" ) @@ -77,7 +76,7 @@ func init() { // IsRuleNameSpecial return true if it contains special character func IsRuleNameSpecial(ruleName string) bool { for i := 0; i < len(ruleName); i++ { - if syntax.Special(ruleName[i]) { + if glob.IsSpecialByte(ruleName[i]) { return true } } diff --git a/models/git/protected_branch_list.go b/models/git/protected_branch_list.go index 16f85006723..6b282835a46 100644 --- a/models/git/protected_branch_list.go +++ b/models/git/protected_branch_list.go @@ -8,9 +8,8 @@ import ( "sort" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/optional" - - "github.com/gobwas/glob" ) type ProtectedBranchRules []*ProtectedBranch diff --git a/models/git/protected_tag.go b/models/git/protected_tag.go index 9a6646c742c..95642df5932 100644 --- a/models/git/protected_tag.go +++ b/models/git/protected_tag.go @@ -11,9 +11,8 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/timeutil" - - "github.com/gobwas/glob" ) // ProtectedTag struct diff --git a/models/issues/assignees.go b/models/issues/assignees.go index efd992cda2b..54f995dd2e9 100644 --- a/models/issues/assignees.go +++ b/models/issues/assignees.go @@ -91,18 +91,10 @@ func GetAssignedIssues(ctx context.Context, opts *AssignedIssuesOptions) ([]*Iss // ToggleIssueAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it. func ToggleIssueAssignee(ctx context.Context, issue *Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *Comment, err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return false, nil, err - } - defer committer.Close() - - removed, comment, err = toggleIssueAssignee(ctx, issue, doer, assigneeID, false) - if err != nil { - return false, nil, err - } - - if err := committer.Commit(); err != nil { + if err := db.WithTx(ctx, func(ctx context.Context) error { + removed, comment, err = toggleIssueAssignee(ctx, issue, doer, assigneeID, false) + return err + }); err != nil { return false, nil, err } diff --git a/models/issues/comment.go b/models/issues/comment.go index a366b7c6a9c..3a4049700de 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -279,8 +279,8 @@ type Comment struct { DependentIssue *Issue `xorm:"-"` CommitID int64 - Line int64 // - previous line / + proposed line - TreePath string + Line int64 // - previous line / + proposed line + TreePath string `xorm:"VARCHAR(4000)"` // SQLServer only supports up to 4000 Content string `xorm:"LONGTEXT"` ContentVersion int `xorm:"NOT NULL DEFAULT 0"` RenderedContent template.HTML `xorm:"-"` diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go index 1c168174918..553e99aece2 100644 --- a/models/issues/issue_update.go +++ b/models/issues/issue_update.go @@ -415,37 +415,28 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue // NewIssue creates new issue with labels for repository. // The title will be cut off at 255 characters if it's longer than 255 characters. func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - - idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID) - if err != nil { - return fmt.Errorf("generate issue index failed: %w", err) - } - - issue.Index = idx - issue.Title = util.EllipsisDisplayString(issue.Title, 255) - - if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ - Repo: repo, - Issue: issue, - LabelIDs: labelIDs, - Attachments: uuids, - }); err != nil { - if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { - return err + return db.WithTx(ctx, func(ctx context.Context) error { + idx, err := db.GetNextResourceIndex(ctx, "issue_index", repo.ID) + if err != nil { + return fmt.Errorf("generate issue index failed: %w", err) } - return fmt.Errorf("newIssue: %w", err) - } - if err = committer.Commit(); err != nil { - return fmt.Errorf("Commit: %w", err) - } + issue.Index = idx + issue.Title = util.EllipsisDisplayString(issue.Title, 255) - return nil + if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ + Repo: repo, + Issue: issue, + LabelIDs: labelIDs, + Attachments: uuids, + }); err != nil { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { + return err + } + return fmt.Errorf("newIssue: %w", err) + } + return nil + }) } // UpdateIssueMentions updates issue-user relations for mentioned users. diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 88967a8b870..1b1558f39d1 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -393,6 +393,7 @@ func prepareMigrationTasks() []*migration { // Gitea 1.24.0 ends at database version 321 newMigration(321, "Use LONGTEXT for some columns and fix review_state.updated_files column", v1_25.UseLongTextInSomeColumnsAndFixBugs), + newMigration(322, "Extend comment tree_path length limit", v1_25.ExtendCommentTreePathLength), } return preparedMigrations } diff --git a/models/migrations/v1_11/v111.go b/models/migrations/v1_11/v111.go index c27465f0518..2634906565e 100644 --- a/models/migrations/v1_11/v111.go +++ b/models/migrations/v1_11/v111.go @@ -408,7 +408,7 @@ func AddBranchProtectionCanPushAndEnableWhitelist(x *xorm.Engine) error { official, err := isOfficialReviewer(sess, review.IssueID, reviewer) if err != nil { - // Branch might not be proteced or other error, ignore it. + // Branch might not be protected or other error, ignore it. continue } review.Official = official diff --git a/models/migrations/v1_12/v128.go b/models/migrations/v1_12/v128.go index d2e8b86a3d9..34746dcdc42 100644 --- a/models/migrations/v1_12/v128.go +++ b/models/migrations/v1_12/v128.go @@ -12,6 +12,7 @@ import ( "time" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -83,17 +84,17 @@ func FixMergeBase(ctx context.Context, x *xorm.Engine) error { if !pr.HasMerged { var err error - pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = gitcmd.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err != nil { var err2 error - pr.MergeBase, _, err2 = git.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err2 = gitcmd.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err2 != nil { log.Error("Unable to get merge base for PR ID %d, Index %d in %s/%s. Error: %v & %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err, err2) continue } } } else { - parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue @@ -105,9 +106,9 @@ func FixMergeBase(ctx context.Context, x *xorm.Engine) error { refs := append([]string{}, parents[1:]...) refs = append(refs, gitRefName) - cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) + cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...) - pr.MergeBase, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue diff --git a/models/migrations/v1_12/v134.go b/models/migrations/v1_12/v134.go index 189d80cc523..d31cc3abdb3 100644 --- a/models/migrations/v1_12/v134.go +++ b/models/migrations/v1_12/v134.go @@ -11,7 +11,7 @@ import ( "strings" "time" - "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -80,7 +80,7 @@ func RefixMergeBase(ctx context.Context, x *xorm.Engine) error { gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index) - parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue @@ -93,9 +93,9 @@ func RefixMergeBase(ctx context.Context, x *xorm.Engine) error { // we should recalculate refs := append([]string{}, parents[1:]...) refs = append(refs, gitRefName) - cmd := git.NewCommand("merge-base").AddDashesAndList(refs...) + cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...) - pr.MergeBase, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + pr.MergeBase, _, err = cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err != nil { log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err) continue diff --git a/models/migrations/v1_25/v322.go b/models/migrations/v1_25/v322.go new file mode 100644 index 00000000000..32dae9945ae --- /dev/null +++ b/models/migrations/v1_25/v322.go @@ -0,0 +1,28 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_25 + +import ( + "code.gitea.io/gitea/models/migrations/base" + + "xorm.io/xorm" + "xorm.io/xorm/schemas" +) + +func ExtendCommentTreePathLength(x *xorm.Engine) error { + dbType := x.Dialect().URI().DBType + if dbType == schemas.SQLITE { // For SQLITE, varchar or char will always be represented as TEXT + return nil + } + + return base.ModifyColumn(x, "comment", &schemas.Column{ + Name: "tree_path", + SQLType: schemas.SQLType{ + Name: "VARCHAR", + }, + Length: 4000, + Nullable: true, // To keep compatible as nullable + DefaultIsEmpty: true, + }) +} diff --git a/models/perm/access/repo_permission.go b/models/perm/access/repo_permission.go index 7de43ecd07c..678b18442ee 100644 --- a/models/perm/access/repo_permission.go +++ b/models/perm/access/repo_permission.go @@ -348,10 +348,8 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use for _, u := range repo.Units { for _, team := range teams { - unitAccessMode := minAccessMode - if teamMode, exist := team.UnitAccessModeEx(ctx, u.Type); exist { - unitAccessMode = max(perm.unitsMode[u.Type], unitAccessMode, teamMode) - } + teamMode, _ := team.UnitAccessModeEx(ctx, u.Type) + unitAccessMode := max(perm.unitsMode[u.Type], minAccessMode, teamMode) perm.unitsMode[u.Type] = unitAccessMode } } diff --git a/models/perm/access/repo_permission_test.go b/models/perm/access/repo_permission_test.go index c8675b1ded5..d81dfba288e 100644 --- a/models/perm/access/repo_permission_test.go +++ b/models/perm/access/repo_permission_test.go @@ -197,4 +197,37 @@ func TestGetUserRepoPermission(t *testing.T) { assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeCode]) assert.Equal(t, perm_model.AccessModeRead, perm.unitsMode[unit.TypeIssues]) }) + + repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // org private repo, same org as repo 32 + require.NoError(t, repo3.LoadOwner(ctx)) + require.True(t, repo3.Owner.IsOrganization()) + require.NoError(t, db.TruncateBeans(ctx, &organization.TeamUnit{}, &Access{})) // The user has access set of that repo, remove it, it is useless for our test + require.NoError(t, db.Insert(ctx, &organization.TeamRepo{OrgID: org.ID, TeamID: team.ID, RepoID: repo3.ID})) + t.Run("DoerWithNoopTeamOnPrivateRepo", func(t *testing.T) { + perm, err := GetUserRepoPermission(ctx, repo3, user) + require.NoError(t, err) + assert.Equal(t, perm_model.AccessModeNone, perm.AccessMode) + assert.Equal(t, perm_model.AccessModeNone, perm.unitsMode[unit.TypeCode]) + assert.Equal(t, perm_model.AccessModeNone, perm.unitsMode[unit.TypeIssues]) + }) + + require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeCode, AccessMode: perm_model.AccessModeNone})) + require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeIssues, AccessMode: perm_model.AccessModeRead})) + t.Run("DoerWithReadIssueTeamOnPrivateRepo", func(t *testing.T) { + perm, err := GetUserRepoPermission(ctx, repo3, user) + require.NoError(t, err) + assert.Equal(t, perm_model.AccessModeNone, perm.AccessMode) + assert.Equal(t, perm_model.AccessModeNone, perm.unitsMode[unit.TypeCode]) + assert.Equal(t, perm_model.AccessModeRead, perm.unitsMode[unit.TypeIssues]) + }) + + require.NoError(t, db.Insert(ctx, repo_model.Collaboration{RepoID: repo3.ID, UserID: user.ID, Mode: perm_model.AccessModeWrite})) + require.NoError(t, db.Insert(ctx, Access{RepoID: repo3.ID, UserID: user.ID, Mode: perm_model.AccessModeWrite})) + t.Run("DoerWithReadIssueTeamAndWriteCollaboratorOnPrivateRepo", func(t *testing.T) { + perm, err := GetUserRepoPermission(ctx, repo3, user) + require.NoError(t, err) + assert.Equal(t, perm_model.AccessModeWrite, perm.AccessMode) + assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeCode]) + assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeIssues]) + }) } diff --git a/models/user/email_address.go b/models/user/email_address.go index cb423945f8a..67aa1bdd822 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -442,58 +442,53 @@ func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmail // ActivateUserEmail will change the activated state of an email address, // either primary or secondary (all in the email_address table) func ActivateUserEmail(ctx context.Context, userID int64, email string, activate bool) (err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - - // Activate/deactivate a user's secondary email address - // First check if there's another user active with the same address - addr, exist, err := db.Get[EmailAddress](ctx, builder.Eq{"uid": userID, "lower_email": strings.ToLower(email)}) - if err != nil { - return err - } else if !exist { - return fmt.Errorf("no such email: %d (%s)", userID, email) - } - - if addr.IsActivated == activate { - // Already in the desired state; no action - return nil - } - if activate { - if used, err := IsEmailActive(ctx, email, addr.ID); err != nil { - return fmt.Errorf("unable to check isEmailActive() for %s: %w", email, err) - } else if used { - return ErrEmailAlreadyUsed{Email: email} - } - } - if err = updateActivation(ctx, addr, activate); err != nil { - return fmt.Errorf("unable to updateActivation() for %d:%s: %w", addr.ID, addr.Email, err) - } - - // Activate/deactivate a user's primary email address and account - if addr.IsPrimary { - user, exist, err := db.Get[User](ctx, builder.Eq{"id": userID}) + return db.WithTx(ctx, func(ctx context.Context) error { + // Activate/deactivate a user's secondary email address + // First check if there's another user active with the same address + addr, exist, err := db.Get[EmailAddress](ctx, builder.Eq{"uid": userID, "lower_email": strings.ToLower(email)}) if err != nil { return err - } else if !exist || !strings.EqualFold(user.Email, email) { - return fmt.Errorf("no user with ID: %d and Email: %s", userID, email) + } else if !exist { + return fmt.Errorf("no such email: %d (%s)", userID, email) } - // The user's activation state should be synchronized with the primary email - if user.IsActive != activate { - user.IsActive = activate - if user.Rands, err = GetUserSalt(); err != nil { - return fmt.Errorf("unable to generate salt: %w", err) - } - if err = UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { - return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err) + if addr.IsActivated == activate { + // Already in the desired state; no action + return nil + } + if activate { + if used, err := IsEmailActive(ctx, email, addr.ID); err != nil { + return fmt.Errorf("unable to check isEmailActive() for %s: %w", email, err) + } else if used { + return ErrEmailAlreadyUsed{Email: email} } } - } + if err = updateActivation(ctx, addr, activate); err != nil { + return fmt.Errorf("unable to updateActivation() for %d:%s: %w", addr.ID, addr.Email, err) + } - return committer.Commit() + // Activate/deactivate a user's primary email address and account + if addr.IsPrimary { + user, exist, err := db.Get[User](ctx, builder.Eq{"id": userID}) + if err != nil { + return err + } else if !exist || !strings.EqualFold(user.Email, email) { + return fmt.Errorf("no user with ID: %d and Email: %s", userID, email) + } + + // The user's activation state should be synchronized with the primary email + if user.IsActive != activate { + user.IsActive = activate + if user.Rands, err = GetUserSalt(); err != nil { + return fmt.Errorf("unable to generate salt: %w", err) + } + if err = UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { + return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err) + } + } + } + return nil + }) } // validateEmailBasic checks whether the email complies with the rules diff --git a/models/user/setting_options.go b/models/user/setting_options.go index 7be50393296..6d37ef63d55 100644 --- a/models/user/setting_options.go +++ b/models/user/setting_options.go @@ -8,7 +8,7 @@ const ( SettingsKeyHiddenCommentTypes = "issue.hidden_comment_types" // SettingsKeyDiffWhitespaceBehavior is the setting key for whitespace behavior of diff SettingsKeyDiffWhitespaceBehavior = "diff.whitespace_behaviour" - // SettingsKeyShowOutdatedComments is the setting key wether or not to show outdated comments in PRs + // SettingsKeyShowOutdatedComments is the setting key whether or not to show outdated comments in PRs SettingsKeyShowOutdatedComments = "comment_code.show_outdated" // UserActivityPubPrivPem is user's private key diff --git a/models/user/user.go b/models/user/user.go index ae500f3a1f2..6143992a253 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -716,90 +716,82 @@ func createUser(ctx context.Context, u *User, meta *Meta, createdByAdmin bool, o } } - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - - isExist, err := IsUserExist(ctx, 0, u.Name) - if err != nil { - return err - } else if isExist { - return ErrUserAlreadyExist{u.Name} - } - - isExist, err = IsEmailUsed(ctx, u.Email) - if err != nil { - return err - } else if isExist { - return ErrEmailAlreadyUsed{ - Email: u.Email, + return db.WithTx(ctx, func(ctx context.Context) error { + isExist, err := IsUserExist(ctx, 0, u.Name) + if err != nil { + return err + } else if isExist { + return ErrUserAlreadyExist{u.Name} } - } - // prepare for database + isExist, err = IsEmailUsed(ctx, u.Email) + if err != nil { + return err + } else if isExist { + return ErrEmailAlreadyUsed{ + Email: u.Email, + } + } - u.LowerName = strings.ToLower(u.Name) - u.AvatarEmail = u.Email - if u.Rands, err = GetUserSalt(); err != nil { - return err - } - if u.Passwd != "" { - if err = u.SetPassword(u.Passwd); err != nil { + // prepare for database + + u.LowerName = strings.ToLower(u.Name) + u.AvatarEmail = u.Email + if u.Rands, err = GetUserSalt(); err != nil { return err } - } else { - u.Salt = "" - u.PasswdHashAlgo = "" - } + if u.Passwd != "" { + if err = u.SetPassword(u.Passwd); err != nil { + return err + } + } else { + u.Salt = "" + u.PasswdHashAlgo = "" + } - // save changes to database + // save changes to database - if err = DeleteUserRedirect(ctx, u.Name); err != nil { - return err - } - - if u.CreatedUnix == 0 { - // Caller expects auto-time for creation & update timestamps. - err = db.Insert(ctx, u) - } else { - // Caller sets the timestamps themselves. They are responsible for ensuring - // both `CreatedUnix` and `UpdatedUnix` are set appropriately. - _, err = db.GetEngine(ctx).NoAutoTime().Insert(u) - } - if err != nil { - return err - } - - if setting.RecordUserSignupMetadata { - // insert initial IP and UserAgent - if err = SetUserSetting(ctx, u.ID, SignupIP, meta.InitialIP); err != nil { + if err = DeleteUserRedirect(ctx, u.Name); err != nil { return err } - // trim user agent string to a reasonable length, if necessary - userAgent := strings.TrimSpace(meta.InitialUserAgent) - if len(userAgent) > 255 { - userAgent = userAgent[:255] + if u.CreatedUnix == 0 { + // Caller expects auto-time for creation & update timestamps. + err = db.Insert(ctx, u) + } else { + // Caller sets the timestamps themselves. They are responsible for ensuring + // both `CreatedUnix` and `UpdatedUnix` are set appropriately. + _, err = db.GetEngine(ctx).NoAutoTime().Insert(u) } - if err = SetUserSetting(ctx, u.ID, SignupUserAgent, userAgent); err != nil { + if err != nil { return err } - } - // insert email address - if err := db.Insert(ctx, &EmailAddress{ - UID: u.ID, - Email: u.Email, - LowerEmail: strings.ToLower(u.Email), - IsActivated: u.IsActive, - IsPrimary: true, - }); err != nil { - return err - } + if setting.RecordUserSignupMetadata { + // insert initial IP and UserAgent + if err = SetUserSetting(ctx, u.ID, SignupIP, meta.InitialIP); err != nil { + return err + } - return committer.Commit() + // trim user agent string to a reasonable length, if necessary + userAgent := strings.TrimSpace(meta.InitialUserAgent) + if len(userAgent) > 255 { + userAgent = userAgent[:255] + } + if err = SetUserSetting(ctx, u.ID, SignupUserAgent, userAgent); err != nil { + return err + } + } + + // insert email address + return db.Insert(ctx, &EmailAddress{ + UID: u.ID, + Email: u.Email, + LowerEmail: strings.ToLower(u.Email), + IsActivated: u.IsActive, + IsPrimary: true, + }) + }) } // ErrDeleteLastAdminUser represents a "DeleteLastAdminUser" kind of error. diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 27bcafa6497..5fc530b63e5 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -10,11 +10,11 @@ import ( "strings" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/glob" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" webhook_module "code.gitea.io/gitea/modules/webhook" - "github.com/gobwas/glob" "github.com/nektos/act/pkg/jobparser" "github.com/nektos/act/pkg/model" "github.com/nektos/act/pkg/workflowpattern" diff --git a/modules/avatar/identicon/identicon.go b/modules/avatar/identicon/identicon.go index ee92416a536..19f87da85af 100644 --- a/modules/avatar/identicon/identicon.go +++ b/modules/avatar/identicon/identicon.go @@ -70,7 +70,7 @@ func (i *Identicon) render(c, b1, b2, b1Angle, b2Angle, foreColor int) image.Ima /* # Algorithm -Origin: An image is splitted into 9 areas +Origin: An image is split into 9 areas ``` ------------- diff --git a/modules/git/attribute/batch.go b/modules/git/attribute/batch.go index 4e31fda5753..9f805d55c51 100644 --- a/modules/git/attribute/batch.go +++ b/modules/git/attribute/batch.go @@ -12,6 +12,7 @@ import ( "time" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" ) @@ -23,7 +24,7 @@ type BatchChecker struct { stdOut *nulSeparatedAttributeWriter ctx context.Context cancel context.CancelFunc - cmd *git.Command + cmd *gitcmd.Command } // NewBatchChecker creates a check attribute reader for the current repository and provided commit ID @@ -76,7 +77,7 @@ func NewBatchChecker(repo *git.Repository, treeish string, attributes []string) _ = lw.Close() }() stdErr := new(bytes.Buffer) - err := cmd.Run(ctx, &git.RunOpts{ + err := cmd.Run(ctx, &gitcmd.RunOpts{ Env: envs, Dir: repo.Path, Stdin: stdinReader, diff --git a/modules/git/attribute/checker.go b/modules/git/attribute/checker.go index 167b31416e1..4b313adf377 100644 --- a/modules/git/attribute/checker.go +++ b/modules/git/attribute/checker.go @@ -11,12 +11,13 @@ import ( "os" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" ) -func checkAttrCommand(gitRepo *git.Repository, treeish string, filenames, attributes []string) (*git.Command, []string, func(), error) { +func checkAttrCommand(gitRepo *git.Repository, treeish string, filenames, attributes []string) (*gitcmd.Command, []string, func(), error) { cancel := func() {} envs := []string{"GIT_FLUSH=1"} - cmd := git.NewCommand("check-attr", "-z") + cmd := gitcmd.NewCommand("check-attr", "-z") if len(attributes) == 0 { cmd.AddArguments("--all") } @@ -70,7 +71,7 @@ func CheckAttributes(ctx context.Context, gitRepo *git.Repository, treeish strin stdOut := new(bytes.Buffer) stdErr := new(bytes.Buffer) - if err := cmd.Run(ctx, &git.RunOpts{ + if err := cmd.Run(ctx, &gitcmd.RunOpts{ Env: append(os.Environ(), envs...), Dir: gitRepo.Path, Stdout: stdOut, diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go index 7bbab76bb82..f09f4144c89 100644 --- a/modules/git/batch_reader.go +++ b/modules/git/batch_reader.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" "github.com/djherbis/buffer" @@ -29,13 +30,13 @@ type WriteCloserError interface { // This is needed otherwise the git cat-file will hang for invalid repositories. func ensureValidGitRepository(ctx context.Context, repoPath string) error { stderr := strings.Builder{} - err := NewCommand("rev-parse"). - Run(ctx, &RunOpts{ + err := gitcmd.NewCommand("rev-parse"). + Run(ctx, &gitcmd.RunOpts{ Dir: repoPath, Stderr: &stderr, }) if err != nil { - return ConcatenateError(err, (&stderr).String()) + return gitcmd.ConcatenateError(err, (&stderr).String()) } return nil } @@ -61,8 +62,8 @@ func catFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, go func() { stderr := strings.Builder{} - err := NewCommand("cat-file", "--batch-check"). - Run(ctx, &RunOpts{ + err := gitcmd.NewCommand("cat-file", "--batch-check"). + Run(ctx, &gitcmd.RunOpts{ Dir: repoPath, Stdin: batchStdinReader, Stdout: batchStdoutWriter, @@ -71,8 +72,8 @@ func catFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, UseContextTimeout: true, }) if err != nil { - _ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String())) - _ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String())) + _ = batchStdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String())) + _ = batchStdinReader.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String())) } else { _ = batchStdoutWriter.Close() _ = batchStdinReader.Close() @@ -109,8 +110,8 @@ func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi go func() { stderr := strings.Builder{} - err := NewCommand("cat-file", "--batch"). - Run(ctx, &RunOpts{ + err := gitcmd.NewCommand("cat-file", "--batch"). + Run(ctx, &gitcmd.RunOpts{ Dir: repoPath, Stdin: batchStdinReader, Stdout: batchStdoutWriter, @@ -119,8 +120,8 @@ func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi UseContextTimeout: true, }) if err != nil { - _ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String())) - _ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String())) + _ = batchStdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String())) + _ = batchStdinReader.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String())) } else { _ = batchStdoutWriter.Close() _ = batchStdinReader.Close() diff --git a/modules/git/blame.go b/modules/git/blame.go index db10df129e2..50cadc41c22 100644 --- a/modules/git/blame.go +++ b/modules/git/blame.go @@ -10,6 +10,7 @@ import ( "io" "os" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) @@ -141,7 +142,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath } }() - cmd := NewCommand("blame", "--porcelain") + cmd := gitcmd.NewCommand("blame", "--porcelain") if DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore { ignoreRevsFileName, ignoreRevsFileCleanup, err = tryCreateBlameIgnoreRevsFile(commit) @@ -165,7 +166,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath go func() { stderr := bytes.Buffer{} // TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close" - err := cmd.Run(ctx, &RunOpts{ + err := cmd.Run(ctx, &gitcmd.RunOpts{ UseContextTimeout: true, Dir: repoPath, Stdout: stdout, diff --git a/modules/git/commit.go b/modules/git/commit.go index 0dc894d3ab6..a0c5955ae8b 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -14,6 +14,7 @@ import ( "strconv" "strings" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" ) @@ -87,12 +88,12 @@ func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) { // AddChanges marks local changes to be ready for commit. func AddChanges(ctx context.Context, repoPath string, all bool, files ...string) error { - cmd := NewCommand().AddArguments("add") + cmd := gitcmd.NewCommand().AddArguments("add") if all { cmd.AddArguments("--all") } cmd.AddDashesAndList(files...) - _, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) + _, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) return err } @@ -106,7 +107,7 @@ type CommitChangesOptions struct { // CommitChanges commits local changes with given committer, author and message. // If author is nil, it will be the same as committer. func CommitChanges(ctx context.Context, repoPath string, opts CommitChangesOptions) error { - cmd := NewCommand() + cmd := gitcmd.NewCommand() if opts.Committer != nil { cmd.AddOptionValues("-c", "user.name="+opts.Committer.Name) cmd.AddOptionValues("-c", "user.email="+opts.Committer.Email) @@ -121,7 +122,7 @@ func CommitChanges(ctx context.Context, repoPath string, opts CommitChangesOptio } cmd.AddOptionFormat("--message=%s", opts.Message) - _, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) + _, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) // No stderr but exit status 1 means nothing to commit. if err != nil && err.Error() == "exit status 1" { return nil @@ -131,7 +132,7 @@ func CommitChanges(ctx context.Context, repoPath string, opts CommitChangesOptio // AllCommitsCount returns count of all commits in repository func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, files ...string) (int64, error) { - cmd := NewCommand("rev-list") + cmd := gitcmd.NewCommand("rev-list") if hidePRRefs { cmd.AddArguments("--exclude=" + PullPrefix + "*") } @@ -140,7 +141,7 @@ func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, file cmd.AddDashesAndList(files...) } - stdout, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) + stdout, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err != nil { return 0, err } @@ -160,7 +161,7 @@ type CommitsCountOptions struct { // CommitsCount returns number of total commits of until given revision. func CommitsCount(ctx context.Context, opts CommitsCountOptions) (int64, error) { - cmd := NewCommand("rev-list", "--count") + cmd := gitcmd.NewCommand("rev-list", "--count") cmd.AddDynamicArguments(opts.Revision...) @@ -172,7 +173,7 @@ func CommitsCount(ctx context.Context, opts CommitsCountOptions) (int64, error) cmd.AddDashesAndList(opts.RelPath...) } - stdout, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: opts.RepoPath}) + stdout, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: opts.RepoPath}) if err != nil { return 0, err } @@ -207,7 +208,7 @@ func (c *Commit) HasPreviousCommit(objectID ObjectID) (bool, error) { return false, nil } - _, _, err := NewCommand("merge-base", "--is-ancestor").AddDynamicArguments(that, this).RunStdString(c.repo.Ctx, &RunOpts{Dir: c.repo.Path}) + _, _, err := gitcmd.NewCommand("merge-base", "--is-ancestor").AddDynamicArguments(that, this).RunStdString(c.repo.Ctx, &gitcmd.RunOpts{Dir: c.repo.Path}) if err == nil { return true, nil } @@ -348,12 +349,12 @@ func (c *Commit) GetFileContent(filename string, limit int) (string, error) { // GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only') func (c *Commit) GetBranchName() (string, error) { - cmd := NewCommand("name-rev") + cmd := gitcmd.NewCommand("name-rev") if DefaultFeatures().CheckVersionAtLeast("2.13.0") { cmd.AddArguments("--exclude", "refs/tags/*") } cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String()) - data, _, err := cmd.RunStdString(c.repo.Ctx, &RunOpts{Dir: c.repo.Path}) + data, _, err := cmd.RunStdString(c.repo.Ctx, &gitcmd.RunOpts{Dir: c.repo.Path}) if err != nil { // handle special case where git can not describe commit if strings.Contains(err.Error(), "cannot describe") { @@ -431,14 +432,14 @@ func GetCommitFileStatus(ctx context.Context, repoPath, commitID string) (*Commi }() stderr := new(bytes.Buffer) - err := NewCommand("log", "--name-status", "-m", "--pretty=format:", "--first-parent", "--no-renames", "-z", "-1").AddDynamicArguments(commitID).Run(ctx, &RunOpts{ + err := gitcmd.NewCommand("log", "--name-status", "-m", "--pretty=format:", "--first-parent", "--no-renames", "-z", "-1").AddDynamicArguments(commitID).Run(ctx, &gitcmd.RunOpts{ Dir: repoPath, Stdout: w, Stderr: stderr, }) w.Close() // Close writer to exit parsing goroutine if err != nil { - return nil, ConcatenateError(err, stderr.String()) + return nil, gitcmd.ConcatenateError(err, stderr.String()) } <-done @@ -447,7 +448,7 @@ func GetCommitFileStatus(ctx context.Context, repoPath, commitID string) (*Commi // GetFullCommitID returns full length (40) of commit ID by given short SHA in a repository. func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, error) { - commitID, _, err := NewCommand("rev-parse").AddDynamicArguments(shortID).RunStdString(ctx, &RunOpts{Dir: repoPath}) + commitID, _, err := gitcmd.NewCommand("rev-parse").AddDynamicArguments(shortID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err != nil { if strings.Contains(err.Error(), "exit status 128") { return "", ErrNotExist{shortID, ""} diff --git a/modules/git/config.go b/modules/git/config.go index 3a717908b9b..2eafe971b39 100644 --- a/modules/git/config.go +++ b/modules/git/config.go @@ -11,13 +11,14 @@ import ( "runtime" "strings" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/setting" ) // syncGitConfig only modifies gitconfig, won't change global variables (otherwise there will be data-race problem) func syncGitConfig(ctx context.Context) (err error) { - if err = os.MkdirAll(HomeDir(), os.ModePerm); err != nil { - return fmt.Errorf("unable to prepare git home directory %s, err: %w", HomeDir(), err) + if err = os.MkdirAll(gitcmd.HomeDir(), os.ModePerm); err != nil { + return fmt.Errorf("unable to prepare git home directory %s, err: %w", gitcmd.HomeDir(), err) } // first, write user's git config options to git config file @@ -117,8 +118,8 @@ func syncGitConfig(ctx context.Context) (err error) { } func configSet(ctx context.Context, key, value string) error { - stdout, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) - if err != nil && !IsErrorExitCode(err, 1) { + stdout, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) + if err != nil && !gitcmd.IsErrorExitCode(err, 1) { return fmt.Errorf("failed to get git config %s, err: %w", key, err) } @@ -127,7 +128,7 @@ func configSet(ctx context.Context, key, value string) error { return nil } - _, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil) + _, _, err = gitcmd.NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil) if err != nil { return fmt.Errorf("failed to set git global config %s, err: %w", key, err) } @@ -136,14 +137,14 @@ func configSet(ctx context.Context, key, value string) error { } func configSetNonExist(ctx context.Context, key, value string) error { - _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) + _, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) if err == nil { // already exist return nil } - if IsErrorExitCode(err, 1) { + if gitcmd.IsErrorExitCode(err, 1) { // not exist, set new config - _, _, err = NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil) + _, _, err = gitcmd.NewCommand("config", "--global").AddDynamicArguments(key, value).RunStdString(ctx, nil) if err != nil { return fmt.Errorf("failed to set git global config %s, err: %w", key, err) } @@ -154,14 +155,14 @@ func configSetNonExist(ctx context.Context, key, value string) error { } func configAddNonExist(ctx context.Context, key, value string) error { - _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil) + _, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil) if err == nil { // already exist return nil } - if IsErrorExitCode(err, 1) { + if gitcmd.IsErrorExitCode(err, 1) { // not exist, add new config - _, _, err = NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(ctx, nil) + _, _, err = gitcmd.NewCommand("config", "--global", "--add").AddDynamicArguments(key, value).RunStdString(ctx, nil) if err != nil { return fmt.Errorf("failed to add git global config %s, err: %w", key, err) } @@ -171,16 +172,16 @@ func configAddNonExist(ctx context.Context, key, value string) error { } func configUnsetAll(ctx context.Context, key, value string) error { - _, _, err := NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) + _, _, err := gitcmd.NewCommand("config", "--global", "--get").AddDynamicArguments(key).RunStdString(ctx, nil) if err == nil { // exist, need to remove - _, _, err = NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil) + _, _, err = gitcmd.NewCommand("config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(ctx, nil) if err != nil { return fmt.Errorf("failed to unset git global config %s, err: %w", key, err) } return nil } - if IsErrorExitCode(err, 1) { + if gitcmd.IsErrorExitCode(err, 1) { // not exist return nil } diff --git a/modules/git/config_test.go b/modules/git/config_test.go index 911e0e01845..237feb67d54 100644 --- a/modules/git/config_test.go +++ b/modules/git/config_test.go @@ -8,13 +8,14 @@ import ( "strings" "testing" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/setting" "github.com/stretchr/testify/assert" ) func gitConfigContains(sub string) bool { - if b, err := os.ReadFile(HomeDir() + "/.gitconfig"); err == nil { + if b, err := os.ReadFile(gitcmd.HomeDir() + "/.gitconfig"); err == nil { return strings.Contains(string(b), sub) } return false diff --git a/modules/git/diff.go b/modules/git/diff.go index 35d115be0e5..d185cc92776 100644 --- a/modules/git/diff.go +++ b/modules/git/diff.go @@ -14,6 +14,7 @@ import ( "strconv" "strings" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" ) @@ -34,8 +35,8 @@ func GetRawDiff(repo *Repository, commitID string, diffType RawDiffType, writer // GetReverseRawDiff dumps the reverse diff results of repository in given commit ID to io.Writer. func GetReverseRawDiff(ctx context.Context, repoPath, commitID string, writer io.Writer) error { stderr := new(bytes.Buffer) - cmd := NewCommand("show", "--pretty=format:revert %H%n", "-R").AddDynamicArguments(commitID) - if err := cmd.Run(ctx, &RunOpts{ + cmd := gitcmd.NewCommand("show", "--pretty=format:revert %H%n", "-R").AddDynamicArguments(commitID) + if err := cmd.Run(ctx, &gitcmd.RunOpts{ Dir: repoPath, Stdout: writer, Stderr: stderr, @@ -56,7 +57,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff files = append(files, file) } - cmd := NewCommand() + cmd := gitcmd.NewCommand() switch diffType { case RawDiffNormal: if len(startCommit) != 0 { @@ -89,7 +90,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff } stderr := new(bytes.Buffer) - if err = cmd.Run(repo.Ctx, &RunOpts{ + if err = cmd.Run(repo.Ctx, &gitcmd.RunOpts{ Dir: repo.Path, Stdout: writer, Stderr: stderr, @@ -312,8 +313,8 @@ func GetAffectedFiles(repo *Repository, branchName, oldCommitID, newCommitID str affectedFiles := make([]string, 0, 32) // Run `git diff --name-only` to get the names of the changed files - err = NewCommand("diff", "--name-only").AddDynamicArguments(oldCommitID, newCommitID). - Run(repo.Ctx, &RunOpts{ + err = gitcmd.NewCommand("diff", "--name-only").AddDynamicArguments(oldCommitID, newCommitID). + Run(repo.Ctx, &gitcmd.RunOpts{ Env: env, Dir: repo.Path, Stdout: stdoutWriter, diff --git a/modules/git/git.go b/modules/git/git.go index 0a2e87a2eae..161fa42196a 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -9,12 +9,12 @@ import ( "errors" "fmt" "os" - "os/exec" "path/filepath" "runtime" "strings" "time" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -33,10 +33,7 @@ type Features struct { SupportCheckAttrOnBare bool // >= 2.40 } -var ( - GitExecutable = "git" // the command name of git, will be updated to an absolute path during initialization - defaultFeatures *Features -) +var defaultFeatures *Features func (f *Features) CheckVersionAtLeast(atLeast string) bool { return f.gitVersion.Compare(version.Must(version.NewVersion(atLeast))) >= 0 @@ -60,7 +57,7 @@ func DefaultFeatures() *Features { } func loadGitVersionFeatures() (*Features, error) { - stdout, _, runErr := NewCommand("version").RunStdString(context.Background(), nil) + stdout, _, runErr := gitcmd.NewCommand("version").RunStdString(context.Background(), nil) if runErr != nil { return nil, runErr } @@ -129,32 +126,6 @@ func ensureGitVersion() error { return nil } -// SetExecutablePath changes the path of git executable and checks the file permission and version. -func SetExecutablePath(path string) error { - // If path is empty, we use the default value of GitExecutable "git" to search for the location of git. - if path != "" { - GitExecutable = path - } - absPath, err := exec.LookPath(GitExecutable) - if err != nil { - return fmt.Errorf("git not found: %w", err) - } - GitExecutable = absPath - return nil -} - -// HomeDir is the home dir for git to store the global config file used by Gitea internally -func HomeDir() string { - if setting.Git.HomePath == "" { - // strict check, make sure the git module is initialized correctly. - // attention: when the git module is called in gitea sub-command (serv/hook), the log module might not obviously show messages to users/developers. - // for example: if there is gitea git hook code calling git.NewCommand before git.InitXxx, the integration test won't show the real failure reasons. - log.Fatal("Unable to init Git's HomeDir, incorrect initialization of the setting and git modules") - return "" - } - return setting.Git.HomePath -} - // InitSimple initializes git module with a very simple step, no config changes, no global command arguments. // This method doesn't change anything to filesystem. At the moment, it is only used by some Gitea sub-commands. func InitSimple() error { @@ -167,10 +138,10 @@ func InitSimple() error { } if setting.Git.Timeout.Default > 0 { - defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second + gitcmd.SetDefaultCommandExecutionTimeout(time.Duration(setting.Git.Timeout.Default) * time.Second) } - if err := SetExecutablePath(setting.Git.Path); err != nil { + if err := gitcmd.SetExecutablePath(setting.Git.Path); err != nil { return err } @@ -185,7 +156,7 @@ func InitSimple() error { // when git works with gnupg (commit signing), there should be a stable home for gnupg commands if _, ok := os.LookupEnv("GNUPGHOME"); !ok { - _ = os.Setenv("GNUPGHOME", filepath.Join(HomeDir(), ".gnupg")) + _ = os.Setenv("GNUPGHOME", filepath.Join(gitcmd.HomeDir(), ".gnupg")) } return nil } diff --git a/modules/git/command.go b/modules/git/gitcmd/command.go similarity index 99% rename from modules/git/command.go rename to modules/git/gitcmd/command.go index eeb987feb0b..ed2f6fb647e 100644 --- a/modules/git/command.go +++ b/modules/git/gitcmd/command.go @@ -2,7 +2,7 @@ // Copyright 2016 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package git +package gitcmd import ( "bytes" @@ -32,6 +32,10 @@ type TrustedCmdArgs []internal.CmdArg // defaultCommandExecutionTimeout default command execution timeout duration var defaultCommandExecutionTimeout = 360 * time.Second +func SetDefaultCommandExecutionTimeout(timeout time.Duration) { + defaultCommandExecutionTimeout = timeout +} + // DefaultLocale is the default LC_ALL to run git commands in. const DefaultLocale = "C" diff --git a/modules/git/command_race_test.go b/modules/git/gitcmd/command_race_test.go similarity index 98% rename from modules/git/command_race_test.go rename to modules/git/gitcmd/command_race_test.go index a6aa3a1580a..aee2272808b 100644 --- a/modules/git/command_race_test.go +++ b/modules/git/gitcmd/command_race_test.go @@ -3,7 +3,7 @@ //go:build race -package git +package gitcmd import ( "context" diff --git a/modules/git/command_test.go b/modules/git/gitcmd/command_test.go similarity index 83% rename from modules/git/command_test.go rename to modules/git/gitcmd/command_test.go index 85976e289ef..544a97f64c1 100644 --- a/modules/git/command_test.go +++ b/modules/git/gitcmd/command_test.go @@ -1,14 +1,30 @@ // Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package git +package gitcmd import ( + "fmt" + "os" "testing" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/tempdir" + "github.com/stretchr/testify/assert" ) +func TestMain(m *testing.M) { + gitHomePath, cleanup, err := tempdir.OsTempDir("gitea-test").MkdirTempRandom("git-home") + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "unable to create temp dir: %v", err) + os.Exit(1) + } + defer cleanup() + + setting.Git.HomePath = gitHomePath +} + func TestRunWithContextStd(t *testing.T) { cmd := NewCommand("--version") stdout, stderr, err := cmd.RunStdString(t.Context(), &RunOpts{}) diff --git a/modules/git/gitcmd/env.go b/modules/git/gitcmd/env.go new file mode 100644 index 00000000000..269b51a253a --- /dev/null +++ b/modules/git/gitcmd/env.go @@ -0,0 +1,40 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitcmd + +import ( + "fmt" + "os/exec" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" +) + +var GitExecutable = "git" // the command name of git, will be updated to an absolute path during initialization + +// SetExecutablePath changes the path of git executable and checks the file permission and version. +func SetExecutablePath(path string) error { + // If path is empty, we use the default value of GitExecutable "git" to search for the location of git. + if path != "" { + GitExecutable = path + } + absPath, err := exec.LookPath(GitExecutable) + if err != nil { + return fmt.Errorf("git not found: %w", err) + } + GitExecutable = absPath + return nil +} + +// HomeDir is the home dir for git to store the global config file used by Gitea internally +func HomeDir() string { + if setting.Git.HomePath == "" { + // strict check, make sure the git module is initialized correctly. + // attention: when the git module is called in gitea sub-command (serv/hook), the log module might not obviously show messages to users/developers. + // for example: if there is gitea git hook code calling NewCommand before git.InitXxx, the integration test won't show the real failure reasons. + log.Fatal("Unable to init Git's HomeDir, incorrect initialization of the setting and git modules") + return "" + } + return setting.Git.HomePath +} diff --git a/modules/git/gitcmd/utils.go b/modules/git/gitcmd/utils.go new file mode 100644 index 00000000000..ee24eb6a9a1 --- /dev/null +++ b/modules/git/gitcmd/utils.go @@ -0,0 +1,14 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitcmd + +import "fmt" + +// ConcatenateError concatenats an error with stderr string +func ConcatenateError(err error, stderr string) error { + if len(stderr) == 0 { + return err + } + return fmt.Errorf("%w - %s", err, stderr) +} diff --git a/modules/git/grep.go b/modules/git/grep.go index 66711650c96..f5f6f120416 100644 --- a/modules/git/grep.go +++ b/modules/git/grep.go @@ -14,6 +14,7 @@ import ( "strconv" "strings" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/util" ) @@ -60,7 +61,7 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO 2^@repo: go-gitea/gitea */ var results []*GrepResult - cmd := NewCommand("grep", "--null", "--break", "--heading", "--line-number", "--full-name") + cmd := gitcmd.NewCommand("grep", "--null", "--break", "--heading", "--line-number", "--full-name") cmd.AddOptionValues("--context", strconv.Itoa(opts.ContextLineNumber)) switch opts.GrepMode { case GrepModeExact: @@ -83,7 +84,7 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO cmd.AddDashesAndList(opts.PathspecList...) opts.MaxResultLimit = util.IfZero(opts.MaxResultLimit, 50) stderr := bytes.Buffer{} - err = cmd.Run(ctx, &RunOpts{ + err = cmd.Run(ctx, &gitcmd.RunOpts{ Dir: repo.Path, Stdout: stdoutWriter, Stderr: &stderr, @@ -135,11 +136,11 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO }, }) // git grep exits by cancel (killed), usually it is caused by the limit of results - if IsErrorExitCode(err, -1) && stderr.Len() == 0 { + if gitcmd.IsErrorExitCode(err, -1) && stderr.Len() == 0 { return results, nil } // git grep exits with 1 if no results are found - if IsErrorExitCode(err, 1) && stderr.Len() == 0 { + if gitcmd.IsErrorExitCode(err, 1) && stderr.Len() == 0 { return nil, nil } if err != nil && !errors.Is(err, context.Canceled) { diff --git a/modules/git/key.go b/modules/git/key.go index 2513c048b7c..8c14742f34a 100644 --- a/modules/git/key.go +++ b/modules/git/key.go @@ -3,13 +3,24 @@ package git +import "code.gitea.io/gitea/modules/setting" + // Based on https://git-scm.com/docs/git-config#Documentation/git-config.txt-gpgformat const ( SigningKeyFormatOpenPGP = "openpgp" // for GPG keys, the expected default of git cli SigningKeyFormatSSH = "ssh" ) +// SigningKey represents an instance key info which will be used to sign git commits. +// FIXME: need to refactor it to a new name, this name conflicts with the variable names for "asymkey.GPGKey" in many places. type SigningKey struct { KeyID string Format string } + +func (s *SigningKey) String() string { + // Do not expose KeyID + // In case the key is a file path and the struct is rendered in a template, then the server path will be exposed. + setting.PanicInDevOrTesting("don't call SigningKey.String() - it exposes the KeyID which might be a local file path") + return "SigningKey:" + s.Format +} diff --git a/modules/git/log_name_status.go b/modules/git/log_name_status.go index dfdef38ef9d..7a5192f58b7 100644 --- a/modules/git/log_name_status.go +++ b/modules/git/log_name_status.go @@ -14,6 +14,7 @@ import ( "strings" "code.gitea.io/gitea/modules/container" + "code.gitea.io/gitea/modules/git/gitcmd" "github.com/djherbis/buffer" "github.com/djherbis/nio/v3" @@ -34,7 +35,7 @@ func LogNameStatusRepo(ctx context.Context, repository, head, treepath string, p _ = stdoutWriter.Close() } - cmd := NewCommand() + cmd := gitcmd.NewCommand() cmd.AddArguments("log", "--name-status", "-c", "--format=commit%x00%H %P%x00", "--parents", "--no-renames", "-t", "-z").AddDynamicArguments(head) var files []string @@ -64,13 +65,13 @@ func LogNameStatusRepo(ctx context.Context, repository, head, treepath string, p go func() { stderr := strings.Builder{} - err := cmd.Run(ctx, &RunOpts{ + err := cmd.Run(ctx, &gitcmd.RunOpts{ Dir: repository, Stdout: stdoutWriter, Stderr: &stderr, }) if err != nil { - _ = stdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String())) + _ = stdoutWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String())) return } diff --git a/modules/git/pipeline/catfile.go b/modules/git/pipeline/catfile.go index 5ddc36cc01c..ced8532e6d9 100644 --- a/modules/git/pipeline/catfile.go +++ b/modules/git/pipeline/catfile.go @@ -13,7 +13,7 @@ import ( "strings" "sync" - "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" ) @@ -25,8 +25,8 @@ func CatFileBatchCheck(ctx context.Context, shasToCheckReader *io.PipeReader, ca stderr := new(bytes.Buffer) var errbuf strings.Builder - cmd := git.NewCommand("cat-file", "--batch-check") - if err := cmd.Run(ctx, &git.RunOpts{ + cmd := gitcmd.NewCommand("cat-file", "--batch-check") + if err := cmd.Run(ctx, &gitcmd.RunOpts{ Dir: tmpBasePath, Stdin: shasToCheckReader, Stdout: catFileCheckWriter, @@ -43,8 +43,8 @@ func CatFileBatchCheckAllObjects(ctx context.Context, catFileCheckWriter *io.Pip stderr := new(bytes.Buffer) var errbuf strings.Builder - cmd := git.NewCommand("cat-file", "--batch-check", "--batch-all-objects") - if err := cmd.Run(ctx, &git.RunOpts{ + cmd := gitcmd.NewCommand("cat-file", "--batch-check", "--batch-all-objects") + if err := cmd.Run(ctx, &gitcmd.RunOpts{ Dir: tmpBasePath, Stdout: catFileCheckWriter, Stderr: stderr, @@ -64,7 +64,7 @@ func CatFileBatch(ctx context.Context, shasToBatchReader *io.PipeReader, catFile stderr := new(bytes.Buffer) var errbuf strings.Builder - if err := git.NewCommand("cat-file", "--batch").Run(ctx, &git.RunOpts{ + if err := gitcmd.NewCommand("cat-file", "--batch").Run(ctx, &gitcmd.RunOpts{ Dir: tmpBasePath, Stdout: catFileBatchWriter, Stdin: shasToBatchReader, diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs_nogogit.go index c5eed737011..d2f147854d9 100644 --- a/modules/git/pipeline/lfs_nogogit.go +++ b/modules/git/pipeline/lfs_nogogit.go @@ -14,6 +14,7 @@ import ( "sync" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" ) // FindLFSFile finds commits that contain a provided pointer file hash @@ -32,13 +33,13 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err go func() { stderr := strings.Builder{} - err := git.NewCommand("rev-list", "--all").Run(repo.Ctx, &git.RunOpts{ + err := gitcmd.NewCommand("rev-list", "--all").Run(repo.Ctx, &gitcmd.RunOpts{ Dir: repo.Path, Stdout: revListWriter, Stderr: &stderr, }) if err != nil { - _ = revListWriter.CloseWithError(git.ConcatenateError(err, (&stderr).String())) + _ = revListWriter.CloseWithError(gitcmd.ConcatenateError(err, (&stderr).String())) } else { _ = revListWriter.Close() } diff --git a/modules/git/pipeline/namerev.go b/modules/git/pipeline/namerev.go index 06731c50519..0081f7a26db 100644 --- a/modules/git/pipeline/namerev.go +++ b/modules/git/pipeline/namerev.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" ) // NameRevStdin runs name-rev --stdin @@ -22,7 +22,7 @@ func NameRevStdin(ctx context.Context, shasToNameReader *io.PipeReader, nameRevS stderr := new(bytes.Buffer) var errbuf strings.Builder - if err := git.NewCommand("name-rev", "--stdin", "--name-only", "--always").Run(ctx, &git.RunOpts{ + if err := gitcmd.NewCommand("name-rev", "--stdin", "--name-only", "--always").Run(ctx, &gitcmd.RunOpts{ Dir: tmpBasePath, Stdout: nameRevStdinWriter, Stdin: shasToNameReader, diff --git a/modules/git/pipeline/revlist.go b/modules/git/pipeline/revlist.go index 31627a0f3a7..9d4ff754341 100644 --- a/modules/git/pipeline/revlist.go +++ b/modules/git/pipeline/revlist.go @@ -12,7 +12,7 @@ import ( "strings" "sync" - "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/log" ) @@ -23,8 +23,8 @@ func RevListAllObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sy stderr := new(bytes.Buffer) var errbuf strings.Builder - cmd := git.NewCommand("rev-list", "--objects", "--all") - if err := cmd.Run(ctx, &git.RunOpts{ + cmd := gitcmd.NewCommand("rev-list", "--objects", "--all") + if err := cmd.Run(ctx, &gitcmd.RunOpts{ Dir: basePath, Stdout: revListWriter, Stderr: stderr, @@ -42,11 +42,11 @@ func RevListObjects(ctx context.Context, revListWriter *io.PipeWriter, wg *sync. defer revListWriter.Close() stderr := new(bytes.Buffer) var errbuf strings.Builder - cmd := git.NewCommand("rev-list", "--objects").AddDynamicArguments(headSHA) + cmd := gitcmd.NewCommand("rev-list", "--objects").AddDynamicArguments(headSHA) if baseSHA != "" { cmd = cmd.AddArguments("--not").AddDynamicArguments(baseSHA) } - if err := cmd.Run(ctx, &git.RunOpts{ + if err := cmd.Run(ctx, &gitcmd.RunOpts{ Dir: tmpBasePath, Stdout: revListWriter, Stderr: stderr, diff --git a/modules/git/remote.go b/modules/git/remote.go index 283d26484bb..9f12142f916 100644 --- a/modules/git/remote.go +++ b/modules/git/remote.go @@ -9,19 +9,20 @@ import ( "net/url" "strings" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/util" ) // GetRemoteAddress returns remote url of git repository in the repoPath with special remote name func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string, error) { - var cmd *Command + var cmd *gitcmd.Command if DefaultFeatures().CheckVersionAtLeast("2.7") { - cmd = NewCommand("remote", "get-url").AddDynamicArguments(remoteName) + cmd = gitcmd.NewCommand("remote", "get-url").AddDynamicArguments(remoteName) } else { - cmd = NewCommand("config", "--get").AddDynamicArguments("remote." + remoteName + ".url") + cmd = gitcmd.NewCommand("config", "--get").AddDynamicArguments("remote." + remoteName + ".url") } - result, _, err := cmd.RunStdString(ctx, &RunOpts{Dir: repoPath}) + result, _, err := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}) if err != nil { return "", err } diff --git a/modules/git/repo.go b/modules/git/repo.go index 8e7b427bd0e..38cb4592a04 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -17,6 +17,7 @@ import ( "strings" "time" + "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/setting" ) @@ -40,9 +41,9 @@ func (repo *Repository) GetAllCommitsCount() (int64, error) { func (repo *Repository) ShowPrettyFormatLogToList(ctx context.Context, revisionRange string) ([]*Commit, error) { // avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'gitPackage.swift souboru:
swift.install2=a spustit následující příkaz:
vagrant.install=Pro přidání Vagrant box spusťte následující příkaz:
settings.link=Propojit tento balíček s repozitářem
-settings.link.description=Pokud propojíte balíček s repozitářem, je tento balíček uveden v seznamu balíčků repozitáře.
settings.link.select=Vybrat repozitář
settings.link.button=Aktualizovat odkaz na repozitář
settings.link.success=Odkaz na repozitář byl úspěšně aktualizován.
diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini
index 8c0731edd9b..dae7275f82e 100644
--- a/options/locale/locale_de-DE.ini
+++ b/options/locale/locale_de-DE.ini
@@ -3475,7 +3475,6 @@ swift.install=Füge das Paket deiner Package.swift Datei hinzu:
swift.install2=und führe den folgenden Befehl aus:
vagrant.install=Um eine Vagrant-Box hinzuzufügen, führe den folgenden Befehl aus:
settings.link=Dieses Paket einem Repository zuweisen
-settings.link.description=Wenn du ein Paket mit einem Repository verknüpfst, wird es in der Paketliste des Repositories angezeigt.
settings.link.select=Repository auswählen
settings.link.button=Repository-Link aktualisieren
settings.link.success=Repository-Link wurde erfolgreich aktualisiert.
diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini
index 60876b1ab00..42b23dea058 100644
--- a/options/locale/locale_el-GR.ini
+++ b/options/locale/locale_el-GR.ini
@@ -3133,7 +3133,6 @@ swift.install=Προσθέστε το πακέτο στο αρχείο Pac
swift.install2=και εκτελέστε την ακόλουθη εντολή:
vagrant.install=Για προσθήκη ενός κυτίου Vagrant, εκτελέστε την ακόλουθη εντολή:
settings.link=Σύνδεση αυτού του πακέτου με ένα αποθετήριο
-settings.link.description=Εάν συνδέσετε ένα πακέτο με ένα αποθετήριο, το πακέτο περιλαμβάνεται στη λίστα πακέτων του αποθετηρίου.
settings.link.select=Επιλογή Αποθετηρίου
settings.link.button=Ενημέρωση Συνδέσμου Αποθετηρίου
settings.link.success=Ο σύνδεσμος αποθετηρίου ενημερώθηκε επιτυχώς.
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index a974b172256..b3eb7b1f4a4 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -3729,11 +3729,14 @@ swift.install = Add the package in your Package.swift file:
swift.install2 = and run the following command:
vagrant.install = To add a Vagrant box, run the following command:
settings.link = Link this package to a repository
-settings.link.description = If you link a package with a repository, the package is listed in the repository's package list.
+settings.link.description = If you link a package with a repository, the package will appear in the repository's package list. Only repositories under the same owner can be linked. Leaving the field empty will remove the link.
settings.link.select = Select Repository
settings.link.button = Update Repository Link
settings.link.success = Repository link was successfully updated.
settings.link.error = Failed to update repository link.
+settings.link.repo_not_found = Repository %s not found.
+settings.unlink.error = Failed to remove repository link.
+settings.unlink.success = Repository link was successfully removed.
settings.delete = Delete package
settings.delete.description = Deleting a package is permanent and cannot be undone.
settings.delete.notice = You are about to delete %s (%s). This operation is irreversible, are you sure?
diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini
index 882a06330af..ffacb46b199 100644
--- a/options/locale/locale_es-ES.ini
+++ b/options/locale/locale_es-ES.ini
@@ -3113,7 +3113,6 @@ swift.install=Añade el paquete en tu archivo Package.swift:
swift.install2=y ejecuta el siguiente comando:
vagrant.install=Para añadir un paquete Vagrant, ejecuta el siguiente comando:
settings.link=Vincular este paquete a un repositorio
-settings.link.description=Si enlaza un paquete con un repositorio, el paquete se enumera en la lista de paquetes del repositorio.
settings.link.select=Seleccionar repositorio
settings.link.button=Actualizar enlace de repositorio
settings.link.success=El enlace del repositorio se ha actualizado correctamente.
diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini
index f75976bc4f0..5814de64ca8 100644
--- a/options/locale/locale_fr-FR.ini
+++ b/options/locale/locale_fr-FR.ini
@@ -120,6 +120,7 @@ error404=La page que vous essayez d'atteindre n'existe pas ou <
error503=Le serveur n’a pas pu répondre à votre demande. Veuillez réessayer plus tard.
go_back=Retour
invalid_data=Données invalides : %v
+nothing_has_been_changed=Rien n’a été changé.
never=Jamais
unknown=Inconnu
@@ -550,6 +551,13 @@ repo.transfer.body=Pour l’accepter ou le rejeter, visitez %s ou ignorez-le.
repo.collaborator.added.subject=%s vous a ajouté à %s
repo.collaborator.added.text=Vous avez été ajouté en tant que collaborateur du dépôt :
+repo.actions.run.failed=L’exécution a échoué
+repo.actions.run.succeeded=L’exécution a réussi
+repo.actions.run.cancelled=L’exécution a été annulée
+repo.actions.jobs.all_succeeded=Tous les tâches ont réussi.
+repo.actions.jobs.all_failed=Toutes les tâches ont échoué.
+repo.actions.jobs.some_not_successful=Certaines tâches n’ont pas réussi.
+repo.actions.jobs.all_cancelled=Toutes les tâches ont bien été annulés.
team_invite.subject=%[1]s vous a invité à rejoindre l’organisation %[2]s
team_invite.text_1=%[1]s vous a invité à rejoindre l’équipe %[2]s dans l’organisation %[3]s.
@@ -2844,6 +2852,11 @@ settings.location=Localisation
settings.permission=Autorisations
settings.repoadminchangeteam=L'administrateur de dépôt peut ajouter et supprimer l'accès aux équipes
settings.visibility=Visibilité
+settings.change_visibility=Modifier la visibilité
+settings.change_visibility_notices_1=Si l’organisation est convertie en privé, les étoiles du dépôt seront supprimées et ne pourront pas être restaurées.
+settings.change_visibility_notices_2=Les non-membres ne pourront plus accéder aux dépôts de l’organisation si la visibilité devient privée.
+settings.change_visibility_success=La visibilité de l’organisation %s a été modifiée.
+settings.visibility_desc=Changez qui peut voir l’organisation et ses dépôts.
settings.visibility.public=Public
settings.visibility.limited=Limité (Visible uniquement aux utilisateurs authentifiés)
settings.visibility.limited_shortname=Limité
@@ -3420,6 +3433,7 @@ config.picture_service=Service d'Imagerie
config.disable_gravatar=Désactiver Gravatar
config.enable_federated_avatar=Activer les avatars unifiés
config.open_with_editor_app_help=Les éditeurs disponibles via « Ouvrir avec ». Si laissé vide, la valeur par défaut sera utilisée. Développez pour voir la valeur par défaut.
+config.git_guide_remote_name=Nom du dépôt distant pour les commandes git dans le guide
config.git_config=Configuration de Git
config.git_disable_diff_highlight=Désactiver la surbrillance syntaxique de Diff
@@ -3715,7 +3729,6 @@ swift.install=Ajoutez le paquet dans votre fichier Package.swift:
swift.install2=et exécutez la commande suivante :
vagrant.install=Pour ajouter une machine Vagrant, exécutez la commande suivante :
settings.link=Lier ce paquet à un dépôt
-settings.link.description=Si vous liez un paquet à dépôt, le paquet sera inclus dans sa liste des paquets.
settings.link.select=Sélectionner un dépôt
settings.link.button=Actualiser le lien du dépôt
settings.link.success=Le lien du dépôt a été mis à jour avec succès.
diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini
index ae8068ea10e..b5b05209e5a 100644
--- a/options/locale/locale_ga-IE.ini
+++ b/options/locale/locale_ga-IE.ini
@@ -3729,11 +3729,14 @@ swift.install=Cuir an pacáiste i do chomhad Package.swift:
swift.install2=agus reáchtáil an t-ordú seo a leanas:
vagrant.install=Chun bosca Vagrant a chur leis, reáchtáil an t-ordú seo a leanas:
settings.link=Nasc an pacáiste seo le stóras
-settings.link.description=Má nascann tú pacáiste le stóras, liostaítear an pacáiste i liosta pacáistí an stórais.
+settings.link.description=Má nascann tú pacáiste le stórlann, beidh an pacáiste le feiceáil i liosta pacáistí an stórlainne. Ní féidir ach stórlanna faoin úinéir céanna a nascadh. Má fhágtar an réimse folamh, bainfear an nasc.
settings.link.select=Roghnaigh Stóras
settings.link.button=Nuashonraigh Nasc Stórais
settings.link.success=D'éirigh le nasc an stórais a nuashonrú.
settings.link.error=Theip ar an nasc stóras a nuashonrú.
+settings.link.repo_not_found=Níor aimsíodh an stóras %s.
+settings.unlink.error=Theip ar nasc an stórais a bhaint.
+settings.unlink.success=Baineadh an nasc chuig an stóras go rathúil.
settings.delete=Scrios pacáiste
settings.delete.description=Tá pacáiste a scriosadh buan agus ní féidir é a chur ar ais.
settings.delete.notice=Tá tú ar tí %s (%s) a scriosadh. Tá an oibríocht seo dochúlaithe, an bhfuil tú cinnte?
diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini
index 2519688d086..31aebff2d61 100644
--- a/options/locale/locale_it-IT.ini
+++ b/options/locale/locale_it-IT.ini
@@ -2667,7 +2667,6 @@ rubygems.dependencies.development=Dipendenze Di Sviluppo
rubygems.required.ruby=Richiede la versione di Ruby
rubygems.required.rubygems=Richiede la versione RubyGem
settings.link=Collega questo pacchetto a un repository
-settings.link.description=Se si collega un pacchetto a un repository, il pacchetto è elencato nell'elenco dei pacchetti del repository.
settings.link.select=Seleziona Repository
settings.link.button=Aggiorna Collegamento Repository
settings.link.success=Il link del repository è stato aggiornato correttamente.
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index 14a4825c40c..3b3083d8c68 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -3722,7 +3722,6 @@ swift.install=あなたの Package.swift ファイルにパッケ
swift.install2=そして次のコマンドを実行します:
vagrant.install=Vagrant ボックスを追加するには、次のコマンドを実行します。
settings.link=このパッケージをリポジトリにリンク
-settings.link.description=パッケージをリポジトリにリンクすると、リポジトリのパッケージリストに表示されるようになります。
settings.link.select=リポジトリを選択
settings.link.button=リポジトリのリンクを更新
settings.link.success=リポジトリのリンクが正常に更新されました。
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 0ec540104f1..9c8f47534bf 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -3134,7 +3134,6 @@ swift.install=Pievienojiet pakotni savā Package.swift failā:
swift.install2=un izpildiet sekojošu komandu:
vagrant.install=Lai pievienotu Vagrant kasti, izpildiet sekojošu komandu:
settings.link=Piesaistīt pakotni šim repozitorijam
-settings.link.description=Sasaistot pakotni ar repozitoriju, tā tiks attēlota repozitorija pakotņu sarakstā.
settings.link.select=Norādiet repozitoriju
settings.link.button=Atjaunot repozitorija saiti
settings.link.success=Repozitorija saite tika veiksmīgi atjaunota.
diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini
index e345c336b40..b457ecc8004 100644
--- a/options/locale/locale_pt-BR.ini
+++ b/options/locale/locale_pt-BR.ini
@@ -1010,9 +1010,9 @@ visibility.private_tooltip=Visível apenas para membros das organizações às q
new_repo_helper=Um repositório contém todos os arquivos do projeto, inclusive o histórico de revisões. Já está hospedando um em outro lugar? Migre o repositório.
owner=Proprietário
owner_helper=Algumas organizações podem não aparecer no menu devido a um limite de contagem dos repositórios.
-repo_name=Nome do repositório
+repo_name=Nome do Repositório
repo_name_helper=Bons nomes de repositórios usam palavras-chave curtas, memorizáveis e únicas. Um repositório chamado ".profile" ou ".profile-private" pode ser usado para adicionar um README.md para seu perfil de usuário/organização.
-repo_size=Tamanho do repositório
+repo_size=Tamanho do Repositório
template=Modelo
template_select=Selecione um modelo.
template_helper=Tornar repositório um modelo
@@ -1079,7 +1079,7 @@ mirror_lfs=Armazenamento de Arquivo Grande (LFS)
mirror_lfs_desc=Ativar espelhamento de dados LFS.
mirror_lfs_endpoint=Destino LFS
mirror_lfs_endpoint_desc=A sincronização tentará usar o URL de clonagem para determinar o servidor LFS. Você também pode especificar um destino personalizado se os dados do repositório LFS forem armazenados em outro lugar.
-mirror_last_synced=Última sincronização
+mirror_last_synced=Última Sincronização
mirror_password_placeholder=(inalterada)
mirror_password_blank_placeholder=(não definida)
mirror_password_help=Altere o nome de usuário para apagar uma senha armazenada.
@@ -1103,9 +1103,9 @@ delete_preexisting_success=Arquivos órfãos excluídos em %s
blame_prior=Ver a responsabilização anterior a esta modificação
-transfer.accept=Aceitar transferência
+transfer.accept=Aceitar Transferência
transfer.accept_desc=`Transferir para "%s"`
-transfer.reject=Rejeitar transferência
+transfer.reject=Rejeitar Transferência
transfer.reject_desc=`Cancelar a transferência para "%s"`
transfer.no_permission_to_accept=Você não tem permissão para aceitar essa transferência.
transfer.no_permission_to_reject=Você não tem permissão para rejeitar essa transferência.
@@ -1118,14 +1118,14 @@ desc.internal=Interno
desc.archived=Arquivado
desc.sha256=SHA256
-template.items=Itens do modelo
+template.items=Itens do Modelo
template.git_content=Conteúdo Git (Branch padrão)
template.git_hooks=Hooks do Git
template.git_hooks_tooltip=Atualmente você não pode modificar ou remover os Git Hooks adicionados. Selecione isso apenas se você confia no repositório modelo.
template.webhooks=Webhooks
template.topics=Tópicos
template.avatar=Avatar
-template.issue_labels=Etiquetas de issue
+template.issue_labels=Etiquetas de Issue
template.one_item=Deve-se selecionar pelo menos um item de modelo
template.invalid=Deve-se selecionar um repositório de modelo
@@ -1148,7 +1148,7 @@ migrate_options_lfs_endpoint.label=Destino LFS
migrate_options_lfs_endpoint.description=A migração tentará usar seu controle remoto Git para determinar o servidor LFS. Você também pode especificar um destino personalizado se os dados do repositório LFS forem armazenados em outro lugar.
migrate_options_lfs_endpoint.description.local=Um caminho de servidor local também é suportado.
migrate_options_lfs_endpoint.placeholder=Se for deixado em branco, o destino será derivado do URL de clone.
-migrate_items=Itens da migração
+migrate_items=Itens da Migração
migrate_items_wiki=Wiki
migrate_items_milestones=Marcos
migrate_items_labels=Etiquetas
@@ -1232,7 +1232,7 @@ find_tag=Pesquisar etiqueta
branches=Branches
tags=Tags
issues=Issues
-pulls=Pull requests
+pulls=Pull Requests
projects=Projetos
packages=Pacotes
actions=Ações
@@ -1363,7 +1363,7 @@ commits.no_commits=Nenhum commit em comum. "%s" e "%s" tem históricos completam
commits.nothing_to_compare=Estes branches são iguais.
commits.search.tooltip=Você pode prefixar as palavras-chave com "author:" (autor da mudança), "committer:" (autor do commit), "after:" (depois) ou "before:" (antes). Por exemplo: "revert author:Ana before:2019-01-13".\
commits.search_branch=Este Branch
-commits.search_all=Todos os branches
+commits.search_all=Todos os Branches
commits.author=Autor
commits.message=Mensagem
commits.date=Data
@@ -1396,7 +1396,7 @@ projects.description=Descrição (opcional)
projects.description_placeholder=Descrição
projects.create=Criar Projeto
projects.title=Título
-projects.new=Novo projeto
+projects.new=Novo Projeto
projects.new_subheader=Coordene, acompanhe e atualize seu trabalho em um só lugar, para que os projetos permaneçam transparentes e dentro do cronograma.
projects.create_success=Projeto "%s" criado.
projects.deletion=Apagar Projeto
@@ -1407,25 +1407,25 @@ projects.edit_subheader=Projetos organizam issues e acompanham o progresso.
projects.modify=Atualizar Projeto
projects.edit_success=Projeto "%s" atualizado.
projects.type.none=Nenhum
-projects.type.basic_kanban=Kanban básico
+projects.type.basic_kanban=Kanban Básico
projects.type.bug_triage=Triagem de Bugs
projects.template.desc=Modelo de projeto
projects.template.desc_helper=Selecione um modelo de projeto para começar
projects.column.edit=Editar coluna
projects.column.edit_title=Nome
projects.column.new_title=Nome
-projects.column.new_submit=Criar coluna
+projects.column.new_submit=Criar Coluna
projects.column.new=Nova Coluna
-projects.column.set_default=Atribuir como padrão
+projects.column.set_default=Atribuir como Padrão
projects.column.set_default_desc=Definir esta coluna como padrão para pull e issues sem categoria
-projects.column.delete=Excluir coluna
+projects.column.delete=Excluir Coluna
projects.column.color=Cor
projects.open=Abrir
projects.close=Fechar
projects.column.assigned_to=Atribuído a
projects.card_type.desc=Pré-visualizações de Cards
projects.card_type.images_and_text=Imagens e Texto
-projects.card_type.text_only=Somente texto
+projects.card_type.text_only=Somente Texto
issues.desc=Organize relatórios de bugs, tarefas e marcos.
issues.filter_assignees=Filtrar Atribuição
@@ -1665,7 +1665,7 @@ issues.add_time_hours=Horas
issues.add_time_minutes=Minutos
issues.add_time_sum_to_small=Nenhum tempo foi inserido.
issues.time_spent_total=Tempo Total Gasto
-issues.time_spent_from_all_authors=`Tempo total gasto: %s`
+issues.time_spent_from_all_authors=`Tempo Total Gasto: %s`
issues.due_date=Data Limite
issues.invalid_due_date_format=Formato da data limite inválido, deve ser 'dd/mm/aaaa'.
@@ -1755,9 +1755,9 @@ compare.compare_base=base
compare.compare_head=comparar
pulls.desc=Habilitar pull requests e revisões de código.
-pulls.new=Novo pull request
+pulls.new=Novo Pull Request
pulls.view=Ver Pull Request
-pulls.compare_changes=Novo pull request
+pulls.compare_changes=Novo Pull Request
pulls.allow_edits_from_maintainers=Permitir edições de mantenedores
pulls.allow_edits_from_maintainers_desc=Usuários com acesso de gravação para o branch base também podem fazer push para este branch
pulls.allow_edits_from_maintainers_err=Falha na atualização
@@ -1787,7 +1787,7 @@ pulls.merged_title_desc=aplicou merge dos %[1]d commits de %[2]s em
pulls.change_target_branch_at=`mudou o branch de destino de %s para %s %s`
pulls.tab_conversation=Conversação
pulls.tab_commits=Commits
-pulls.tab_files=Arquivos alterados
+pulls.tab_files=Arquivos Alterados
pulls.reopen_to_merge=Por favor reabra este pull request para aplicar o merge.
pulls.cant_reopen_deleted_branch=Este pull request não pode ser reaberto porque o branch foi excluído.
pulls.merged=Merge aplicado
@@ -1837,9 +1837,9 @@ pulls.merge_commit_id=A ID de merge commit
pulls.require_signed_wont_sign=O branch requer commits assinados, mas este merge não será assinado
pulls.invalid_merge_option=Você não pode usar esta opção de merge neste pull request.
-pulls.merge_conflict_summary=Mensagem de erro
+pulls.merge_conflict_summary=Mensagem de Erro
pulls.rebase_conflict_summary=Mensagem de Erro
-pulls.push_rejected_summary=Mensagem completa da rejeição
+pulls.push_rejected_summary=Mensagem Completa da Rejeição
pulls.open_unmerged_pull_exists=`Não é possível executar uma operação de reabertura pois há um pull request pendente (#%d) com propriedades idênticas.`
pulls.status_checking=Algumas verificações estão pendentes
pulls.status_checks_success=Todas as verificações foram bem sucedidas
@@ -1855,7 +1855,7 @@ pulls.update_branch_rebase=Atualizar branch por rebase
pulls.update_branch_success=Atualização do branch foi bem-sucedida
pulls.update_not_allowed=Você não tem permissão para atualizar o branch
pulls.outdated_with_base_branch=Este branch está desatualizado com o branch base
-pulls.close=Fechar pull request
+pulls.close=Fechar Pull Request
pulls.closed_at=`fechou este pull request %[2]s`
pulls.reopened_at=`reabriu este pull request %[2]s`
pulls.cmd_instruction_checkout_title=Checkout
@@ -1885,7 +1885,7 @@ pull.deleted_branch=(excluído):%s
pull.agit_documentation=Veja a documentação sobre AGit
-milestones.new=Novo marco
+milestones.new=Novo Marco
milestones.closed=Fechado %s
milestones.update_ago=Atualizado há %s
milestones.no_due_date=Sem data limite
@@ -1896,11 +1896,11 @@ milestones.completeness=%d%% Concluído
milestones.create=Criar Marco
milestones.title=Título
milestones.desc=Descrição
-milestones.due_date=Data limite (opcional)
+milestones.due_date=Data Limite (opcional)
milestones.clear=Limpar
milestones.invalid_due_date_format=Formato da data limite deve ser 'dd/mm/aaaa'.
milestones.create_success=O marco "%s" foi criado.
-milestones.edit=Editar marco
+milestones.edit=Editar Marco
milestones.edit_subheader=Marcos organizam as issues e acompanham o progresso.
milestones.cancel=Cancelar
milestones.modify=Atualizar Marco
@@ -1931,24 +1931,24 @@ ext_wiki=Acesso a Wiki Externo
ext_wiki.desc=Link para uma wiki externa.
wiki=Wiki
-wiki.welcome=Bem-vindo a wiki.
+wiki.welcome=Bem-vindo a Wiki.
wiki.welcome_desc=A wiki permite que você escreva e compartilhe a documentação com os colaboradores.
wiki.desc=Escrever e compartilhar a documentação com os colaboradores.
-wiki.create_first_page=Criar a primeira página
+wiki.create_first_page=Criar a Primeira Página
wiki.page=Página
wiki.filter_page=Filtrar página
wiki.new_page=Página
wiki.page_title=Título da página
wiki.page_content=Conteúdo
wiki.default_commit_message=Escreva uma nota sobre a atualização nesta página (opcional).
-wiki.save_page=Salvar página
+wiki.save_page=Salvar Página
wiki.last_commit_info=%s editou esta página %s
wiki.edit_page_button=Editar
-wiki.new_page_button=Nova página
-wiki.file_revision=Revisão de página
+wiki.new_page_button=Nova Página
+wiki.file_revision=Revisão de Página
wiki.wiki_page_revisions=Revisões de página Wiki
wiki.back_to_wiki=Voltar para página Wiki
-wiki.delete_page_button=Excluir página
+wiki.delete_page_button=Excluir Página
wiki.delete_page_notice_1=A exclusão da página de wiki "%s" não pode ser desfeita. Continuar?
wiki.page_already_exists=Uma página de wiki com o mesmo nome já existe.
wiki.reserved_page=O nome da página da wiki "%s" está reservado.
@@ -2042,7 +2042,7 @@ settings.collaboration.undefined=Indefinido
settings.hooks=Webhooks
settings.githooks=Hooks do Git
settings.basic_settings=Configurações Básicas
-settings.mirror_settings=Opções de espelhamento
+settings.mirror_settings=Opções de Espelhamento
settings.mirror_settings.docs=Configure o seu repositório para sincronizar automaticamente commits, tags e branches de outro repositório.
settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=No momento, isso só pode ser feito no menu "Nova migração". Para obter mais informações, consulte:
settings.mirror_settings.docs.can_still_use=Embora não seja possível modificar os espelhos existentes ou criar novos espelhos, você ainda pode usar o espelho existente.
@@ -2057,25 +2057,25 @@ settings.mirror_settings.push_mirror.remote_url=URL do repositório do Git remot
settings.mirror_settings.push_mirror.add=Adicionar Espelho de Push
settings.mirror_settings.push_mirror.edit_sync_time=Editar intervalo de sincronização de espelhos
-settings.sync_mirror=Sincronizar agora
+settings.sync_mirror=Sincronizar Agora
settings.site=Site
-settings.update_settings=Atualizar configurações
-settings.update_mirror_settings=Atualizar espelho
-settings.branches.switch_default_branch=Alterar
+settings.update_settings=Atualizar Configurações
+settings.update_mirror_settings=Atualizar Configurações de Espelhamento
+settings.branches.switch_default_branch=Alterar Branch Padrão
settings.branches.update_default_branch=Atualizar Branch Padrão
settings.branches.add_new_rule=Adicionar Nova Regra
-settings.advanced_settings=Configurações avançadas
-settings.wiki_desc=Habilitar a wiki do repositório
-settings.use_internal_wiki=Usar a wiki nativa
+settings.advanced_settings=Configurações Avançadas
+settings.wiki_desc=Habilitar a Wiki do Repositório
+settings.use_internal_wiki=Usar a Wiki Nativa
settings.default_wiki_branch_name=Nome Padrão do Branch da Wiki
-settings.use_external_wiki=Usar wiki externa
-settings.external_wiki_url=URL externa da wiki
+settings.use_external_wiki=Usar Wiki Externa
+settings.external_wiki_url=URL Externa da Wiki
settings.external_wiki_url_error=A URL da wiki externa não é válida.
settings.external_wiki_url_desc=Visitantes são redirecionados para a URL da wiki externa ao clicar na aba da wiki.
settings.issues_desc=Habilitar Issue Tracker para o Repositório
settings.use_internal_issue_tracker=Usar o issue tracker nativo
settings.use_external_issue_tracker=Usar issue tracker externo
-settings.external_tracker_url=URL do issue tracker externo
+settings.external_tracker_url=URL do Issue Tracker Externo
settings.external_tracker_url_error=A URL do issue tracker externo não é válida.
settings.external_tracker_url_desc=Visitantes são redirecionados para a URL do issue tracker externo ao clicar na aba de issues.
settings.tracker_url_format=Formato de URL do issue tracker externo
@@ -2099,29 +2099,29 @@ settings.releases_desc=Habilitar versões do Repositório
settings.packages_desc=Habilitar Registro de Pacotes de Repositório
settings.projects_desc=Habilitar Projetos
settings.projects_mode_all=Todos os projetos
-settings.actions_desc=Habilitar ações do repositório
-settings.admin_settings=Configurações do administrador
+settings.actions_desc=Habilitar Ações do Repositório
+settings.admin_settings=Configurações do Administrador
settings.admin_enable_health_check=Habilitar verificações de integridade (git fsck) no repositório
-settings.admin_code_indexer=Indexador de código
+settings.admin_code_indexer=Indexador de Código
settings.admin_stats_indexer=Indexador de Estatísticas do Código
settings.admin_indexer_commit_sha=Último SHA indexado
settings.admin_indexer_unindexed=Não indexado
settings.reindex_button=Adicionar à fila de reindexação
settings.reindex_requested=Reindexação Requisitada
settings.admin_enable_close_issues_via_commit_in_any_branch=Fechar issue via commit em um branch não padrão
-settings.danger_zone=Zona de perigo
+settings.danger_zone=Zona de Perigo
settings.new_owner_has_same_repo=O novo proprietário já tem um repositório com o mesmo nome. Por favor, escolha outro nome.
settings.convert=Converter para repositório tradicional
settings.convert_desc=Você pode converter este espelhamento em um repositório tradicional. Esta ação não pode ser revertida.
settings.convert_notices_1=Esta operação vai converter este espelhamento em um repositório tradicional. Esta ação não pode ser desfeita.
-settings.convert_confirm=Converter o repositório
+settings.convert_confirm=Converter o Repositório
settings.convert_succeed=O espelhamento foi convertido em um repositório tradicional.
settings.convert_fork=Converter Para Um Repositório Normal
settings.convert_fork_desc=Você pode converter este fork em um repositório normal. Esta ação não pode ser desfeita.
settings.convert_fork_notices_1=Esta operação irá converter o fork em um repositório normal e não pode ser desfeita.
-settings.convert_fork_confirm=Converter repositório
+settings.convert_fork_confirm=Converter Repositório
settings.convert_fork_succeed=O fork foi convertido em um repositório normal.
-settings.transfer=Transferir propriedade
+settings.transfer=Transferir Propriedade
settings.transfer.rejected=A transferência do repositório foi rejeitada.
settings.transfer.success=A transferência do repositório foi bem sucedida.
settings.transfer_abort=Cancelar transferência
@@ -2132,7 +2132,7 @@ settings.transfer_form_title=Digite o nome do repositório para confirmar:
settings.transfer_notices_1=- Você perderá o acesso ao repositório se transferir para um usuário individual.
settings.transfer_notices_2=- Você manterá acesso ao repositório se transferi-lo para uma organização que você também é proprietário.
settings.transfer_notices_3=- Se o repositório for privado e for transferido para um usuário individual, esta ação certifica que o usuário tem pelo menos permissão de leitura (e altera as permissões se necessário).
-settings.transfer_owner=Novo proprietário
+settings.transfer_owner=Novo Proprietário
settings.transfer_perform=Executar Transferência
settings.transfer_started=`Este repositório foi marcado para transferência e aguarda a confirmação de "%s"`
settings.transfer_succeed=O repositório foi transferido.
@@ -2145,7 +2145,7 @@ settings.trust_model.collaborator.long=Colaborador: Confiar em assinaturas feita
settings.trust_model.committer=Committer
settings.trust_model.collaboratorcommitter=Colaborador+Commiter
settings.trust_model.collaboratorcommitter.long=Colaborador+Committer: Confiar na assinatura dos colaboradores que correspondem ao autor do commit
-settings.wiki_delete=Excluir dados da wiki
+settings.wiki_delete=Excluir Dados da Wiki
settings.wiki_delete_desc=A exclusão de dados da wiki é permanente e não pode ser desfeita.
settings.wiki_delete_notices_1=- Isso excluirá e desabilitará permanentemente a wiki do repositório %s.
settings.confirm_wiki_delete=Excluir Dados da Wiki
@@ -2156,14 +2156,14 @@ settings.delete_notices_1=- Esta operação NÃO PODERÁ ser de
settings.delete_notices_fork_1=- Forks deste repositório se tornarão independentes após a exclusão.
settings.deletion_success=O repositório foi excluído.
settings.update_settings_success=As configurações do repositório foram atualizadas.
-settings.confirm_delete=Excluir repositório
-settings.add_collaborator=Adicionar colaborador
+settings.confirm_delete=Excluir Repositório
+settings.add_collaborator=Adicionar Colaborador
settings.add_collaborator_success=O colaborador foi adicionado.
settings.add_collaborator_inactive_user=Não é possível adicionar um usuário inativo como colaborador.
settings.add_collaborator_owner=Não é possível adicionar um proprietário como um colaborador.
settings.add_collaborator_duplicate=O colaborador já está adicionado a este repositório.
settings.delete_collaborator=Remover
-settings.collaborator_deletion=Remover colaborador
+settings.collaborator_deletion=Remover Colaborador
settings.collaborator_deletion_desc=A exclusão de um colaborador irá revogar o acesso a este repositório. Continuar?
settings.remove_collaborator_success=O colaborador foi removido.
settings.org_not_allowed_to_be_collaborator=Organizações não podem ser adicionadas como um colaborador.
@@ -2174,10 +2174,10 @@ settings.add_team=Adicionar Equipe
settings.add_team_duplicate=A equipe já tem o repositório
settings.delete_team_tip=Esta equipe tem acesso a todos os repositórios e não pode ser removida
settings.remove_team_success=O acesso da equipe ao repositório foi removido.
-settings.add_webhook=Adicionar webhook
+settings.add_webhook=Adicionar Webhook
settings.add_webhook.invalid_channel_name=Nome do canal no webhook não pode estar em branco e não pode conter somente o caractere #.
settings.hooks_desc=Webhooks automaticamente fazem requisições de HTTP POST para um servidor quando acionados determinados eventos de Gitea. Leia mais no guia de webhooks.
-settings.webhook_deletion=Remover webhook
+settings.webhook_deletion=Remover Webhook
settings.webhook_deletion_desc=A exclusão de um webhook exclui suas configurações e o histórico de entrega. Continuar?
settings.webhook_deletion_success=O webhook foi removido.
settings.webhook.test_delivery=Testar Evento de Push
@@ -2194,7 +2194,7 @@ settings.githook_name=Nome do Hook
settings.githook_content=Conteúdo do Hook
settings.update_githook=Atualizar Hook
settings.add_webhook_desc=Gitea enviará requisições POST com um tipo de conteúdo especificado para a URL de destino. Leia mais no guia de webhooks.
-settings.payload_url=URL de destino
+settings.payload_url=URL de Destino
settings.http_method=Método HTTP
settings.content_type=Tipo de conteúdo POST
settings.secret=Senha
@@ -2204,9 +2204,9 @@ settings.slack_color=Cor
settings.discord_username=Nome de usuário
settings.discord_icon_url=URL do ícone
settings.event_desc=Acionado em:
-settings.event_push_only=Eventos de push
-settings.event_send_everything=Todos os eventos
-settings.event_choose=Eventos personalizados...
+settings.event_push_only=Eventos de Push
+settings.event_send_everything=Todos os Eventos
+settings.event_choose=Eventos Personalizados…
settings.event_header_repository=Eventos do Repositório
settings.event_create=Criar
settings.event_create_desc=Branch ou tag criado.
@@ -2232,10 +2232,10 @@ settings.event_issue_label=Issue Rotulada
settings.event_issue_label_desc=Rótulos da issue atualizados ou removidos.
settings.event_issue_milestone=Marco Atribuído à Issue
settings.event_issue_milestone_desc=Marco atribuído ou desatribuído à Issue.
-settings.event_issue_comment=Comentário da issue
+settings.event_issue_comment=Comentário da Issue
settings.event_issue_comment_desc=Comentário da issue criado, editado ou excluído.
settings.event_header_pull_request=Eventos de Pull Request
-settings.event_pull_request=Pull request
+settings.event_pull_request=Pull Request
settings.event_pull_request_desc=Pull request aberto, fechado, reaberto, editado ou excluído.
settings.event_pull_request_assign=Pull Request Atribuído
settings.event_pull_request_assign_desc=Pull request atribuído ou desatribuído.
@@ -2257,9 +2257,9 @@ settings.authorization_header_desc=Será incluído como header de autorização
settings.active=Ativo
settings.active_helper=Informações sobre eventos disparados serão enviadas para esta URL do webhook.
settings.add_hook_success=O webhook foi adicionado.
-settings.update_webhook=Atualizar webhook
+settings.update_webhook=Atualizar Webhook
settings.update_hook_success=O webhook foi atualizado.
-settings.delete_webhook=Remover webhook
+settings.delete_webhook=Remover Webhook
settings.recent_deliveries=Entregas Recentes
settings.hook_type=Tipo de Hook
settings.slack_token=Token
@@ -2285,14 +2285,14 @@ settings.packagist_package_url=URL do pacote do Packagist
settings.deploy_keys=Chaves de Deploy
settings.add_deploy_key=Nova Chave de Deploy
settings.deploy_key_desc=As chaves de deploy possuem somente acesso de leitura (pull) ao repositório.
-settings.is_writable=Habilitar acesso de escrita
+settings.is_writable=Habilitar Acesso de Escrita
settings.is_writable_info=Permitir que esta chave de deploy faça push para o repositório.
settings.no_deploy_keys=Não há nenhuma chave de deploy ainda.
settings.title=Título
settings.deploy_key_content=Conteúdo da chave
settings.key_been_used=Uma chave de deploy com conteúdo idêntico já está em uso.
settings.key_name_used=Uma chave de deploy já existe com esse mesmo nome.
-settings.deploy_key_deletion=Remover chave de deploy
+settings.deploy_key_deletion=Remover Chave de Deploy
settings.deploy_key_deletion_desc=A exclusão de uma chave de deploy irá revogar o seu acesso a este repositório. Continuar?
settings.deploy_key_deletion_success=A chave de deploy foi removida.
settings.branches=Branches
@@ -2304,15 +2304,15 @@ settings.protected_branch_can_push_yes=Você pode fazer push
settings.protected_branch_can_push_no=Você não pode fazer push
settings.protect_this_branch=Habilitar Proteção de Branch
settings.protect_this_branch_desc=Previne a exclusão e restringe o merge e push para o branch.
-settings.protect_disable_push=Desabilitar push
+settings.protect_disable_push=Desabilitar Push
settings.protect_disable_push_desc=Nenhum push será permitido neste branch.
settings.protect_disable_force_push=Desativar Push Forçado
settings.protect_disable_force_push_desc=Nenhum push forçado será permitido para este branch.
settings.protect_enable_push=Habilitar Push
settings.protect_enable_push_desc=Qualquer pessoa com acesso de escrita terá permissão para realizar push neste branch (mas não forçar o push).
settings.protect_enable_force_push_all=Ativar Push Forçado
-settings.protect_enable_merge=Permitir merge
-settings.protect_check_status_contexts=Habilitar verificação de status
+settings.protect_enable_merge=Permitir Merge
+settings.protect_check_status_contexts=Habilitar Verificação de Status
settings.protect_check_status_contexts_list=Verificações de status encontradas na última semana para este repositório
settings.protect_required_approvals=Aprovações necessárias:
settings.dismiss_stale_approvals=Descartar aprovações obsoletas
@@ -2350,7 +2350,7 @@ settings.tags.protection.allowed=Permitido
settings.tags.protection.allowed.users=Usuários permitidos
settings.tags.protection.allowed.teams=Equipes permitidas
settings.tags.protection.allowed.noone=Ninguém
-settings.tags.protection.create=Proteger tag
+settings.tags.protection.create=Proteger Tag
settings.tags.protection.none=Não há tags protegidas.
settings.bot_token=Token do Bot
settings.chat_id=ID do Chat
@@ -2359,7 +2359,7 @@ settings.matrix.room_id=ID da Sala
settings.matrix.message_type=Tipo de Mensagem
settings.visibility.private.button=Tornar Privado
settings.visibility.public.button=Tornar Público
-settings.archive.button=Arquivar repositório
+settings.archive.button=Arquivar Repositório
settings.archive.header=Arquivar Este Repositório
settings.archive.success=O repositório foi arquivado com sucesso.
settings.archive.error=Um erro ocorreu enquanto estava sendo arquivado o repositório. Veja o log para mais detalhes.
@@ -2384,12 +2384,12 @@ settings.lfs_invalid_locking_path=Caminho inválido: %s
settings.lfs_invalid_lock_directory=Não é possível bloquear o diretório: %s
settings.lfs_lock_already_exists=O bloqueio já existe: %s
settings.lfs_lock=Bloqueio
-settings.lfs_locks_no_locks=Sem bloqueios
+settings.lfs_locks_no_locks=Sem Bloqueios
settings.lfs_lock_file_no_exist=Arquivo bloqueado não existe no branch padrão
-settings.lfs_force_unlock=Forçar desbloqueio
+settings.lfs_force_unlock=Forçar Desbloqueio
settings.lfs_pointers.sha=SHA Blob
settings.lfs_pointers.oid=OID
-settings.lfs_pointers.inRepo=No repositório
+settings.lfs_pointers.inRepo=No Repositório
settings.lfs_pointers.exists=Existe na loja
settings.lfs_pointers.accessible=Acessível ao Usuário
settings.lfs_pointers.associateAccessible=Associar %d OIDs acessíveis
@@ -2459,7 +2459,7 @@ releases.desc=Acompanhe as versões e downloads do projeto.
release.releases=Versões
release.detail=Detalhes da versão
release.tags=Tags
-release.new_release=Nova versão
+release.new_release=Nova Versão
release.draft=Rascunho
release.prerelease=Versão prévia
release.stable=Estável
@@ -2479,15 +2479,15 @@ release.tag_helper_existing=Tag existente.
release.title=Título da versão
release.title_empty=O título não pode estar em branco.
release.message=Descreva esta versão
-release.prerelease_desc=Marcar como pré-lançamento
+release.prerelease_desc=Marcar como Pré-lançamento
release.prerelease_helper=Marcar esta versão como inadequada para uso em produção.
release.cancel=Cancelar
-release.publish=Publicar versão
-release.save_draft=Salvar rascunho
-release.edit_release=Atualizar versão
+release.publish=Publicar Versão
+release.save_draft=Salvar Rascunho
+release.edit_release=Atualizar Versão
release.delete_release=Excluir Versão
release.delete_tag=Apagar Tag
-release.deletion=Excluir versão
+release.deletion=Excluir Versão
release.deletion_desc=A exclusão de uma versão apenas a remove do Gitea. Isso não afetará a tag do Git, o conteúdo do seu repositório ou seu histórico. Continuar?
release.deletion_success=A versão foi excluída.
release.deletion_tag_desc=A tag será excluída do repositório. Conteúdo do repositório e histórico permanecerão inalterados. Continuar?
@@ -3381,7 +3381,6 @@ swift.install=Adicione o pacote em seu arquivo Package.swift:
swift.install2=e execute o seguinte comando:
vagrant.install=Para adicionar uma Vagrant box, execute o seguinte comando:
settings.link=Vincular este pacote a um repositório
-settings.link.description=Se você vincular um pacote a um repositório, o pacote será listado na lista de pacotes do repositório.
settings.link.select=Selecionar Repositório
settings.link.button=Atualizar Link do Repositório
settings.link.success=Link do repositório foi atualizado com sucesso.
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index c16677151c4..9e648b66023 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -3599,7 +3599,7 @@ no_subscriptions=Sem subscrições
default_key=Assinado com a chave padrão
error.extract_sign=Falhou ao extrair a assinatura
error.generate_hash=Falhou ao gerar o hash do cometimento
-error.no_committer_account=Não existe qualquer conta ligada ao endereço de email de quem cometeu
+error.no_committer_account=Não existe qualquer conta vinculada ao endereço de email de quem cometeu
error.no_gpg_keys_found=Não foi encontrada uma chave conhecida para esta assinatura, na base de dados
error.not_signed_commit=Não é um cometimento assinado
error.failed_retrieval_gpg_keys=Falhou ao obter uma chave ligada à conta de quem cometeu
@@ -3617,7 +3617,7 @@ desc=Gerir pacotes do repositório.
empty=Ainda não há pacotes.
no_metadata=Sem metadados.
empty.documentation=Para obter mais informação sobre o registo de pacotes, veja a documentação.
-empty.repo=Carregou um pacote mas este não é apresentado aqui? Vá às configurações do pacote e ligue-o a este repositório.
+empty.repo=Carregou um pacote mas este não é apresentado aqui? Vá às configurações do pacote e vincule-o a este repositório.
registry.documentation=Para mais informação sobre o registo %s, veja a documentação.
filter.type=Tipo
filter.type.all=Todos
@@ -3729,11 +3729,14 @@ swift.install=Adicione o pacote no seu ficheiro Package.swift:
swift.install2=e execute o seguinte comando:
vagrant.install=Para adicionar uma máquina virtual Vagrant, execute o seguinte comando:
settings.link=Vincular este pacote a um repositório
-settings.link.description=Se você vincular um pacote a um repositório, o pacote será listado na lista de pacotes do repositório.
+settings.link.description=Se você vincular um pacote a um repositório, o pacote será listado na lista de pacotes do repositório. Apenas os repositórios do mesmo dono podem ser vinculados. Deixar o campo em branco irá remover o vínculo.
settings.link.select=Escolha o repositório
settings.link.button=Modificar vínculo ao repositório
-settings.link.success=A ligação ao repositório foi modificada com sucesso.
+settings.link.success=O vínculo ao repositório foi modificado com sucesso.
settings.link.error=Falhou a modificação do vínculo ao repositório.
+settings.link.repo_not_found=O repositório %s não foi encontrado.
+settings.unlink.error=Falhou a remoção do vínculo ao repositório.
+settings.unlink.success=O vínculo ao repositório foi removido com sucesso.
settings.delete=Eliminar pacote
settings.delete.description=Eliminar o pacote é permanente e não pode ser desfeito.
settings.delete.notice=Está prestes a eliminar %s (%s). Esta operação é irreversível. Tem a certeza?
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index 47aace96144..6da0eea91ce 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -3083,7 +3083,6 @@ swift.install=Добавьте пакет в свой файл Package.swi
swift.install2=и запустите следующую команду:
vagrant.install=Чтобы добавить бокс Vagrant, выполните следующую команду:
settings.link=Связать этот пакет с репозиторием
-settings.link.description=Если связать пакет с репозиторием, он добавится в список пакетов репозитория.
settings.link.select=Выберите репозиторий
settings.link.button=Обновить ссылку на репозиторий
settings.link.success=Связь с репозиторием успешно обновлена.
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index 8b0e1aced26..a3ae736f67a 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -3418,7 +3418,6 @@ swift.install=Paketi Package.swift dosyanıza ekleyin:
swift.install2=ve şu komutu çalıştırın:
vagrant.install=Vagrant paketi eklemek için aşağıdaki komutu çalıştırın:
settings.link=Bu paketi bir depoya bağlayın
-settings.link.description=Eğer bir paketi bir depoya bağlarsanız, paket deponun paket listesinde listelenecektir.
settings.link.select=Depo Seç
settings.link.button=Depo Bağlantısını Güncelle
settings.link.success=Depo bağlantısı başarıyla güncellendi.
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index 85a9982d00a..1849d5d3782 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -3290,7 +3290,6 @@ swift.install=Додайте пакет у ваш файл Package.swift
swift.install2=і виконайте наступну команду:
vagrant.install=Щоб додати бокс Vagrant, виконайте наступну команду:
settings.link=Прив'язати пакет до сховища
-settings.link.description=Якщо ви зв'яжете пакет зі сховищем, його буде вказано у списку пакетів сховища.
settings.link.select=Обрати сховище
settings.link.button=Оновити посилання на сховище
settings.link.error=Не вдалося оновити посилання на сховище.
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index c0817b79bbe..496efa46a74 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -3723,7 +3723,6 @@ swift.install=在您的 Package.swift 文件中添加该包:
swift.install2=并运行以下命令:
vagrant.install=若要添加一个 Vagrant box,请运行以下命令:
settings.link=将此软件包链接到仓库
-settings.link.description=如果您将一个软件包与一个仓库链接起来,软件包将显示在仓库的软件包列表中。
settings.link.select=选择仓库
settings.link.button=更新仓库链接
settings.link.success=仓库链接已成功更新。
diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini
index c82987ed73b..c1879203f7d 100644
--- a/options/locale/locale_zh-TW.ini
+++ b/options/locale/locale_zh-TW.ini
@@ -3397,7 +3397,6 @@ swift.install=將此套件加入您的 Package.swift 檔:
swift.install2=並執行下列命令:
vagrant.install=執行下列命令以新增 Vagrant box:
settings.link=連結此套件到儲存庫
-settings.link.description=如果您將套件連結到儲存庫,該套件會顯示在儲存庫的套件清單。
settings.link.select=選擇儲存庫
settings.link.button=更新儲存庫連結
settings.link.success=儲存庫連結更新成功。
diff --git a/package.json b/package.json
index 79aaa880a55..0b2ce033545 100644
--- a/package.json
+++ b/package.json
@@ -11,14 +11,15 @@
"@citation-js/plugin-csl": "0.7.18",
"@citation-js/plugin-software-formats": "0.6.1",
"@github/markdown-toolbar-element": "2.2.3",
+ "@github/paste-markdown": "1.5.3",
"@github/relative-time-element": "4.4.8",
"@github/text-expander-element": "2.9.2",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
- "@primer/octicons": "19.17.0",
+ "@primer/octicons": "19.18.0",
"@resvg/resvg-wasm": "2.6.2",
"@silverwind/vue3-calendar-heatmap": "2.0.6",
"@techknowlogick/license-checker-webpack-plugin": "0.3.0",
- "add-asset-webpack-plugin": "3.0.0",
+ "add-asset-webpack-plugin": "3.1.1",
"ansi_up": "6.0.6",
"asciinema-player": "3.10.0",
"chart.js": "4.5.0",
@@ -31,23 +32,21 @@
"dropzone": "6.0.0-beta.2",
"easymde": "2.20.0",
"esbuild-loader": "4.3.0",
- "htmx.org": "2.0.6",
+ "htmx.org": "2.0.7",
"idiomorph": "0.7.3",
"jquery": "3.7.1",
"katex": "0.16.22",
"mermaid": "11.11.0",
"mini-css-extract-plugin": "2.9.4",
- "minimatch": "10.0.3",
- "monaco-editor": "0.52.2",
+ "monaco-editor": "0.53.0",
"monaco-editor-webpack-plugin": "7.1.0",
"online-3d-viewer": "0.16.0",
"pdfobject": "2.3.1",
"perfect-debounce": "2.0.0",
"postcss": "8.5.6",
"postcss-loader": "8.2.0",
- "postcss-nesting": "13.0.2",
"sortablejs": "1.15.6",
- "swagger-ui-dist": "5.28.1",
+ "swagger-ui-dist": "5.29.0",
"tailwindcss": "3.4.17",
"throttle-debounce": "5.0.2",
"tinycolor2": "1.6.0",
@@ -63,46 +62,44 @@
"vue-loader": "17.4.2",
"webpack": "5.101.3",
"webpack-cli": "6.0.1",
- "wrap-ansi": "9.0.0"
+ "wrap-ansi": "9.0.2"
},
"devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "4.5.0",
"@playwright/test": "1.55.0",
"@stoplight/spectral-cli": "6.15.0",
- "@stylistic/eslint-plugin-js": "3.1.0",
+ "@stylistic/eslint-plugin": "5.3.1",
"@stylistic/stylelint-plugin": "4.0.0",
"@types/codemirror": "5.60.16",
"@types/dropzone": "5.7.9",
"@types/jquery": "3.5.33",
"@types/katex": "0.16.7",
- "@types/license-checker-webpack-plugin": "0.2.5",
"@types/pdfobject": "2.2.5",
"@types/sortablejs": "1.15.8",
"@types/swagger-ui-dist": "3.30.6",
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@types/toastify-js": "1.12.4",
- "@typescript-eslint/eslint-plugin": "8.42.0",
- "@typescript-eslint/parser": "8.42.0",
+ "@typescript-eslint/parser": "8.43.0",
"@vitejs/plugin-vue": "6.0.1",
"@vitest/eslint-plugin": "1.3.9",
- "eslint": "8.57.0",
+ "eslint": "9.35.0",
"eslint-import-resolver-typescript": "4.4.4",
- "eslint-plugin-array-func": "4.0.0",
- "eslint-plugin-github": "5.0.2",
+ "eslint-plugin-array-func": "5.0.2",
+ "eslint-plugin-github": "6.0.0",
"eslint-plugin-import-x": "4.16.1",
- "eslint-plugin-no-jquery": "3.1.1",
- "eslint-plugin-no-use-extend-native": "0.5.0",
+ "eslint-plugin-no-use-extend-native": "0.7.2",
"eslint-plugin-playwright": "2.2.2",
"eslint-plugin-regexp": "2.10.0",
"eslint-plugin-sonarjs": "3.0.5",
- "eslint-plugin-unicorn": "56.0.1",
+ "eslint-plugin-unicorn": "61.0.2",
"eslint-plugin-vue": "10.4.0",
"eslint-plugin-vue-scoped-css": "2.12.0",
"eslint-plugin-wc": "3.0.1",
+ "globals": "16.4.0",
"happy-dom": "18.0.1",
"markdownlint-cli": "0.45.0",
- "material-icon-theme": "5.26.0",
+ "material-icon-theme": "5.27.0",
"nolyfill": "1.0.44",
"postcss-html": "1.8.0",
"stylelint": "16.24.0",
@@ -111,8 +108,8 @@
"stylelint-declaration-strict-value": "1.10.11",
"stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "4.0.0",
- "type-fest": "4.41.0",
- "updates": "16.6.4",
+ "typescript-eslint": "8.43.0",
+ "updates": "16.7.0",
"vite-string-plugin": "1.4.6",
"vitest": "3.2.4",
"vue-tsc": "3.0.6"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 149d8f179c1..5d40acd1019 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -41,6 +41,9 @@ importers:
'@github/markdown-toolbar-element':
specifier: 2.2.3
version: 2.2.3
+ '@github/paste-markdown':
+ specifier: 1.5.3
+ version: 1.5.3
'@github/relative-time-element':
specifier: 4.4.8
version: 4.4.8
@@ -51,8 +54,8 @@ importers:
specifier: 0.1.0-alpha-3
version: 0.1.0-alpha-3
'@primer/octicons':
- specifier: 19.17.0
- version: 19.17.0
+ specifier: 19.18.0
+ version: 19.18.0
'@resvg/resvg-wasm':
specifier: 2.6.2
version: 2.6.2
@@ -63,8 +66,8 @@ importers:
specifier: 0.3.0
version: 0.3.0(webpack@5.101.3)
add-asset-webpack-plugin:
- specifier: 3.0.0
- version: 3.0.0(webpack@5.101.3)
+ specifier: 3.1.1
+ version: 3.1.1(webpack@5.101.3)
ansi_up:
specifier: 6.0.6
version: 6.0.6
@@ -102,8 +105,8 @@ importers:
specifier: 4.3.0
version: 4.3.0(webpack@5.101.3)
htmx.org:
- specifier: 2.0.6
- version: 2.0.6
+ specifier: 2.0.7
+ version: 2.0.7
idiomorph:
specifier: 0.7.3
version: 0.7.3
@@ -119,15 +122,12 @@ importers:
mini-css-extract-plugin:
specifier: 2.9.4
version: 2.9.4(webpack@5.101.3)
- minimatch:
- specifier: 10.0.3
- version: 10.0.3
monaco-editor:
- specifier: 0.52.2
- version: 0.52.2
+ specifier: 0.53.0
+ version: 0.53.0
monaco-editor-webpack-plugin:
specifier: 7.1.0
- version: 7.1.0(monaco-editor@0.52.2)(webpack@5.101.3)
+ version: 7.1.0(monaco-editor@0.53.0)(webpack@5.101.3)
online-3d-viewer:
specifier: 0.16.0
version: 0.16.0
@@ -143,15 +143,12 @@ importers:
postcss-loader:
specifier: 8.2.0
version: 8.2.0(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.3)
- postcss-nesting:
- specifier: 13.0.2
- version: 13.0.2(postcss@8.5.6)
sortablejs:
specifier: 1.15.6
version: 1.15.6
swagger-ui-dist:
- specifier: 5.28.1
- version: 5.28.1
+ specifier: 5.29.0
+ version: 5.29.0
tailwindcss:
specifier: 3.4.17
version: 3.4.17
@@ -198,21 +195,21 @@ importers:
specifier: 6.0.1
version: 6.0.1(webpack@5.101.3)
wrap-ansi:
- specifier: 9.0.0
- version: 9.0.0
+ specifier: 9.0.2
+ version: 9.0.2
devDependencies:
'@eslint-community/eslint-plugin-eslint-comments':
specifier: 4.5.0
- version: 4.5.0(eslint@8.57.0)
+ version: 4.5.0(eslint@9.35.0(jiti@2.5.1))
'@playwright/test':
specifier: 1.55.0
version: 1.55.0
'@stoplight/spectral-cli':
specifier: 6.15.0
version: 6.15.0
- '@stylistic/eslint-plugin-js':
- specifier: 3.1.0
- version: 3.1.0(eslint@8.57.0)
+ '@stylistic/eslint-plugin':
+ specifier: 5.3.1
+ version: 5.3.1(eslint@9.35.0(jiti@2.5.1))
'@stylistic/stylelint-plugin':
specifier: 4.0.0
version: 4.0.0(stylelint@16.24.0(typescript@5.9.2))
@@ -228,9 +225,6 @@ importers:
'@types/katex':
specifier: 0.16.7
version: 0.16.7
- '@types/license-checker-webpack-plugin':
- specifier: 0.2.5
- version: 0.2.5
'@types/pdfobject':
specifier: 2.2.5
version: 2.2.5
@@ -249,60 +243,57 @@ importers:
'@types/toastify-js':
specifier: 1.12.4
version: 1.12.4
- '@typescript-eslint/eslint-plugin':
- specifier: 8.42.0
- version: 8.42.0(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(typescript@5.9.2)
'@typescript-eslint/parser':
- specifier: 8.42.0
- version: 8.42.0(eslint@8.57.0)(typescript@5.9.2)
+ specifier: 8.43.0
+ version: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
'@vitejs/plugin-vue':
specifier: 6.0.1
- version: 6.0.1(vite@7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2))
+ version: 6.0.1(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2))
'@vitest/eslint-plugin':
specifier: 1.3.9
- version: 1.3.9(eslint@8.57.0)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))
+ version: 1.3.9(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))
eslint:
- specifier: 8.57.0
- version: 8.57.0
+ specifier: 9.35.0
+ version: 9.35.0(jiti@2.5.1)
eslint-import-resolver-typescript:
specifier: 4.4.4
- version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0))(eslint-plugin-import@2.32.0)(eslint@8.57.0)
+ version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-array-func:
- specifier: 4.0.0
- version: 4.0.0(eslint@8.57.0)
- eslint-plugin-github:
specifier: 5.0.2
- version: 5.0.2(@types/eslint@9.6.1)(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0)(typescript@5.9.2)
+ version: 5.0.2(eslint@9.35.0(jiti@2.5.1))
+ eslint-plugin-github:
+ specifier: 6.0.0
+ version: 6.0.0(@types/eslint@9.6.1)(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-import-x:
specifier: 4.16.1
- version: 4.16.1(@typescript-eslint/utils@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
- eslint-plugin-no-jquery:
- specifier: 3.1.1
- version: 3.1.1(eslint@8.57.0)
+ version: 4.16.1(@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-no-use-extend-native:
- specifier: 0.5.0
- version: 0.5.0
+ specifier: 0.7.2
+ version: 0.7.2(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-playwright:
specifier: 2.2.2
- version: 2.2.2(eslint@8.57.0)
+ version: 2.2.2(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-regexp:
specifier: 2.10.0
- version: 2.10.0(eslint@8.57.0)
+ version: 2.10.0(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-sonarjs:
specifier: 3.0.5
- version: 3.0.5(eslint@8.57.0)
+ version: 3.0.5(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-unicorn:
- specifier: 56.0.1
- version: 56.0.1(eslint@8.57.0)
+ specifier: 61.0.2
+ version: 61.0.2(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-vue:
specifier: 10.4.0
- version: 10.4.0(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(vue-eslint-parser@10.2.0(eslint@8.57.0))
+ version: 10.4.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1)))
eslint-plugin-vue-scoped-css:
specifier: 2.12.0
- version: 2.12.0(eslint@8.57.0)(vue-eslint-parser@10.2.0(eslint@8.57.0))
+ version: 2.12.0(eslint@9.35.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1)))
eslint-plugin-wc:
specifier: 3.0.1
- version: 3.0.1(eslint@8.57.0)
+ version: 3.0.1(eslint@9.35.0(jiti@2.5.1))
+ globals:
+ specifier: 16.4.0
+ version: 16.4.0
happy-dom:
specifier: 18.0.1
version: 18.0.1
@@ -310,8 +301,8 @@ importers:
specifier: 0.45.0
version: 0.45.0
material-icon-theme:
- specifier: 5.26.0
- version: 5.26.0
+ specifier: 5.27.0
+ version: 5.27.0
nolyfill:
specifier: 1.0.44
version: 1.0.44
@@ -336,12 +327,12 @@ importers:
svgo:
specifier: 4.0.0
version: 4.0.0
- type-fest:
- specifier: 4.41.0
- version: 4.41.0
+ typescript-eslint:
+ specifier: 8.43.0
+ version: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
updates:
- specifier: 16.6.4
- version: 16.6.4
+ specifier: 16.7.0
+ version: 16.7.0
vite-string-plugin:
specifier: 1.4.6
version: 1.4.6
@@ -475,12 +466,6 @@ packages:
'@csstools/css-parser-algorithms': ^3.0.5
'@csstools/css-tokenizer': ^3.0.4
- '@csstools/selector-resolve-nested@3.1.0':
- resolution: {integrity: sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==}
- engines: {node: '>=18'}
- peerDependencies:
- postcss-selector-parser: ^7.0.0
-
'@csstools/selector-specificity@5.0.0':
resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==}
engines: {node: '>=18'}
@@ -665,8 +650,8 @@ packages:
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
- '@eslint-community/eslint-utils@4.8.0':
- resolution: {integrity: sha512-MJQFqrZgcW0UNYLGOuQpey/oTN59vyWwplvCGZztn1cKz9agZPPYpJB7h2OMmuu7VLqkvEjN8feFZJmxNF9D+Q==}
+ '@eslint-community/eslint-utils@4.9.0':
+ resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
@@ -675,13 +660,42 @@ packages:
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- '@eslint/eslintrc@2.1.4':
- resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ '@eslint/compat@1.3.2':
+ resolution: {integrity: sha512-jRNwzTbd6p2Rw4sZ1CgWRS8YMtqG15YyZf7zvb6gY2rB2u6n+2Z+ELW0GtL0fQgyl0pr4Y/BzBfng/BdsereRA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.40 || 9
+ peerDependenciesMeta:
+ eslint:
+ optional: true
- '@eslint/js@8.57.0':
- resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ '@eslint/config-array@0.21.0':
+ resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/config-helpers@0.3.1':
+ resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/core@0.15.2':
+ resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/eslintrc@3.3.1':
+ resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/js@9.35.0':
+ resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/object-schema@2.1.6':
+ resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/plugin-kit@0.3.5':
+ resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@github/browserslist-config@1.0.0':
resolution: {integrity: sha512-gIhjdJp/c2beaIWWIlsXdqXVRUz3r2BxBCpfz/F3JXHvSAQ1paMYjLH+maEATtENg+k5eLV7gA+9yPp762ieuw==}
@@ -692,24 +706,30 @@ packages:
'@github/markdown-toolbar-element@2.2.3':
resolution: {integrity: sha512-AlquKGee+IWiAMYVB0xyHFZRMnu4n3X4HTvJHu79GiVJ1ojTukCWyxMlF5NMsecoLcBKsuBhx3QPv2vkE/zQ0A==}
+ '@github/paste-markdown@1.5.3':
+ resolution: {integrity: sha512-PzZ1b3PaqBzYqbT4fwKEhiORf38h2OcGp2+JdXNNM7inZ7egaSmfmhyNkQILpqWfS0AYtRS3CDq6z03eZ8yOMQ==}
+
'@github/relative-time-element@4.4.8':
resolution: {integrity: sha512-FSLYm6F3TSQnqHE1EMQUVVgi2XjbCvsESwwXfugHFpBnhyF1uhJOtu0Psp/BB/qqazfdkk7f5fVcu7WuXl3t8Q==}
'@github/text-expander-element@2.9.2':
resolution: {integrity: sha512-XY8EUMqM4GAloNxXNA1Py1ny+engWwYntbgsnpstQN4piaTI9rIlfYldyd0nnPXhxjGCVqHPmP6yg17Q0/n9Vg==}
- '@humanwhocodes/config-array@0.11.14':
- resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
- engines: {node: '>=10.10.0'}
- deprecated: Use @eslint/config-array instead
+ '@humanfs/core@0.19.1':
+ resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/node@0.16.7':
+ resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==}
+ engines: {node: '>=18.18.0'}
'@humanwhocodes/module-importer@1.0.1':
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
engines: {node: '>=12.22'}
- '@humanwhocodes/object-schema@2.0.3':
- resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
- deprecated: Use @eslint/object-schema instead
+ '@humanwhocodes/retry@0.4.3':
+ resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
+ engines: {node: '>=18.18'}
'@iconify/types@2.0.0':
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
@@ -876,8 +896,8 @@ packages:
'@popperjs/core@2.11.8':
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
- '@primer/octicons@19.17.0':
- resolution: {integrity: sha512-uM3ET0WC2aZMetxv7CRfIw3FexIo2fYtw2EgxqLFzLjn/rh+dIQWu781chLHh9d2mSNlxedauHLQmbYi0Dd/Mg==}
+ '@primer/octicons@19.18.0':
+ resolution: {integrity: sha512-4P8FS7slUp0vHE7zLtlfOQcgF99r0tdxpriT3ahp6iwwnf1hF3OlDWXEp5n6b6G5eIY1cNr1bCrjRL+DkRjFVw==}
'@resvg/resvg-wasm@2.6.2':
resolution: {integrity: sha512-FqALmHI8D4o6lk/LRWDnhw95z5eO+eAa6ORjVg09YRR7BkcM6oPHU9uyC0gtQG5vpFLvgpeU4+zEAz2H8APHNw==}
@@ -1116,11 +1136,11 @@ packages:
resolution: {integrity: sha512-JZlVFE6/dYpP9tQmV0/ADfn32L9uFarHWxfcRhReKUnljz1ZiUM5zpX+PH8h5CJs6lao3TuFqnPm9IJJCEkE2w==}
engines: {node: '>=10.8'}
- '@stylistic/eslint-plugin-js@3.1.0':
- resolution: {integrity: sha512-lQktsOiCr8S6StG29C5fzXYxLOD6ID1rp4j6TRS+E/qY1xd59Fm7dy5qm9UauJIEoSTlYx6yGsCHYh5UkgXPyg==}
+ '@stylistic/eslint-plugin@5.3.1':
+ resolution: {integrity: sha512-Ykums1VYonM0TgkD0VteVq9mrlO2FhF48MDJnPyv3MktIB2ydtuhlO0AfWm7xnW1kyf5bjOqA6xc7JjviuVTxg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- eslint: '>=8.40.0'
+ eslint: '>=9.0.0'
'@stylistic/stylelint-plugin@4.0.0':
resolution: {integrity: sha512-CFwt3K4Y/7bygNCLCQ8Sy4Hzgbhxq3BsNW0FIuYxl17HD3ywptm54ocyeiLVRrk5jtz1Zwks7Xr9eiZt8SWHAw==}
@@ -1280,9 +1300,6 @@ packages:
'@types/katex@0.16.7':
resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
- '@types/license-checker-webpack-plugin@0.2.5':
- resolution: {integrity: sha512-raj3YPZxjkDlRrJJUq6So+C9i/fqYxUtVZzlXxm6bwwXONOnTHvGCfYmbQhzsHJneiJdlR6mMH76/bvWbZZN8Q==}
-
'@types/markdown-escape@1.1.3':
resolution: {integrity: sha512-JIc1+s3y5ujKnt/+N+wq6s/QdL2qZ11fP79MijrVXsAAnzSxCbT2j/3prHRouJdZ2yFLN3vkP0HytfnoCczjOw==}
@@ -1298,9 +1315,6 @@ packages:
'@types/node@24.3.1':
resolution: {integrity: sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==}
- '@types/normalize-package-data@2.4.4':
- resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
-
'@types/pdfobject@2.2.5':
resolution: {integrity: sha512-7gD5tqc/RUDq0PyoLemL0vEHxBYi+zY0WVaFAx/Y0jBsXFgot1vB9No1GhDZGwRGJMCIZbgAb74QG9MTyTNU/g==}
@@ -1313,15 +1327,9 @@ packages:
'@types/sortablejs@1.15.8':
resolution: {integrity: sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==}
- '@types/source-list-map@0.1.6':
- resolution: {integrity: sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==}
-
'@types/swagger-ui-dist@3.30.6':
resolution: {integrity: sha512-FVxN7wjLYRtJsZBscOcOcf8oR++m38vbUFjT33Mr9HBuasX9bRDrJsp7iwixcOtKSHEEa2B7o2+4wEiXqC+Ebw==}
- '@types/tapable@1.0.12':
- resolution: {integrity: sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==}
-
'@types/tern@0.23.9':
resolution: {integrity: sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==}
@@ -1334,89 +1342,80 @@ packages:
'@types/toastify-js@1.12.4':
resolution: {integrity: sha512-zfZHU4tKffPCnZRe7pjv/eFKzTVHozKewFCKaCjZ4gFinKgJRz/t0bkZiMCXJxPhv/ZoeDGNOeRD09R0kQZ/nw==}
+ '@types/trusted-types@1.0.6':
+ resolution: {integrity: sha512-230RC8sFeHoT6sSUlRO6a8cAnclO06eeiq1QDfiv2FGCLWFvvERWgwIQD4FWqD9A69BN7Lzee4OXwoMVnnsWDw==}
+
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
- '@types/uglify-js@3.17.5':
- resolution: {integrity: sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==}
-
'@types/unist@2.0.11':
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
'@types/urijs@1.19.25':
resolution: {integrity: sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==}
- '@types/webpack-sources@3.2.3':
- resolution: {integrity: sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==}
-
- '@types/webpack@4.41.40':
- resolution: {integrity: sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw==}
-
'@types/whatwg-mimetype@3.0.2':
resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==}
- '@typescript-eslint/eslint-plugin@8.42.0':
- resolution: {integrity: sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==}
+ '@typescript-eslint/eslint-plugin@8.43.0':
+ resolution: {integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- '@typescript-eslint/parser': ^8.42.0
+ '@typescript-eslint/parser': ^8.43.0
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/parser@8.42.0':
- resolution: {integrity: sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==}
+ '@typescript-eslint/parser@8.43.0':
+ resolution: {integrity: sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/project-service@8.42.0':
- resolution: {integrity: sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==}
+ '@typescript-eslint/project-service@8.43.0':
+ resolution: {integrity: sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/scope-manager@8.42.0':
- resolution: {integrity: sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==}
+ '@typescript-eslint/scope-manager@8.43.0':
+ resolution: {integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/tsconfig-utils@8.42.0':
- resolution: {integrity: sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==}
+ '@typescript-eslint/tsconfig-utils@8.43.0':
+ resolution: {integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/type-utils@8.42.0':
- resolution: {integrity: sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==}
+ '@typescript-eslint/type-utils@8.43.0':
+ resolution: {integrity: sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/types@8.42.0':
- resolution: {integrity: sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==}
+ '@typescript-eslint/types@8.43.0':
+ resolution: {integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/typescript-estree@8.42.0':
- resolution: {integrity: sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==}
+ '@typescript-eslint/typescript-estree@8.43.0':
+ resolution: {integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/utils@8.42.0':
- resolution: {integrity: sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==}
+ '@typescript-eslint/utils@8.43.0':
+ resolution: {integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
- '@typescript-eslint/visitor-keys@8.42.0':
- resolution: {integrity: sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==}
+ '@typescript-eslint/visitor-keys@8.43.0':
+ resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@ungap/structured-clone@1.3.0':
- resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
-
'@unrs/resolver-binding-android-arm-eabi@1.11.1':
resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==}
cpu: [arm]
@@ -1705,11 +1704,14 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
- add-asset-webpack-plugin@3.0.0:
- resolution: {integrity: sha512-mg6nL4E+dNZPQfTc/A4xcOYsIxCN7Cuy9OScZsjI9qOYPiJeFZfsYcdoYlqcNNQEC4w8yNwArhD1Gm+G1iWrNg==}
+ add-asset-webpack-plugin@3.1.1:
+ resolution: {integrity: sha512-0WexE8uFq2hkC/rc+zVY8Hf5cKj/UwuBa0GSDKfCiKh6rrw/e7PYDgdxz1syHXIthTRlgt5q2vLvBIWcWtAvIQ==}
engines: {node: '>=18'}
peerDependencies:
webpack: '>=5'
+ peerDependenciesMeta:
+ webpack:
+ optional: true
ajv-draft-04@1.0.0:
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
@@ -1750,16 +1752,16 @@ packages:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
- ansi-regex@6.2.0:
- resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==}
+ ansi-regex@6.2.2:
+ resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
engines: {node: '>=12'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
- ansi-styles@6.2.1:
- resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ ansi-styles@6.2.3:
+ resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
ansi_up@6.0.6:
@@ -1872,6 +1874,10 @@ packages:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
engines: {node: '>=6'}
+ builtin-modules@5.0.0:
+ resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==}
+ engines: {node: '>=18.20'}
+
builtins@1.0.3:
resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==}
@@ -1905,6 +1911,9 @@ packages:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
+ change-case@5.4.4:
+ resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==}
+
character-entities-legacy@3.0.0:
resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
@@ -2349,10 +2358,6 @@ packages:
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
engines: {node: '>=0.10.0'}
- doctrine@3.0.0:
- resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
- engines: {node: '>=6.0.0'}
-
dom-input-range@2.0.1:
resolution: {integrity: sha512-UMGnuQlEepIPCju5NrPe+8y52B+pRvSjIaSPW92KpukoDGSEVkI2iaCR4HxK7K6C7zmVsWE8PEjCYZaJMr3vpg==}
@@ -2381,8 +2386,8 @@ packages:
easymde@2.20.0:
resolution: {integrity: sha512-V1Z5f92TfR42Na852OWnIZMbM7zotWQYTddNaLYZFVKj7APBbyZ3FYJ27gBw2grMW3R6Qdv9J8n5Ij7XRSIgXQ==}
- electron-to-chromium@1.5.214:
- resolution: {integrity: sha512-TpvUNdha+X3ybfU78NoQatKvQEm1oq3lf2QbnmCEdw+Bd9RuIAY+hJTvq1avzHM0f7EJfnH3vbCnbzKzisc/9Q==}
+ electron-to-chromium@1.5.215:
+ resolution: {integrity: sha512-TIvGp57UpeNetj/wV/xpFNpWGb0b/ROw372lHPx5Aafx02gjTBtWnEEcaSX3W2dLM3OSdGGyHX/cHl01JQsLaQ==}
emoji-regex@10.5.0:
resolution: {integrity: sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==}
@@ -2500,11 +2505,11 @@ packages:
eslint-import-resolver-webpack:
optional: true
- eslint-plugin-array-func@4.0.0:
- resolution: {integrity: sha512-p3NY2idNIvgmQLF2/62ZskYt8gOuUgQ51smRc3Lh7FtSozpNc2sg+lniz9VaCagLZHEZTl8qGJKqE7xy8O/D/g==}
+ eslint-plugin-array-func@5.0.2:
+ resolution: {integrity: sha512-iyLex2+pTcxHZ6OLL80oMy+CtffpJ9j6A/57VQi1VN5bK1IS/0o+mWvezDHeAlwXjn6ksRO9L5SGU329BBuY8A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
- eslint: '>=8.40.0'
+ eslint: '>=8.51.0'
eslint-plugin-escompat@3.11.4:
resolution: {integrity: sha512-j0ywwNnIufshOzgAu+PfIig1c7VRClKSNKzpniMT2vXQ4leL5q+e/SpMFQU0nrdL2WFFM44XmhSuwmxb3G0CJg==}
@@ -2522,11 +2527,11 @@ packages:
peerDependencies:
eslint: '*'
- eslint-plugin-github@5.0.2:
- resolution: {integrity: sha512-nMdzWJQ5CimjQDY6SFeJ0KIXuNFf0dgDWEd4eP3UWfuTuP/dXcZJDg7MQRvAFt743T1zUi4+/HdOihfu8xJkLA==}
+ eslint-plugin-github@6.0.0:
+ resolution: {integrity: sha512-J8MvUoiR/TU/Y9NnEmg1AnbvMUj9R6IO260z47zymMLLvso7B4c80IKjd8diqmqtSmeXXlbIus4i0SvK84flag==}
hasBin: true
peerDependencies:
- eslint: ^8.0.1
+ eslint: ^8 || ^9
eslint-plugin-i18n-text@1.0.1:
resolution: {integrity: sha512-3G3UetST6rdqhqW9SfcfzNYMpQXS7wNkJvp6dsXnjzGiku6Iu5hl3B0kmk6lIcFPwYjhQIY+tXVRtK9TlGT7RA==}
@@ -2562,18 +2567,15 @@ packages:
peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9
- eslint-plugin-no-jquery@3.1.1:
- resolution: {integrity: sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==}
- peerDependencies:
- eslint: '>=8.0.0'
-
eslint-plugin-no-only-tests@3.3.0:
resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==}
engines: {node: '>=5.0.0'}
- eslint-plugin-no-use-extend-native@0.5.0:
- resolution: {integrity: sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==}
- engines: {node: '>=6.0.0'}
+ eslint-plugin-no-use-extend-native@0.7.2:
+ resolution: {integrity: sha512-hUBlwaTXIO1GzTwPT6pAjvYwmSHe4XduDhAiQvur4RUujmBUFjd8Nb2+e7WQdsQ+nGHWGRlogcUWXJRGqizTWw==}
+ engines: {node: '>=18.18.0'}
+ peerDependencies:
+ eslint: ^9.3.0
eslint-plugin-playwright@2.2.2:
resolution: {integrity: sha512-j0jKpndIPOXRRP9uMkwb9l/nSmModOU3452nrFdgFJoEv/435J1onk8+aITzjDW8DfypxgmVaDMdmVIa6F7I0w==}
@@ -2606,11 +2608,11 @@ packages:
peerDependencies:
eslint: ^8.0.0 || ^9.0.0
- eslint-plugin-unicorn@56.0.1:
- resolution: {integrity: sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog==}
- engines: {node: '>=18.18'}
+ eslint-plugin-unicorn@61.0.2:
+ resolution: {integrity: sha512-zLihukvneYT7f74GNbVJXfWIiNQmkc/a9vYBTE4qPkQZswolWNdu+Wsp9sIXno1JOzdn6OUwLPd19ekXVkahRA==}
+ engines: {node: ^20.10.0 || >=21.0.0}
peerDependencies:
- eslint: '>=8.56.0'
+ eslint: '>=9.29.0'
eslint-plugin-vue-scoped-css@2.12.0:
resolution: {integrity: sha512-gEbuvYetNbsPA0IsmERFkVC2/vOHCInfFekNSOsAxWI/7C/bc8PoLal+fRibWfnzWryY6iL8YoluMtrEqWRj1A==}
@@ -2643,10 +2645,6 @@ packages:
resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
engines: {node: '>=8.0.0'}
- eslint-scope@7.2.2:
- resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
-
eslint-scope@8.4.0:
resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -2659,20 +2657,20 @@ packages:
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- eslint@8.57.0:
- resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
+ eslint@9.35.0:
+ resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
hasBin: true
+ peerDependencies:
+ jiti: '*'
+ peerDependenciesMeta:
+ jiti:
+ optional: true
espree@10.4.0:
resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- espree@9.6.1:
- resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
-
esquery@1.6.0:
resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
engines: {node: '>=0.10'}
@@ -2771,14 +2769,18 @@ packages:
file-entry-cache@10.1.4:
resolution: {integrity: sha512-5XRUFc0WTtUbjfGzEwXc42tiGxQHBmtbUG1h9L2apu4SulCGN3Hqm//9D6FAolf8MYNL7f/YlJl9vy08pj5JuA==}
- file-entry-cache@6.0.1:
- resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
- engines: {node: ^10.12.0 || >=12.0.0}
+ file-entry-cache@8.0.0:
+ resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
+ engines: {node: '>=16.0.0'}
fill-range@7.1.1:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
+ find-up-simple@1.0.1:
+ resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==}
+ engines: {node: '>=18'}
+
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
@@ -2787,9 +2789,9 @@ packages:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
- flat-cache@3.2.0:
- resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
- engines: {node: ^10.12.0 || >=12.0.0}
+ flat-cache@4.0.1:
+ resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
+ engines: {node: '>=16'}
flat-cache@6.1.13:
resolution: {integrity: sha512-gmtS2PaUjSPa4zjObEIn4WWliKyZzYljgxODBfxugpK6q6HU9ClXzgCJ+nlcPKY9Bt090ypTOLIFWkV0jbKFjw==}
@@ -2829,13 +2831,13 @@ packages:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
- get-east-asian-width@1.3.1:
- resolution: {integrity: sha512-R1QfovbPsKmosqTnPoRFiJ7CF9MLRgb53ChvMZm+r4p76/+8yKDy17qLL2PKInORy2RkZZekuK0efYgmzTkXyQ==}
+ get-east-asian-width@1.4.0:
+ resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==}
engines: {node: '>=18'}
- get-set-props@0.1.0:
- resolution: {integrity: sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==}
- engines: {node: '>=0.10.0'}
+ get-set-props@0.2.0:
+ resolution: {integrity: sha512-YCmOj+4YAeEB5Dd9jfp6ETdejMet4zSxXjNkgaa4npBEKRI9uDOGB5MmAdAgi2OoFGAKshYhCbmLq2DS03CgVA==}
+ engines: {node: '>=18.0.0'}
get-source@2.0.12:
resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
@@ -2879,10 +2881,18 @@ packages:
resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
engines: {node: '>=8'}
+ globals@14.0.0:
+ resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
+ engines: {node: '>=18'}
+
globals@15.15.0:
resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==}
engines: {node: '>=18'}
+ globals@16.4.0:
+ resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==}
+ engines: {node: '>=18'}
+
globby@11.1.0:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
@@ -2921,9 +2931,6 @@ packages:
hookified@1.12.0:
resolution: {integrity: sha512-hMr1Y9TCLshScrBbV2QxJ9BROddxZ12MX9KsCtuGGy/3SmmN5H1PllKerrVlSotur9dlE8hmUKAOSa3WDzsZmQ==}
- hosted-git-info@2.8.9:
- resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
-
hpagent@1.2.0:
resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==}
engines: {node: '>=14'}
@@ -2935,8 +2942,8 @@ packages:
htmlparser2@8.0.2:
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
- htmx.org@2.0.6:
- resolution: {integrity: sha512-7ythjYneGSk3yCHgtCnQeaoF+D+o7U2LF37WU3O0JYv3gTZSicdEFiI/Ai/NJyC5ZpYJWMpUb11OC5Lr6AfAqA==}
+ htmx.org@2.0.7:
+ resolution: {integrity: sha512-YiJqF3U5KyO28VC5mPfehKJPF+n1Gni+cupK+D69TF0nm7wY6AXn3a4mPWIikfAXtl1u1F1+ZhSCS7KT8pVmqA==}
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
@@ -2978,9 +2985,9 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
- indent-string@4.0.0:
- resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
- engines: {node: '>=8'}
+ indent-string@5.0.0:
+ resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
+ engines: {node: '>=12'}
inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
@@ -3023,9 +3030,9 @@ packages:
is-buffer@1.1.6:
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
- is-builtin-module@3.2.1:
- resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==}
- engines: {node: '>=6'}
+ is-builtin-module@5.0.0:
+ resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==}
+ engines: {node: '>=18.20'}
is-bun-module@2.0.0:
resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==}
@@ -3041,8 +3048,9 @@ packages:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
- is-get-set-prop@1.0.0:
- resolution: {integrity: sha512-DvAYZ1ZgGUz4lzxKMPYlt08qAUqyG9ckSg2pIjfvcQ7+pkVNUHk8yVLXOnCLe5WKXhLop8oorWFBJHpwWQpszQ==}
+ is-get-set-prop@2.0.0:
+ resolution: {integrity: sha512-C32bqXfHJfRwa0U5UIMqSGziZhALszXDJZ8n8mz8WZ6c6V7oYGHEWwJvftliBswypY3P3EQqdY5lpDSEKvTS1Q==}
+ engines: {node: '> 18.0.0'}
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
@@ -3051,19 +3059,17 @@ packages:
is-hexadecimal@2.0.1:
resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
- is-js-type@2.0.0:
- resolution: {integrity: sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==}
+ is-js-type@3.0.0:
+ resolution: {integrity: sha512-IbPf3g3vxm1D902xaBaYp2TUHiXZWwWRu5bM9hgKN9oAQcFaKALV6Gd13PGhXjKE5u2n8s1PhLhdke/E1fchxQ==}
+ engines: {node: '>=18.0.0'}
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
- is-obj-prop@1.0.0:
- resolution: {integrity: sha512-5Idb61slRlJlsAzi0Wsfwbp+zZY+9LXKUAZpvT/1ySw+NxKLRWfa0Bzj+wXI3fX5O9hiddm5c3DAaRSNP/yl2w==}
-
- is-path-inside@3.0.3:
- resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
- engines: {node: '>=8'}
+ is-obj-prop@2.0.0:
+ resolution: {integrity: sha512-2/VFrbzXSZVJIscazpxoB+pOQx2jBOAAL9Gui4cRKxflznUNBpsr8IDvBA4UGol3e40sltLNiY3qnZv/7qSUxA==}
+ engines: {node: '>=18.0.0'}
is-plain-object@2.0.4:
resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
@@ -3076,8 +3082,9 @@ packages:
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
- is-proto-prop@2.0.0:
- resolution: {integrity: sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==}
+ is-proto-prop@3.0.1:
+ resolution: {integrity: sha512-S8xSxNMGJO4eZD86kO46zrq2gLIhA+rN9443lQEvt8Mz/l8cxk72p/AWFmofY6uL9g9ILD6cXW6j8QQj4F3Hcw==}
+ engines: {node: '>=18.0.0'}
is-reference@1.2.1:
resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
@@ -3123,9 +3130,9 @@ packages:
js-tokens@9.0.1:
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
- js-types@1.0.0:
- resolution: {integrity: sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==}
- engines: {node: '>=0.10.0'}
+ js-types@4.0.0:
+ resolution: {integrity: sha512-/c+n06zvqFQGxdz1BbElF7S3nEghjNchLN1TjQnk2j10HYDaUc57rcvl6BbnziTx8NQmrg0JOs/iwRpvcYaxjQ==}
+ engines: {node: '>=18.20'}
js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
@@ -3139,8 +3146,9 @@ packages:
resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==}
engines: {node: '>= 10.16.0'}
- jsesc@0.5.0:
- resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==}
+ jsesc@3.0.2:
+ resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==}
+ engines: {node: '>=6'}
hasBin: true
jsesc@3.1.0:
@@ -3316,9 +3324,9 @@ packages:
loupe@3.2.1:
resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
- lowercase-keys@1.0.1:
- resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==}
- engines: {node: '>=0.10.0'}
+ lowercase-keys@3.0.0:
+ resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@@ -3330,8 +3338,8 @@ packages:
magic-string@0.25.9:
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
- magic-string@0.30.18:
- resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==}
+ magic-string@0.30.19:
+ resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==}
markdown-escape@2.0.0:
resolution: {integrity: sha512-Trz4v0+XWlwy68LJIyw3bLbsJiC8XAbRCKF9DbEtZjyndKOGVx6n+wNB0VfoRmY2LKboQLeniap3xrb6LGSJ8A==}
@@ -3359,8 +3367,8 @@ packages:
engines: {node: '>= 12'}
hasBin: true
- material-icon-theme@5.26.0:
- resolution: {integrity: sha512-Etrm3gMsgCRfpyqE11dDRqb3epoqxq94Pa1QEk20D7uIImneRhtsTFvhOcbKEQfMzup8IBUI1+oYrkfwIb6Xuw==}
+ material-icon-theme@5.27.0:
+ resolution: {integrity: sha512-zB3LtPY2n6z4Kp5fSc7OT8KwAZIJRvcOq6PZR4jmAkvmW1Ot+y6lNJmNqERK9rYAT42tZD1YmkhHaMcA2KEObA==}
engines: {vscode: ^1.55.0}
mathml-tag-names@2.1.3:
@@ -3476,10 +3484,6 @@ packages:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
- min-indent@1.0.1:
- resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
- engines: {node: '>=4'}
-
mini-css-extract-plugin@2.9.4:
resolution: {integrity: sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==}
engines: {node: '>= 12.13.0'}
@@ -3513,8 +3517,8 @@ packages:
monaco-editor: '>= 0.31.0'
webpack: ^4.5.0 || 5.x
- monaco-editor@0.52.2:
- resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==}
+ monaco-editor@0.53.0:
+ resolution: {integrity: sha512-0WNThgC6CMWNXXBxTbaYYcunj08iB5rnx4/G56UOPeL9UVIUGGHA1GR0EWIh9Ebabj7NpCRawQ5b0hfN1jQmYQ==}
moo@0.5.2:
resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==}
@@ -3581,9 +3585,6 @@ packages:
engines: {node: '>=12.4.0'}
hasBin: true
- normalize-package-data@2.5.0:
- resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
-
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@@ -3591,9 +3592,9 @@ packages:
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
- obj-props@1.4.0:
- resolution: {integrity: sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==}
- engines: {node: '>=0.10.0'}
+ obj-props@2.0.0:
+ resolution: {integrity: sha512-Q/uLAAfjdhrzQWN2czRNh3fDCgXjh7yRIkdHjDgIHTwpFP0BsshxTA3HRNffHR7Iw/XGTH30u8vdMXQ+079urA==}
+ engines: {node: '>=18.0.0'}
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
@@ -3820,12 +3821,6 @@ packages:
peerDependencies:
postcss: ^8.2.14
- postcss-nesting@13.0.2:
- resolution: {integrity: sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==}
- engines: {node: '>=18'}
- peerDependencies:
- postcss: ^8.4
-
postcss-resolve-nested-selector@0.1.6:
resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==}
@@ -3882,9 +3877,9 @@ packages:
printable-characters@1.0.42:
resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
- proto-props@2.0.0:
- resolution: {integrity: sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==}
- engines: {node: '>=4'}
+ prototype-properties@5.0.0:
+ resolution: {integrity: sha512-uCWE2QqnGlwvvJXTwiHTPTyHE62+zORO5hpFWhAwBGDtEtTmNZZleNLJDoFsqHCL4p/CeAP2Q1uMKFUKALuRGQ==}
+ engines: {node: '>=18.20'}
punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
@@ -3906,14 +3901,6 @@ packages:
read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
- read-pkg-up@7.0.1:
- resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
- engines: {node: '>=8'}
-
- read-pkg@5.2.0:
- resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
- engines: {node: '>=8'}
-
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
@@ -3934,8 +3921,8 @@ packages:
resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==}
hasBin: true
- regjsparser@0.10.0:
- resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==}
+ regjsparser@0.12.0:
+ resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==}
hasBin: true
rename-keys@1.2.0:
@@ -3978,11 +3965,6 @@ packages:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
- rimraf@3.0.2:
- resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
- deprecated: Rimraf versions prior to v4 are no longer supported
- hasBin: true
-
robust-predicates@3.0.2:
resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
@@ -4026,10 +4008,6 @@ packages:
resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==}
engines: {node: ^14.0.0 || >=16.0.0}
- semver@5.7.2:
- resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
- hasBin: true
-
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -4122,9 +4100,6 @@ packages:
spdx-compare@1.0.0:
resolution: {integrity: sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==}
- spdx-correct@3.2.0:
- resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
-
spdx-exceptions@2.5.0:
resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
@@ -4172,17 +4147,17 @@ packages:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
- strip-ansi@7.1.0:
- resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ strip-ansi@7.1.2:
+ resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
engines: {node: '>=12'}
strip-bom@3.0.0:
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
engines: {node: '>=4'}
- strip-indent@3.0.0:
- resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
- engines: {node: '>=8'}
+ strip-indent@4.1.0:
+ resolution: {integrity: sha512-OA95x+JPmL7kc7zCu+e+TeYxEiaIyndRx0OrBcK2QPPH09oAndr2ALvymxWA+Lx1PYYvFUm4O63pRkdJAaW96w==}
+ engines: {node: '>=12'}
strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
@@ -4268,8 +4243,8 @@ packages:
svgson@5.3.1:
resolution: {integrity: sha512-qdPgvUNWb40gWktBJnbJRelWcPzkLed/ShhnRsjbayXz8OtdPOzbil9jtiZdrYvSDumAz/VNQr6JaNfPx/gvPA==}
- swagger-ui-dist@5.28.1:
- resolution: {integrity: sha512-IvPrtNi8MvjiuDgoSmPYgg27Lvu38fnLD1OSd8Y103xXsPAqezVNnNeHnVCZ/d+CMXJblflGaIyHxAYIF3O71w==}
+ swagger-ui-dist@5.29.0:
+ resolution: {integrity: sha512-gqs7Md3AxP4mbpXAq31o5QW+wGUZsUzVatg70yXpUR245dfIis5jAzufBd+UQM/w2xSfrhvA1eqsrgnl2PbezQ==}
sync-fetch@0.4.5:
resolution: {integrity: sha512-esiWJ7ixSKGpd9DJPBTC4ckChqdOjIwJfYhVHkcQ2Gnm41323p1TRmEI+esTQ9ppD+b5opps2OTEGTCGX5kF+g==}
@@ -4404,17 +4379,12 @@ packages:
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
engines: {node: '>=10'}
- type-fest@0.6.0:
- resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
- engines: {node: '>=8'}
-
- type-fest@0.8.1:
- resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
- engines: {node: '>=8'}
-
- type-fest@4.41.0:
- resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
- engines: {node: '>=16'}
+ typescript-eslint@8.43.0:
+ resolution: {integrity: sha512-FyRGJKUGvcFekRRcBKFBlAhnp4Ng8rhe8tuvvkR9OiU0gfd4vyvTRQHEckO6VDlH57jbeUQem2IpqPq9kLJH+w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <6.0.0'
typescript@5.9.2:
resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==}
@@ -4452,8 +4422,8 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
- updates@16.6.4:
- resolution: {integrity: sha512-HHJH9SBWJr/1+iSLuS1txaq4bz2q/ENK4KHRhcTgOgJEUeBnmLeF5/0nQya9vGnRGLnrXacuAk+pTAzKuOs9ng==}
+ updates@16.7.0:
+ resolution: {integrity: sha512-GOqKdZREAlOR90YBBY8FpkmJOPjjxntYcuAKZRWXK5Pvt2CAcPREk+KeqClG3yqqk+NGWkqAsIxa1ORzQB1iQA==}
engines: {node: '>=20'}
hasBin: true
@@ -4474,9 +4444,6 @@ packages:
resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
hasBin: true
- validate-npm-package-license@3.0.4:
- resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
-
validate-npm-package-name@3.0.0:
resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==}
@@ -4491,8 +4458,8 @@ packages:
vite-string-plugin@1.4.6:
resolution: {integrity: sha512-Csjtny8/uVIynzlaRRj4RpHrPAakNwlH9jw6kgQ8tQhc2f0zzA6bCbAgWD0y84EgB8aLNrz7pZFUqSt3LOtk+w==}
- vite@7.1.4:
- resolution: {integrity: sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw==}
+ vite@7.1.5:
+ resolution: {integrity: sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -4705,8 +4672,8 @@ packages:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
- wrap-ansi@9.0.0:
- resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
+ wrap-ansi@9.0.2:
+ resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
engines: {node: '>=18'}
wrappy@1.0.2:
@@ -4871,10 +4838,6 @@ snapshots:
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
'@csstools/css-tokenizer': 3.0.4
- '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.0)':
- dependencies:
- postcss-selector-parser: 7.1.0
-
'@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.0)':
dependencies:
postcss-selector-parser: 7.1.0
@@ -4977,25 +4940,43 @@ snapshots:
'@esbuild/win32-x64@0.25.9':
optional: true
- '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@8.57.0)':
+ '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@9.35.0(jiti@2.5.1))':
dependencies:
escape-string-regexp: 4.0.0
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
ignore: 5.3.2
- '@eslint-community/eslint-utils@4.8.0(eslint@8.57.0)':
+ '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0(jiti@2.5.1))':
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.1': {}
- '@eslint/eslintrc@2.1.4':
+ '@eslint/compat@1.3.2(eslint@9.35.0(jiti@2.5.1))':
+ optionalDependencies:
+ eslint: 9.35.0(jiti@2.5.1)
+
+ '@eslint/config-array@0.21.0':
+ dependencies:
+ '@eslint/object-schema': 2.1.6
+ debug: 4.4.1
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/config-helpers@0.3.1': {}
+
+ '@eslint/core@0.15.2':
+ dependencies:
+ '@types/json-schema': 7.0.15
+
+ '@eslint/eslintrc@3.3.1':
dependencies:
ajv: 6.12.6
debug: 4.4.1
- espree: 9.6.1
- globals: 13.24.0
+ espree: 10.4.0
+ globals: 14.0.0
ignore: 5.3.2
import-fresh: 3.3.1
js-yaml: 4.1.0
@@ -5004,7 +4985,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@eslint/js@8.57.0': {}
+ '@eslint/js@9.35.0': {}
+
+ '@eslint/object-schema@2.1.6': {}
+
+ '@eslint/plugin-kit@0.3.5':
+ dependencies:
+ '@eslint/core': 0.15.2
+ levn: 0.4.1
'@github/browserslist-config@1.0.0': {}
@@ -5012,6 +5000,8 @@ snapshots:
'@github/markdown-toolbar-element@2.2.3': {}
+ '@github/paste-markdown@1.5.3': {}
+
'@github/relative-time-element@4.4.8': {}
'@github/text-expander-element@2.9.2':
@@ -5019,17 +5009,16 @@ snapshots:
'@github/combobox-nav': 2.3.1
dom-input-range: 2.0.1
- '@humanwhocodes/config-array@0.11.14':
+ '@humanfs/core@0.19.1': {}
+
+ '@humanfs/node@0.16.7':
dependencies:
- '@humanwhocodes/object-schema': 2.0.3
- debug: 4.4.1
- minimatch: 3.1.2
- transitivePeerDependencies:
- - supports-color
+ '@humanfs/core': 0.19.1
+ '@humanwhocodes/retry': 0.4.3
'@humanwhocodes/module-importer@1.0.1': {}
- '@humanwhocodes/object-schema@2.0.3': {}
+ '@humanwhocodes/retry@0.4.3': {}
'@iconify/types@2.0.0': {}
@@ -5056,7 +5045,7 @@ snapshots:
dependencies:
string-width: 5.1.2
string-width-cjs: string-width@4.2.3
- strip-ansi: 7.1.0
+ strip-ansi: 7.1.2
strip-ansi-cjs: strip-ansi@6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
@@ -5192,7 +5181,7 @@ snapshots:
'@popperjs/core@2.11.8': {}
- '@primer/octicons@19.17.0':
+ '@primer/octicons@19.18.0':
dependencies:
object-assign: 4.1.1
@@ -5549,11 +5538,15 @@ snapshots:
'@stoplight/yaml-ast-parser': 0.0.50
tslib: 2.8.1
- '@stylistic/eslint-plugin-js@3.1.0(eslint@8.57.0)':
+ '@stylistic/eslint-plugin@5.3.1(eslint@9.35.0(jiti@2.5.1))':
dependencies:
- eslint: 8.57.0
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
+ '@typescript-eslint/types': 8.43.0
+ eslint: 9.35.0(jiti@2.5.1)
eslint-visitor-keys: 4.2.1
espree: 10.4.0
+ estraverse: 5.3.0
+ picomatch: 4.0.3
'@stylistic/stylelint-plugin@4.0.0(stylelint@16.24.0(typescript@5.9.2))':
dependencies:
@@ -5753,10 +5746,6 @@ snapshots:
'@types/katex@0.16.7': {}
- '@types/license-checker-webpack-plugin@0.2.5':
- dependencies:
- '@types/webpack': 4.41.40
-
'@types/markdown-escape@1.1.3': {}
'@types/marked@4.3.2': {}
@@ -5771,8 +5760,6 @@ snapshots:
dependencies:
undici-types: 7.10.0
- '@types/normalize-package-data@2.4.4': {}
-
'@types/pdfobject@2.2.5': {}
'@types/sarif@2.1.7': {}
@@ -5781,12 +5768,8 @@ snapshots:
'@types/sortablejs@1.15.8': {}
- '@types/source-list-map@0.1.6': {}
-
'@types/swagger-ui-dist@3.30.6': {}
- '@types/tapable@1.0.12': {}
-
'@types/tern@0.23.9':
dependencies:
'@types/estree': 1.0.8
@@ -5797,43 +5780,26 @@ snapshots:
'@types/toastify-js@1.12.4': {}
+ '@types/trusted-types@1.0.6': {}
+
'@types/trusted-types@2.0.7':
optional: true
- '@types/uglify-js@3.17.5':
- dependencies:
- source-map: 0.6.1
-
'@types/unist@2.0.11': {}
'@types/urijs@1.19.25': {}
- '@types/webpack-sources@3.2.3':
- dependencies:
- '@types/node': 24.3.1
- '@types/source-list-map': 0.1.6
- source-map: 0.7.6
-
- '@types/webpack@4.41.40':
- dependencies:
- '@types/node': 24.3.1
- '@types/tapable': 1.0.12
- '@types/uglify-js': 3.17.5
- '@types/webpack-sources': 3.2.3
- anymatch: 3.1.3
- source-map: 0.6.1
-
'@types/whatwg-mimetype@3.0.2': {}
- '@typescript-eslint/eslint-plugin@8.42.0(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(typescript@5.9.2)':
+ '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)':
dependencies:
'@eslint-community/regexpp': 4.12.1
- '@typescript-eslint/parser': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
- '@typescript-eslint/scope-manager': 8.42.0
- '@typescript-eslint/type-utils': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
- '@typescript-eslint/utils': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
- '@typescript-eslint/visitor-keys': 8.42.0
- eslint: 8.57.0
+ '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ '@typescript-eslint/scope-manager': 8.43.0
+ '@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ '@typescript-eslint/visitor-keys': 8.43.0
+ eslint: 9.35.0(jiti@2.5.1)
graphemer: 1.4.0
ignore: 7.0.5
natural-compare: 1.4.0
@@ -5842,56 +5808,56 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2)':
+ '@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)':
dependencies:
- '@typescript-eslint/scope-manager': 8.42.0
- '@typescript-eslint/types': 8.42.0
- '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2)
- '@typescript-eslint/visitor-keys': 8.42.0
+ '@typescript-eslint/scope-manager': 8.43.0
+ '@typescript-eslint/types': 8.43.0
+ '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
+ '@typescript-eslint/visitor-keys': 8.43.0
debug: 4.4.1
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
typescript: 5.9.2
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/project-service@8.42.0(typescript@5.9.2)':
+ '@typescript-eslint/project-service@8.43.0(typescript@5.9.2)':
dependencies:
- '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2)
- '@typescript-eslint/types': 8.42.0
+ '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2)
+ '@typescript-eslint/types': 8.43.0
debug: 4.4.1
typescript: 5.9.2
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/scope-manager@8.42.0':
+ '@typescript-eslint/scope-manager@8.43.0':
dependencies:
- '@typescript-eslint/types': 8.42.0
- '@typescript-eslint/visitor-keys': 8.42.0
+ '@typescript-eslint/types': 8.43.0
+ '@typescript-eslint/visitor-keys': 8.43.0
- '@typescript-eslint/tsconfig-utils@8.42.0(typescript@5.9.2)':
+ '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.9.2)':
dependencies:
typescript: 5.9.2
- '@typescript-eslint/type-utils@8.42.0(eslint@8.57.0)(typescript@5.9.2)':
+ '@typescript-eslint/type-utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)':
dependencies:
- '@typescript-eslint/types': 8.42.0
- '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2)
- '@typescript-eslint/utils': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
+ '@typescript-eslint/types': 8.43.0
+ '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
+ '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
debug: 4.4.1
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
ts-api-utils: 2.1.0(typescript@5.9.2)
typescript: 5.9.2
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/types@8.42.0': {}
+ '@typescript-eslint/types@8.43.0': {}
- '@typescript-eslint/typescript-estree@8.42.0(typescript@5.9.2)':
+ '@typescript-eslint/typescript-estree@8.43.0(typescript@5.9.2)':
dependencies:
- '@typescript-eslint/project-service': 8.42.0(typescript@5.9.2)
- '@typescript-eslint/tsconfig-utils': 8.42.0(typescript@5.9.2)
- '@typescript-eslint/types': 8.42.0
- '@typescript-eslint/visitor-keys': 8.42.0
+ '@typescript-eslint/project-service': 8.43.0(typescript@5.9.2)
+ '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2)
+ '@typescript-eslint/types': 8.43.0
+ '@typescript-eslint/visitor-keys': 8.43.0
debug: 4.4.1
fast-glob: 3.3.3
is-glob: 4.0.3
@@ -5902,24 +5868,22 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.42.0(eslint@8.57.0)(typescript@5.9.2)':
+ '@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)':
dependencies:
- '@eslint-community/eslint-utils': 4.8.0(eslint@8.57.0)
- '@typescript-eslint/scope-manager': 8.42.0
- '@typescript-eslint/types': 8.42.0
- '@typescript-eslint/typescript-estree': 8.42.0(typescript@5.9.2)
- eslint: 8.57.0
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
+ '@typescript-eslint/scope-manager': 8.43.0
+ '@typescript-eslint/types': 8.43.0
+ '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
+ eslint: 9.35.0(jiti@2.5.1)
typescript: 5.9.2
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/visitor-keys@8.42.0':
+ '@typescript-eslint/visitor-keys@8.43.0':
dependencies:
- '@typescript-eslint/types': 8.42.0
+ '@typescript-eslint/types': 8.43.0
eslint-visitor-keys: 4.2.1
- '@ungap/structured-clone@1.3.0': {}
-
'@unrs/resolver-binding-android-arm-eabi@1.11.1':
optional: true
@@ -5979,17 +5943,17 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.11.1':
optional: true
- '@vitejs/plugin-vue@6.0.1(vite@7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2))':
+ '@vitejs/plugin-vue@6.0.1(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))(vue@3.5.21(typescript@5.9.2))':
dependencies:
'@rolldown/pluginutils': 1.0.0-beta.29
- vite: 7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
+ vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
vue: 3.5.21(typescript@5.9.2)
- '@vitest/eslint-plugin@1.3.9(eslint@8.57.0)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))':
+ '@vitest/eslint-plugin@1.3.9(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))':
dependencies:
- '@typescript-eslint/scope-manager': 8.42.0
- '@typescript-eslint/utils': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
- eslint: 8.57.0
+ '@typescript-eslint/scope-manager': 8.43.0
+ '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ eslint: 9.35.0(jiti@2.5.1)
optionalDependencies:
typescript: 5.9.2
vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(happy-dom@18.0.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
@@ -6004,13 +5968,13 @@ snapshots:
chai: 5.3.3
tinyrainbow: 2.0.0
- '@vitest/mocker@3.2.4(vite@7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))':
+ '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))':
dependencies:
'@vitest/spy': 3.2.4
estree-walker: 3.0.3
- magic-string: 0.30.18
+ magic-string: 0.30.19
optionalDependencies:
- vite: 7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
+ vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
'@vitest/pretty-format@3.2.4':
dependencies:
@@ -6025,7 +5989,7 @@ snapshots:
'@vitest/snapshot@3.2.4':
dependencies:
'@vitest/pretty-format': 3.2.4
- magic-string: 0.30.18
+ magic-string: 0.30.19
pathe: 2.0.3
'@vitest/spy@3.2.4':
@@ -6071,7 +6035,7 @@ snapshots:
'@vue/compiler-ssr': 3.5.21
'@vue/shared': 3.5.21
estree-walker: 2.0.2
- magic-string: 0.30.18
+ magic-string: 0.30.19
postcss: 8.5.6
source-map-js: 1.2.1
@@ -6231,8 +6195,8 @@ snapshots:
acorn@8.15.0: {}
- add-asset-webpack-plugin@3.0.0(webpack@5.101.3):
- dependencies:
+ add-asset-webpack-plugin@3.1.1(webpack@5.101.3):
+ optionalDependencies:
webpack: 5.101.3(webpack-cli@6.0.1)
ajv-draft-04@1.0.0(ajv@8.17.1):
@@ -6270,13 +6234,13 @@ snapshots:
ansi-regex@5.0.1: {}
- ansi-regex@6.2.0: {}
+ ansi-regex@6.2.2: {}
ansi-styles@4.3.0:
dependencies:
color-convert: 2.0.1
- ansi-styles@6.2.1: {}
+ ansi-styles@6.2.3: {}
ansi_up@6.0.6: {}
@@ -6352,7 +6316,7 @@ snapshots:
browserslist@4.25.4:
dependencies:
caniuse-lite: 1.0.30001741
- electron-to-chromium: 1.5.214
+ electron-to-chromium: 1.5.215
node-releases: 2.0.20
update-browserslist-db: 1.1.3(browserslist@4.25.4)
@@ -6365,6 +6329,8 @@ snapshots:
builtin-modules@3.3.0: {}
+ builtin-modules@5.0.0: {}
+
builtins@1.0.3: {}
bytes@3.1.2: {}
@@ -6395,6 +6361,8 @@ snapshots:
ansi-styles: 4.3.0
supports-color: 7.2.0
+ change-case@5.4.4: {}
+
character-entities-legacy@3.0.0: {}
character-entities@2.0.2: {}
@@ -6837,10 +6805,6 @@ snapshots:
dependencies:
esutils: 2.0.3
- doctrine@3.0.0:
- dependencies:
- esutils: 2.0.3
-
dom-input-range@2.0.1: {}
dom-serializer@2.0.0:
@@ -6880,7 +6844,7 @@ snapshots:
codemirror-spell-checker: 1.1.2
marked: 4.3.0
- electron-to-chromium@1.5.214: {}
+ electron-to-chromium@1.5.215: {}
emoji-regex@10.5.0: {}
@@ -6950,14 +6914,14 @@ snapshots:
escape-string-regexp@4.0.0: {}
- eslint-compat-utils@0.6.5(eslint@8.57.0):
+ eslint-compat-utils@0.6.5(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
semver: 7.7.2
- eslint-config-prettier@10.1.8(eslint@8.57.0):
+ eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
eslint-import-context@0.1.9(unrs-resolver@1.11.1):
dependencies:
@@ -6974,10 +6938,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0))(eslint-plugin-import@2.32.0)(eslint@8.57.0):
+ eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1)):
dependencies:
debug: 4.4.1
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
eslint-import-context: 0.1.9(unrs-resolver@1.11.1)
get-tsconfig: 4.10.1
is-bun-module: 2.0.0
@@ -6985,82 +6949,87 @@ snapshots:
tinyglobby: 0.2.15
unrs-resolver: 1.11.1
optionalDependencies:
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0)
- eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0(jiti@2.5.1))
+ eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0(jiti@2.5.1))
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.1(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0):
+ eslint-module-utils@2.12.1(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0(jiti@2.5.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
- '@typescript-eslint/parser': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
- eslint: 8.57.0
+ '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ eslint: 9.35.0(jiti@2.5.1)
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0))(eslint-plugin-import@2.32.0)(eslint@8.57.0)
+ eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0(jiti@2.5.1)))(eslint-plugin-import@2.32.0)(eslint@9.35.0(jiti@2.5.1))
transitivePeerDependencies:
- supports-color
- eslint-plugin-array-func@4.0.0(eslint@8.57.0):
+ eslint-plugin-array-func@5.0.2(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
- eslint-plugin-escompat@3.11.4(eslint@8.57.0):
+ eslint-plugin-escompat@3.11.4(eslint@9.35.0(jiti@2.5.1)):
dependencies:
browserslist: 4.25.4
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
- eslint-plugin-eslint-comments@3.2.0(eslint@8.57.0):
+ eslint-plugin-eslint-comments@3.2.0(eslint@9.35.0(jiti@2.5.1)):
dependencies:
escape-string-regexp: 1.0.5
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
ignore: 5.3.2
- eslint-plugin-filenames@1.3.2(eslint@8.57.0):
+ eslint-plugin-filenames@1.3.2(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
lodash.camelcase: 4.3.0
lodash.kebabcase: 4.1.1
lodash.snakecase: 4.1.1
lodash.upperfirst: 4.3.1
- eslint-plugin-github@5.0.2(@types/eslint@9.6.1)(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0)(typescript@5.9.2):
+ eslint-plugin-github@6.0.0(@types/eslint@9.6.1)(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0(jiti@2.5.1)):
dependencies:
+ '@eslint/compat': 1.3.2(eslint@9.35.0(jiti@2.5.1))
+ '@eslint/eslintrc': 3.3.1
+ '@eslint/js': 9.35.0
'@github/browserslist-config': 1.0.0
- '@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(typescript@5.9.2)
- '@typescript-eslint/parser': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
+ '@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
aria-query: 5.3.2
- eslint: 8.57.0
- eslint-config-prettier: 10.1.8(eslint@8.57.0)
- eslint-plugin-escompat: 3.11.4(eslint@8.57.0)
- eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0)
- eslint-plugin-filenames: 1.3.2(eslint@8.57.0)
- eslint-plugin-i18n-text: 1.0.1(eslint@8.57.0)
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0)
- eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0)
+ eslint: 9.35.0(jiti@2.5.1)
+ eslint-config-prettier: 10.1.8(eslint@9.35.0(jiti@2.5.1))
+ eslint-plugin-escompat: 3.11.4(eslint@9.35.0(jiti@2.5.1))
+ eslint-plugin-eslint-comments: 3.2.0(eslint@9.35.0(jiti@2.5.1))
+ eslint-plugin-filenames: 1.3.2(eslint@9.35.0(jiti@2.5.1))
+ eslint-plugin-i18n-text: 1.0.1(eslint@9.35.0(jiti@2.5.1))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0(jiti@2.5.1))
+ eslint-plugin-jsx-a11y: 6.10.2(eslint@9.35.0(jiti@2.5.1))
eslint-plugin-no-only-tests: 3.3.0
- eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@8.57.0))(eslint@8.57.0)(prettier@3.6.2)
+ eslint-plugin-prettier: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(prettier@3.6.2)
eslint-rule-documentation: 1.0.23
+ globals: 16.4.0
jsx-ast-utils: 3.3.5
prettier: 3.6.2
svg-element-attributes: 1.3.1
+ typescript: 5.9.2
+ typescript-eslint: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
transitivePeerDependencies:
- '@types/eslint'
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
- - typescript
- eslint-plugin-i18n-text@1.0.1(eslint@8.57.0):
+ eslint-plugin-i18n-text@1.0.1(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
- eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
+ eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- '@typescript-eslint/types': 8.42.0
+ '@typescript-eslint/types': 8.43.0
comment-parser: 1.4.1
debug: 4.4.1
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
eslint-import-context: 0.1.9(unrs-resolver@1.11.1)
is-glob: 4.0.3
minimatch: 10.0.3
@@ -7068,12 +7037,12 @@ snapshots:
stable-hash-x: 0.2.0
unrs-resolver: 1.11.1
optionalDependencies:
- '@typescript-eslint/utils': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
+ '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
eslint-import-resolver-node: 0.3.9
transitivePeerDependencies:
- supports-color
- eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0):
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0(jiti@2.5.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: '@nolyfill/array-includes@1.0.44'
@@ -7082,9 +7051,9 @@ snapshots:
array.prototype.flatmap: '@nolyfill/array.prototype.flatmap@1.0.44'
debug: 3.2.7
doctrine: 2.1.0
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@8.57.0)
+ eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.35.0(jiti@2.5.1))
hasown: '@nolyfill/hasown@1.0.44'
is-core-module: '@nolyfill/is-core-module@1.0.39'
is-glob: 4.0.3
@@ -7096,13 +7065,13 @@ snapshots:
string.prototype.trimend: '@nolyfill/string.prototype.trimend@1.0.44'
tsconfig-paths: 3.15.0
optionalDependencies:
- '@typescript-eslint/parser': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
+ '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.0):
+ eslint-plugin-jsx-a11y@6.10.2(eslint@9.35.0(jiti@2.5.1)):
dependencies:
aria-query: 5.3.2
array-includes: '@nolyfill/array-includes@1.0.44'
@@ -7112,7 +7081,7 @@ snapshots:
axobject-query: 4.1.0
damerau-levenshtein: 1.0.8
emoji-regex: 9.2.2
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
hasown: '@nolyfill/hasown@1.0.44'
jsx-ast-utils: 3.3.5
language-tags: 1.0.9
@@ -7121,51 +7090,48 @@ snapshots:
safe-regex-test: '@nolyfill/safe-regex-test@1.0.44'
string.prototype.includes: '@nolyfill/string.prototype.includes@1.0.44'
- eslint-plugin-no-jquery@3.1.1(eslint@8.57.0):
- dependencies:
- eslint: 8.57.0
-
eslint-plugin-no-only-tests@3.3.0: {}
- eslint-plugin-no-use-extend-native@0.5.0:
+ eslint-plugin-no-use-extend-native@0.7.2(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- is-get-set-prop: 1.0.0
- is-js-type: 2.0.0
- is-obj-prop: 1.0.0
- is-proto-prop: 2.0.0
+ eslint: 9.35.0(jiti@2.5.1)
+ is-get-set-prop: 2.0.0
+ is-js-type: 3.0.0
+ is-obj-prop: 2.0.0
+ is-proto-prop: 3.0.1
- eslint-plugin-playwright@2.2.2(eslint@8.57.0):
+ eslint-plugin-playwright@2.2.2(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
globals: 13.24.0
- eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@8.57.0))(eslint@8.57.0)(prettier@3.6.2):
+ eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(prettier@3.6.2):
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
prettier: 3.6.2
prettier-linter-helpers: 1.0.0
synckit: 0.11.11
optionalDependencies:
'@types/eslint': 9.6.1
- eslint-config-prettier: 10.1.8(eslint@8.57.0)
+ eslint-config-prettier: 10.1.8(eslint@9.35.0(jiti@2.5.1))
- eslint-plugin-regexp@2.10.0(eslint@8.57.0):
+ eslint-plugin-regexp@2.10.0(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- '@eslint-community/eslint-utils': 4.8.0(eslint@8.57.0)
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
'@eslint-community/regexpp': 4.12.1
comment-parser: 1.4.1
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
jsdoc-type-pratt-parser: 4.8.0
refa: 0.12.1
regexp-ast-analysis: 0.7.1
scslre: 0.3.0
- eslint-plugin-sonarjs@3.0.5(eslint@8.57.0):
+ eslint-plugin-sonarjs@3.0.5(eslint@9.35.0(jiti@2.5.1)):
dependencies:
'@eslint-community/regexpp': 4.12.1
builtin-modules: 3.3.0
bytes: 3.1.2
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
functional-red-black-tree: 1.0.1
jsx-ast-utils-x: 0.1.0
lodash.merge: 4.6.2
@@ -7174,57 +7140,59 @@ snapshots:
semver: 7.7.2
typescript: 5.9.2
- eslint-plugin-unicorn@56.0.1(eslint@8.57.0):
+ eslint-plugin-unicorn@61.0.2(eslint@9.35.0(jiti@2.5.1)):
dependencies:
'@babel/helper-validator-identifier': 7.27.1
- '@eslint-community/eslint-utils': 4.8.0(eslint@8.57.0)
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
+ '@eslint/plugin-kit': 0.3.5
+ change-case: 5.4.4
ci-info: 4.3.0
clean-regexp: 1.0.0
core-js-compat: 3.45.1
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
esquery: 1.6.0
- globals: 15.15.0
- indent-string: 4.0.0
- is-builtin-module: 3.2.1
+ find-up-simple: 1.0.1
+ globals: 16.4.0
+ indent-string: 5.0.0
+ is-builtin-module: 5.0.0
jsesc: 3.1.0
pluralize: 8.0.0
- read-pkg-up: 7.0.1
regexp-tree: 0.1.27
- regjsparser: 0.10.0
+ regjsparser: 0.12.0
semver: 7.7.2
- strip-indent: 3.0.0
+ strip-indent: 4.1.0
- eslint-plugin-vue-scoped-css@2.12.0(eslint@8.57.0)(vue-eslint-parser@10.2.0(eslint@8.57.0)):
+ eslint-plugin-vue-scoped-css@2.12.0(eslint@9.35.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1))):
dependencies:
- '@eslint-community/eslint-utils': 4.8.0(eslint@8.57.0)
- eslint: 8.57.0
- eslint-compat-utils: 0.6.5(eslint@8.57.0)
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
+ eslint: 9.35.0(jiti@2.5.1)
+ eslint-compat-utils: 0.6.5(eslint@9.35.0(jiti@2.5.1))
lodash: 4.17.21
postcss: 8.5.6
postcss-safe-parser: 6.0.0(postcss@8.5.6)
postcss-scss: 4.0.9(postcss@8.5.6)
postcss-selector-parser: 7.1.0
postcss-styl: 0.12.3
- vue-eslint-parser: 10.2.0(eslint@8.57.0)
+ vue-eslint-parser: 10.2.0(eslint@9.35.0(jiti@2.5.1))
transitivePeerDependencies:
- supports-color
- eslint-plugin-vue@10.4.0(@typescript-eslint/parser@8.42.0(eslint@8.57.0)(typescript@5.9.2))(eslint@8.57.0)(vue-eslint-parser@10.2.0(eslint@8.57.0)):
+ eslint-plugin-vue@10.4.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1))):
dependencies:
- '@eslint-community/eslint-utils': 4.8.0(eslint@8.57.0)
- eslint: 8.57.0
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
+ eslint: 9.35.0(jiti@2.5.1)
natural-compare: 1.4.0
nth-check: 2.1.1
postcss-selector-parser: 6.1.2
semver: 7.7.2
- vue-eslint-parser: 10.2.0(eslint@8.57.0)
+ vue-eslint-parser: 10.2.0(eslint@9.35.0(jiti@2.5.1))
xml-name-validator: 4.0.0
optionalDependencies:
- '@typescript-eslint/parser': 8.42.0(eslint@8.57.0)(typescript@5.9.2)
+ '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
- eslint-plugin-wc@3.0.1(eslint@8.57.0):
+ eslint-plugin-wc@3.0.1(eslint@9.35.0(jiti@2.5.1)):
dependencies:
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
is-valid-element-name: 1.0.0
js-levenshtein-esm: 2.0.0
@@ -7235,11 +7203,6 @@ snapshots:
esrecurse: 4.3.0
estraverse: 4.3.0
- eslint-scope@7.2.2:
- dependencies:
- esrecurse: 4.3.0
- estraverse: 5.3.0
-
eslint-scope@8.4.0:
dependencies:
esrecurse: 4.3.0
@@ -7249,46 +7212,45 @@ snapshots:
eslint-visitor-keys@4.2.1: {}
- eslint@8.57.0:
+ eslint@9.35.0(jiti@2.5.1):
dependencies:
- '@eslint-community/eslint-utils': 4.8.0(eslint@8.57.0)
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1))
'@eslint-community/regexpp': 4.12.1
- '@eslint/eslintrc': 2.1.4
- '@eslint/js': 8.57.0
- '@humanwhocodes/config-array': 0.11.14
+ '@eslint/config-array': 0.21.0
+ '@eslint/config-helpers': 0.3.1
+ '@eslint/core': 0.15.2
+ '@eslint/eslintrc': 3.3.1
+ '@eslint/js': 9.35.0
+ '@eslint/plugin-kit': 0.3.5
+ '@humanfs/node': 0.16.7
'@humanwhocodes/module-importer': 1.0.1
- '@nodelib/fs.walk': 1.2.8
- '@ungap/structured-clone': 1.3.0
+ '@humanwhocodes/retry': 0.4.3
+ '@types/estree': 1.0.8
+ '@types/json-schema': 7.0.15
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.6
debug: 4.4.1
- doctrine: 3.0.0
escape-string-regexp: 4.0.0
- eslint-scope: 7.2.2
- eslint-visitor-keys: 3.4.3
- espree: 9.6.1
+ eslint-scope: 8.4.0
+ eslint-visitor-keys: 4.2.1
+ espree: 10.4.0
esquery: 1.6.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
- file-entry-cache: 6.0.1
+ file-entry-cache: 8.0.0
find-up: 5.0.0
glob-parent: 6.0.2
- globals: 13.24.0
- graphemer: 1.4.0
ignore: 5.3.2
imurmurhash: 0.1.4
is-glob: 4.0.3
- is-path-inside: 3.0.3
- js-yaml: 4.1.0
json-stable-stringify-without-jsonify: 1.0.1
- levn: 0.4.1
lodash.merge: 4.6.2
minimatch: 3.1.2
natural-compare: 1.4.0
optionator: 0.9.4
- strip-ansi: 6.0.1
- text-table: 0.2.0
+ optionalDependencies:
+ jiti: 2.5.1
transitivePeerDependencies:
- supports-color
@@ -7298,12 +7260,6 @@ snapshots:
acorn-jsx: 5.3.2(acorn@8.15.0)
eslint-visitor-keys: 4.2.1
- espree@9.6.1:
- dependencies:
- acorn: 8.15.0
- acorn-jsx: 5.3.2(acorn@8.15.0)
- eslint-visitor-keys: 3.4.3
-
esquery@1.6.0:
dependencies:
estraverse: 5.3.0
@@ -7386,14 +7342,16 @@ snapshots:
dependencies:
flat-cache: 6.1.13
- file-entry-cache@6.0.1:
+ file-entry-cache@8.0.0:
dependencies:
- flat-cache: 3.2.0
+ flat-cache: 4.0.1
fill-range@7.1.1:
dependencies:
to-regex-range: 5.0.1
+ find-up-simple@1.0.1: {}
+
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
@@ -7404,11 +7362,10 @@ snapshots:
locate-path: 6.0.0
path-exists: 4.0.0
- flat-cache@3.2.0:
+ flat-cache@4.0.1:
dependencies:
flatted: 3.3.3
keyv: 4.5.4
- rimraf: 3.0.2
flat-cache@6.1.13:
dependencies:
@@ -7443,9 +7400,9 @@ snapshots:
get-caller-file@2.0.5: {}
- get-east-asian-width@1.3.1: {}
+ get-east-asian-width@1.4.0: {}
- get-set-props@0.1.0: {}
+ get-set-props@0.2.0: {}
get-source@2.0.12:
dependencies:
@@ -7507,8 +7464,12 @@ snapshots:
dependencies:
type-fest: 0.20.2
+ globals@14.0.0: {}
+
globals@15.15.0: {}
+ globals@16.4.0: {}
+
globby@11.1.0:
dependencies:
array-union: 2.1.0
@@ -7542,8 +7503,6 @@ snapshots:
hookified@1.12.0: {}
- hosted-git-info@2.8.9: {}
-
hpagent@1.2.0: {}
html-tags@3.3.1: {}
@@ -7555,7 +7514,7 @@ snapshots:
domutils: 3.2.2
entities: 4.5.0
- htmx.org@2.0.6: {}
+ htmx.org@2.0.7: {}
iconv-lite@0.6.3:
dependencies:
@@ -7587,7 +7546,7 @@ snapshots:
imurmurhash@0.1.4: {}
- indent-string@4.0.0: {}
+ indent-string@5.0.0: {}
inflight@1.0.6:
dependencies:
@@ -7621,9 +7580,9 @@ snapshots:
is-buffer@1.1.6: {}
- is-builtin-module@3.2.1:
+ is-builtin-module@5.0.0:
dependencies:
- builtin-modules: 3.3.0
+ builtin-modules: 5.0.0
is-bun-module@2.0.0:
dependencies:
@@ -7635,10 +7594,10 @@ snapshots:
is-fullwidth-code-point@3.0.0: {}
- is-get-set-prop@1.0.0:
+ is-get-set-prop@2.0.0:
dependencies:
- get-set-props: 0.1.0
- lowercase-keys: 1.0.1
+ get-set-props: 0.2.0
+ lowercase-keys: 3.0.0
is-glob@4.0.3:
dependencies:
@@ -7646,18 +7605,16 @@ snapshots:
is-hexadecimal@2.0.1: {}
- is-js-type@2.0.0:
+ is-js-type@3.0.0:
dependencies:
- js-types: 1.0.0
+ js-types: 4.0.0
is-number@7.0.0: {}
- is-obj-prop@1.0.0:
+ is-obj-prop@2.0.0:
dependencies:
- lowercase-keys: 1.0.1
- obj-props: 1.4.0
-
- is-path-inside@3.0.3: {}
+ lowercase-keys: 3.0.0
+ obj-props: 2.0.0
is-plain-object@2.0.4:
dependencies:
@@ -7667,10 +7624,10 @@ snapshots:
is-potential-custom-element-name@1.0.1: {}
- is-proto-prop@2.0.0:
+ is-proto-prop@3.0.1:
dependencies:
- lowercase-keys: 1.0.1
- proto-props: 2.0.0
+ lowercase-keys: 3.0.0
+ prototype-properties: 5.0.0
is-reference@1.2.1:
dependencies:
@@ -7712,7 +7669,7 @@ snapshots:
js-tokens@9.0.1: {}
- js-types@1.0.0: {}
+ js-types@4.0.0: {}
js-yaml@4.1.0:
dependencies:
@@ -7722,7 +7679,7 @@ snapshots:
jsep@1.4.0: {}
- jsesc@0.5.0: {}
+ jsesc@3.0.2: {}
jsesc@3.1.0: {}
@@ -7872,7 +7829,7 @@ snapshots:
loupe@3.2.1: {}
- lowercase-keys@1.0.1: {}
+ lowercase-keys@3.0.0: {}
lru-cache@10.4.3: {}
@@ -7882,7 +7839,7 @@ snapshots:
dependencies:
sourcemap-codec: 1.4.8
- magic-string@0.30.18:
+ magic-string@0.30.19:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -7930,7 +7887,7 @@ snapshots:
marked@4.3.0: {}
- material-icon-theme@5.26.0:
+ material-icon-theme@5.27.0:
dependencies:
chroma-js: 3.1.2
events: 3.3.0
@@ -8159,8 +8116,6 @@ snapshots:
dependencies:
mime-db: 1.52.0
- min-indent@1.0.1: {}
-
mini-css-extract-plugin@2.9.4(webpack@5.101.3):
dependencies:
schema-utils: 4.3.2
@@ -8190,13 +8145,15 @@ snapshots:
pkg-types: 1.3.1
ufo: 1.6.1
- monaco-editor-webpack-plugin@7.1.0(monaco-editor@0.52.2)(webpack@5.101.3):
+ monaco-editor-webpack-plugin@7.1.0(monaco-editor@0.53.0)(webpack@5.101.3):
dependencies:
loader-utils: 2.0.4
- monaco-editor: 0.52.2
+ monaco-editor: 0.53.0
webpack: 5.101.3(webpack-cli@6.0.1)
- monaco-editor@0.52.2: {}
+ monaco-editor@0.53.0:
+ dependencies:
+ '@types/trusted-types': 1.0.6
moo@0.5.2: {}
@@ -8247,20 +8204,13 @@ snapshots:
nolyfill@1.0.44: {}
- normalize-package-data@2.5.0:
- dependencies:
- hosted-git-info: 2.8.9
- resolve: 1.22.10
- semver: 5.7.2
- validate-npm-package-license: 3.0.4
-
normalize-path@3.0.0: {}
nth-check@2.1.1:
dependencies:
boolbase: 1.0.0
- obj-props@1.4.0: {}
+ obj-props@2.0.0: {}
object-assign@4.1.1: {}
@@ -8468,13 +8418,6 @@ snapshots:
postcss: 8.5.6
postcss-selector-parser: 6.1.2
- postcss-nesting@13.0.2(postcss@8.5.6):
- dependencies:
- '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.0)
- '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0)
- postcss: 8.5.6
- postcss-selector-parser: 7.1.0
-
postcss-resolve-nested-selector@0.1.6: {}
postcss-safe-parser@6.0.0(postcss@8.5.6):
@@ -8527,7 +8470,7 @@ snapshots:
printable-characters@1.0.42: {}
- proto-props@2.0.0: {}
+ prototype-properties@5.0.0: {}
punycode.js@2.3.1: {}
@@ -8545,19 +8488,6 @@ snapshots:
dependencies:
pify: 2.3.0
- read-pkg-up@7.0.1:
- dependencies:
- find-up: 4.1.0
- read-pkg: 5.2.0
- type-fest: 0.8.1
-
- read-pkg@5.2.0:
- dependencies:
- '@types/normalize-package-data': 2.4.4
- normalize-package-data: 2.5.0
- parse-json: 5.2.0
- type-fest: 0.6.0
-
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
@@ -8577,9 +8507,9 @@ snapshots:
regexp-tree@0.1.27: {}
- regjsparser@0.10.0:
+ regjsparser@0.12.0:
dependencies:
- jsesc: 0.5.0
+ jsesc: 3.0.2
rename-keys@1.2.0: {}
@@ -8607,10 +8537,6 @@ snapshots:
reusify@1.1.0: {}
- rimraf@3.0.2:
- dependencies:
- glob: 7.2.3
-
robust-predicates@3.0.2: {}
rollup@2.79.2:
@@ -8683,8 +8609,6 @@ snapshots:
refa: 0.12.1
regexp-ast-analysis: 0.7.1
- semver@5.7.2: {}
-
semver@6.3.1: {}
semver@7.7.2: {}
@@ -8761,11 +8685,6 @@ snapshots:
spdx-expression-parse: 3.0.1
spdx-ranges: 2.1.1
- spdx-correct@3.2.0:
- dependencies:
- spdx-expression-parse: 3.0.1
- spdx-license-ids: 3.0.22
-
spdx-exceptions@2.5.0: {}
spdx-expression-parse@3.0.1:
@@ -8808,27 +8727,25 @@ snapshots:
dependencies:
eastasianwidth: 0.2.0
emoji-regex: 9.2.2
- strip-ansi: 7.1.0
+ strip-ansi: 7.1.2
string-width@7.2.0:
dependencies:
emoji-regex: 10.5.0
- get-east-asian-width: 1.3.1
- strip-ansi: 7.1.0
+ get-east-asian-width: 1.4.0
+ strip-ansi: 7.1.2
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
- strip-ansi@7.1.0:
+ strip-ansi@7.1.2:
dependencies:
- ansi-regex: 6.2.0
+ ansi-regex: 6.2.2
strip-bom@3.0.0: {}
- strip-indent@3.0.0:
- dependencies:
- min-indent: 1.0.1
+ strip-indent@4.1.0: {}
strip-json-comments@3.1.1: {}
@@ -8959,7 +8876,7 @@ snapshots:
deep-rename-keys: 0.2.1
xml-reader: 2.4.3
- swagger-ui-dist@5.28.1:
+ swagger-ui-dist@5.29.0:
dependencies:
'@scarf/scarf': 1.4.0
@@ -9099,11 +9016,16 @@ snapshots:
type-fest@0.20.2: {}
- type-fest@0.6.0: {}
-
- type-fest@0.8.1: {}
-
- type-fest@4.41.0: {}
+ typescript-eslint@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
+ '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)
+ eslint: 9.35.0(jiti@2.5.1)
+ typescript: 5.9.2
+ transitivePeerDependencies:
+ - supports-color
typescript@5.9.2: {}
@@ -9151,7 +9073,7 @@ snapshots:
escalade: 3.2.0
picocolors: 1.1.1
- updates@16.6.4: {}
+ updates@16.7.0: {}
uri-js@4.4.1:
dependencies:
@@ -9165,11 +9087,6 @@ snapshots:
uuid@11.1.0: {}
- validate-npm-package-license@3.0.4:
- dependencies:
- spdx-correct: 3.2.0
- spdx-expression-parse: 3.0.1
-
validate-npm-package-name@3.0.0:
dependencies:
builtins: 1.0.3
@@ -9182,7 +9099,7 @@ snapshots:
debug: 4.4.1
es-module-lexer: 1.7.0
pathe: 2.0.3
- vite: 7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
+ vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
transitivePeerDependencies:
- '@types/node'
- jiti
@@ -9199,7 +9116,7 @@ snapshots:
vite-string-plugin@1.4.6: {}
- vite@7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1):
+ vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1):
dependencies:
esbuild: 0.25.9
fdir: 6.5.0(picomatch@4.0.3)
@@ -9219,7 +9136,7 @@ snapshots:
dependencies:
'@types/chai': 5.2.2
'@vitest/expect': 3.2.4
- '@vitest/mocker': 3.2.4(vite@7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))
+ '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1))
'@vitest/pretty-format': 3.2.4
'@vitest/runner': 3.2.4
'@vitest/snapshot': 3.2.4
@@ -9228,7 +9145,7 @@ snapshots:
chai: 5.3.3
debug: 4.4.1
expect-type: 1.2.2
- magic-string: 0.30.18
+ magic-string: 0.30.19
pathe: 2.0.3
picomatch: 4.0.3
std-env: 3.9.0
@@ -9237,7 +9154,7 @@ snapshots:
tinyglobby: 0.2.15
tinypool: 1.1.1
tinyrainbow: 2.0.0
- vite: 7.1.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
+ vite: 7.1.5(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
vite-node: 3.2.4(@types/node@24.3.1)(jiti@2.5.1)(stylus@0.57.0)(terser@5.44.0)(yaml@2.8.1)
why-is-node-running: 2.3.0
optionalDependencies:
@@ -9288,10 +9205,10 @@ snapshots:
chart.js: 4.5.0
vue: 3.5.21(typescript@5.9.2)
- vue-eslint-parser@10.2.0(eslint@8.57.0):
+ vue-eslint-parser@10.2.0(eslint@9.35.0(jiti@2.5.1)):
dependencies:
debug: 4.4.1
- eslint: 8.57.0
+ eslint: 9.35.0(jiti@2.5.1)
eslint-scope: 8.4.0
eslint-visitor-keys: 4.2.1
espree: 10.4.0
@@ -9434,15 +9351,15 @@ snapshots:
wrap-ansi@8.1.0:
dependencies:
- ansi-styles: 6.2.1
+ ansi-styles: 6.2.3
string-width: 5.1.2
- strip-ansi: 7.1.0
+ strip-ansi: 7.1.2
- wrap-ansi@9.0.0:
+ wrap-ansi@9.0.2:
dependencies:
- ansi-styles: 6.2.1
+ ansi-styles: 6.2.3
string-width: 7.2.0
- strip-ansi: 7.1.0
+ strip-ansi: 7.1.2
wrappy@1.0.2: {}
diff --git a/public/assets/img/svg/octicon-checkbox-fill.svg b/public/assets/img/svg/octicon-checkbox-fill.svg
new file mode 100644
index 00000000000..6e9085f61c6
--- /dev/null
+++ b/public/assets/img/svg/octicon-checkbox-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/routers/api/actions/runner/runner.go b/routers/api/actions/runner/runner.go
index ce8137592d6..55ba7862a90 100644
--- a/routers/api/actions/runner/runner.go
+++ b/routers/api/actions/runner/runner.go
@@ -157,7 +157,7 @@ func (s *Service) FetchTask(
if tasksVersion != latestVersion {
// if the task version in request is not equal to the version in db,
- // it means there may still be some tasks not be assgined.
+ // it means there may still be some tasks that haven't been assigned.
// try to pick a task for the runner that send the request.
if t, ok, err := actions_service.PickTask(ctx, runner); err != nil {
log.Error("pick task failed: %v", err)
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index bada1f6b760..66afede218c 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -1247,7 +1247,7 @@ func Routes() *web.Router {
}, reqToken())
m.Get("/raw/*", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetRawFile)
m.Get("/media/*", context.ReferencesGitRepo(), context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetRawFileOrLFS)
- m.Methods("HEAD,GET", "/archive/*", reqRepoReader(unit.TypeCode), repo.GetArchive)
+ m.Methods("HEAD,GET", "/archive/*", reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(true), repo.GetArchive)
m.Combo("/forks").Get(repo.ListForks).
Post(reqToken(), reqRepoReader(unit.TypeCode), bind(api.CreateForkOption{}), repo.CreateFork)
m.Post("/merge-upstream", reqToken(), mustNotBeArchived, reqRepoWriter(unit.TypeCode), bind(api.MergeUpstreamRequest{}), repo.MergeUpstream)
@@ -1466,7 +1466,7 @@ func Routes() *web.Router {
m.Delete("", repo.DeleteAvatar)
}, reqAdmin(), reqToken())
- m.Methods("HEAD,GET", "/{ball_type:tarball|zipball|bundle}/*", reqRepoReader(unit.TypeCode), repo.DownloadArchive)
+ m.Methods("HEAD,GET", "/{ball_type:tarball|zipball|bundle}/*", reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(true), repo.DownloadArchive)
}, repoAssignment(), checkTokenPublicOnly())
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository))
diff --git a/routers/api/v1/repo/download.go b/routers/api/v1/repo/download.go
index acd93ecf2ec..c16605d6cd6 100644
--- a/routers/api/v1/repo/download.go
+++ b/routers/api/v1/repo/download.go
@@ -4,14 +4,29 @@
package repo
import (
+ "errors"
"net/http"
"code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/services/context"
archiver_service "code.gitea.io/gitea/services/repository/archiver"
)
+func serveRepoArchive(ctx *context.APIContext, reqFileName string) {
+ aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, reqFileName)
+ if err != nil {
+ if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
+ ctx.APIError(http.StatusBadRequest, err)
+ } else if errors.Is(err, archiver_service.RepoRefNotFoundError{}) {
+ ctx.APIError(http.StatusNotFound, err)
+ } else {
+ ctx.APIErrorInternal(err)
+ }
+ return
+ }
+ archiver_service.ServeRepoArchive(ctx.Base, ctx.Repo.Repository, ctx.Repo.GitRepo, aReq)
+}
+
func DownloadArchive(ctx *context.APIContext) {
var tp git.ArchiveType
switch ballType := ctx.PathParam("ball_type"); ballType {
@@ -25,27 +40,5 @@ func DownloadArchive(ctx *context.APIContext) {
ctx.APIError(http.StatusBadRequest, "Unknown archive type: "+ballType)
return
}
-
- if ctx.Repo.GitRepo == nil {
- var err error
- ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
- }
-
- r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")+"."+tp.String())
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
-
- archive, err := r.Await(ctx)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
-
- download(ctx, r.GetArchiveName(), archive)
+ serveRepoArchive(ctx, ctx.PathParam("*")+"."+tp.String())
}
diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go
index a85dda79d00..cd787b9da33 100644
--- a/routers/api/v1/repo/file.go
+++ b/routers/api/v1/repo/file.go
@@ -15,9 +15,7 @@ import (
"time"
git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/httpcache"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/lfs"
@@ -31,7 +29,6 @@ import (
"code.gitea.io/gitea/routers/common"
"code.gitea.io/gitea/services/context"
pull_service "code.gitea.io/gitea/services/pull"
- archiver_service "code.gitea.io/gitea/services/repository/archiver"
files_service "code.gitea.io/gitea/services/repository/files"
)
@@ -282,74 +279,7 @@ func GetArchive(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- if ctx.Repo.GitRepo == nil {
- var err error
- ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
- }
-
- archiveDownload(ctx)
-}
-
-func archiveDownload(ctx *context.APIContext) {
- aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
- if err != nil {
- if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
- ctx.APIError(http.StatusBadRequest, err)
- } else if errors.Is(err, archiver_service.RepoRefNotFoundError{}) {
- ctx.APIError(http.StatusNotFound, err)
- } else {
- ctx.APIErrorInternal(err)
- }
- return
- }
-
- archiver, err := aReq.Await(ctx)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
-
- download(ctx, aReq.GetArchiveName(), archiver)
-}
-
-func download(ctx *context.APIContext, archiveName string, archiver *repo_model.RepoArchiver) {
- downloadName := ctx.Repo.Repository.Name + "-" + archiveName
-
- // Add nix format link header so tarballs lock correctly:
- // https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md
- ctx.Resp.Header().Add("Link", fmt.Sprintf(`<%s/archive/%s.%s?rev=%s>; rel="immutable"`,
- ctx.Repo.Repository.APIURL(),
- archiver.CommitID,
- archiver.Type.String(),
- archiver.CommitID,
- ))
-
- rPath := archiver.RelativePath()
- if setting.RepoArchive.Storage.ServeDirect() {
- // If we have a signed url (S3, object storage), redirect to this directly.
- u, err := storage.RepoArchives.URL(rPath, downloadName, ctx.Req.Method, nil)
- if u != nil && err == nil {
- ctx.Redirect(u.String())
- return
- }
- }
-
- // If we have matched and access to release or issue
- fr, err := storage.RepoArchives.Open(rPath)
- if err != nil {
- ctx.APIErrorInternal(err)
- return
- }
- defer fr.Close()
-
- ctx.ServeContent(fr, &context.ServeHeaderOptions{
- Filename: downloadName,
- LastModified: archiver.CreatedUnix.AsLocalTime(),
- })
+ serveRepoArchive(ctx, ctx.PathParam("*"))
}
// GetEditorconfig get editor config of a repository
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index d4a5872fd1c..b11e889eb50 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -979,7 +979,7 @@ func DeleteIssue(ctx *context.APIContext) {
return
}
- if err = issue_service.DeleteIssue(ctx, ctx.Doer, ctx.Repo.GitRepo, issue); err != nil {
+ if err = issue_service.DeleteIssue(ctx, ctx.Doer, issue); err != nil {
ctx.APIErrorInternal(err)
return
}
diff --git a/routers/init.go b/routers/init.go
index 2281260a6fa..6cd85728c21 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/eventsource"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/highlight"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
@@ -114,7 +115,7 @@ func InitWebInstallPage(ctx context.Context) {
// InitWebInstalled is for the global configuration of an installed instance
func InitWebInstalled(ctx context.Context) {
mustInit(git.InitFull)
- log.Info("Git version: %s (home: %s)", git.DefaultFeatures().VersionInfo(), git.HomeDir())
+ log.Info("Git version: %s (home: %s)", git.DefaultFeatures().VersionInfo(), gitcmd.HomeDir())
if !git.DefaultFeatures().SupportHashSha256 {
log.Warn("sha256 hash support is disabled - requires Git >= 2.42." + util.Iif(git.DefaultFeatures().UsingGogit, " Gogit is currently unsupported.", ""))
}
diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go
index dd9d0bc15e9..99a0b450d70 100644
--- a/routers/private/hook_pre_receive.go
+++ b/routers/private/hook_pre_receive.go
@@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
@@ -188,7 +189,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
// 2. Disallow force pushes to protected branches
if oldCommitID != objectFormat.EmptyObjectID().String() {
- output, _, err := git.NewCommand("rev-list", "--max-count=1").AddDynamicArguments(oldCommitID, "^"+newCommitID).RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath(), Env: ctx.env})
+ output, _, err := gitcmd.NewCommand("rev-list", "--max-count=1").AddDynamicArguments(oldCommitID, "^"+newCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath(), Env: ctx.env})
if err != nil {
log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err)
ctx.JSON(http.StatusInternalServerError, private.Response{
diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go
index 57d0964ead2..a69c3b04ebd 100644
--- a/routers/private/hook_verification.go
+++ b/routers/private/hook_verification.go
@@ -10,6 +10,7 @@ import (
"os"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
asymkey_service "code.gitea.io/gitea/services/asymkey"
)
@@ -27,18 +28,18 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []
_ = stdoutWriter.Close()
}()
- var command *git.Command
+ var command *gitcmd.Command
objectFormat, _ := repo.GetObjectFormat()
if oldCommitID == objectFormat.EmptyObjectID().String() {
// When creating a new branch, the oldCommitID is empty, by using "newCommitID --not --all":
// List commits that are reachable by following the newCommitID, exclude "all" existing heads/tags commits
// So, it only lists the new commits received, doesn't list the commits already present in the receiving repository
- command = git.NewCommand("rev-list").AddDynamicArguments(newCommitID).AddArguments("--not", "--all")
+ command = gitcmd.NewCommand("rev-list").AddDynamicArguments(newCommitID).AddArguments("--not", "--all")
} else {
- command = git.NewCommand("rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID)
+ command = gitcmd.NewCommand("rev-list").AddDynamicArguments(oldCommitID + "..." + newCommitID)
}
// This is safe as force pushes are already forbidden
- err = command.Run(repo.Ctx, &git.RunOpts{
+ err = command.Run(repo.Ctx, &gitcmd.RunOpts{
Env: env,
Dir: repo.Path,
Stdout: stdoutWriter,
@@ -84,8 +85,8 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
commitID := git.MustIDFromString(sha)
- return git.NewCommand("cat-file", "commit").AddDynamicArguments(sha).
- Run(repo.Ctx, &git.RunOpts{
+ return gitcmd.NewCommand("cat-file", "commit").AddDynamicArguments(sha).
+ Run(repo.Ctx, &gitcmd.RunOpts{
Env: env,
Dir: repo.Path,
Stdout: stdoutWriter,
diff --git a/routers/private/serv.go b/routers/private/serv.go
index b879be0dc20..3dfe4d21da7 100644
--- a/routers/private/serv.go
+++ b/routers/private/serv.go
@@ -108,6 +108,18 @@ func ServCommand(ctx *context.PrivateContext) {
results.RepoName = repoName[:len(repoName)-5]
}
+ // Check if there is a user redirect for the requested owner
+ redirectedUserID, err := user_model.LookupUserRedirect(ctx, results.OwnerName)
+ if err == nil {
+ owner, err := user_model.GetUserByID(ctx, redirectedUserID)
+ if err == nil {
+ log.Info("User %s has been redirected to %s", results.OwnerName, owner.Name)
+ results.OwnerName = owner.Name
+ } else {
+ log.Warn("User %s has a redirect to user with ID %d, but no user with this ID could be found. Trying without redirect...", results.OwnerName, redirectedUserID)
+ }
+ }
+
owner, err := user_model.GetUserByName(ctx, results.OwnerName)
if err != nil {
if user_model.IsErrUserNotExist(err) {
@@ -131,6 +143,19 @@ func ServCommand(ctx *context.PrivateContext) {
return
}
+ redirectedRepoID, err := repo_model.LookupRedirect(ctx, owner.ID, results.RepoName)
+ if err == nil {
+ redirectedRepo, err := repo_model.GetRepositoryByID(ctx, redirectedRepoID)
+ if err == nil {
+ log.Info("Repository %s/%s has been redirected to %s/%s", results.OwnerName, results.RepoName, redirectedRepo.OwnerName, redirectedRepo.Name)
+ results.RepoName = redirectedRepo.Name
+ results.OwnerName = redirectedRepo.OwnerName
+ owner.ID = redirectedRepo.OwnerID
+ } else {
+ log.Warn("Repo %s/%s has a redirect to repo with ID %d, but no repo with this ID could be found. Trying without redirect...", results.OwnerName, results.RepoName, redirectedRepoID)
+ }
+ }
+
// Now get the Repository and set the results section
repoExist := true
repo, err := repo_model.GetRepositoryByName(ctx, owner.ID, results.RepoName)
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index 20f5d6262ef..2e56f6934a0 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -28,6 +28,7 @@ import (
csv_module "code.gitea.io/gitea/modules/csv"
"code.gitea.io/gitea/modules/fileicon"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
@@ -524,7 +525,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
// Treat as pull request if both references are branches
if ctx.Data["PageIsComparePull"] == nil {
- ctx.Data["PageIsComparePull"] = headIsBranch && baseIsBranch
+ ctx.Data["PageIsComparePull"] = headIsBranch && baseIsBranch && permBase.CanReadIssuesOrPulls(true)
}
if ctx.Data["PageIsComparePull"] == true && !permBase.CanReadIssuesOrPulls(true) {
@@ -569,7 +570,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
func PrepareCompareDiff(
ctx *context.Context,
ci *common.CompareInfo,
- whitespaceBehavior git.TrustedCmdArgs,
+ whitespaceBehavior gitcmd.TrustedCmdArgs,
) (nothingToCompare bool) {
repo := ctx.Repo.Repository
headCommitID := ci.CompareInfo.HeadCommitID
@@ -730,6 +731,7 @@ func CompareDiff(ctx *context.Context) {
return
}
+ ctx.Data["PageIsViewCode"] = true
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
ctx.Data["DirectComparison"] = ci.DirectComparison
ctx.Data["OtherCompareSeparator"] = ".."
diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go
index deb3ae4f3a6..ab649b6f15d 100644
--- a/routers/web/repo/githttp.go
+++ b/routers/web/repo/githttp.go
@@ -26,6 +26,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
@@ -315,7 +316,7 @@ func dummyInfoRefs(ctx *context.Context) {
return
}
- refs, _, err := git.NewCommand("receive-pack", "--stateless-rpc", "--advertise-refs", ".").RunStdBytes(ctx, &git.RunOpts{Dir: tmpDir})
+ refs, _, err := gitcmd.NewCommand("receive-pack", "--stateless-rpc", "--advertise-refs", ".").RunStdBytes(ctx, &gitcmd.RunOpts{Dir: tmpDir})
if err != nil {
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
}
@@ -393,12 +394,12 @@ func (h *serviceHandler) sendFile(ctx *context.Context, contentType, file string
// one or more key=value pairs separated by colons
var safeGitProtocolHeader = regexp.MustCompile(`^[0-9a-zA-Z]+=[0-9a-zA-Z]+(:[0-9a-zA-Z]+=[0-9a-zA-Z]+)*$`)
-func prepareGitCmdWithAllowedService(service string) (*git.Command, error) {
+func prepareGitCmdWithAllowedService(service string) (*gitcmd.Command, error) {
if service == "receive-pack" {
- return git.NewCommand("receive-pack"), nil
+ return gitcmd.NewCommand("receive-pack"), nil
}
if service == "upload-pack" {
- return git.NewCommand("upload-pack"), nil
+ return gitcmd.NewCommand("upload-pack"), nil
}
return nil, fmt.Errorf("service %q is not allowed", service)
@@ -448,7 +449,7 @@ func serviceRPC(ctx *context.Context, h *serviceHandler, service string) {
var stderr bytes.Buffer
cmd.AddArguments("--stateless-rpc").AddDynamicArguments(h.getRepoDir())
- if err := cmd.Run(ctx, &git.RunOpts{
+ if err := cmd.Run(ctx, &gitcmd.RunOpts{
Dir: h.getRepoDir(),
Env: append(os.Environ(), h.environ...),
Stdout: ctx.Resp,
@@ -488,7 +489,7 @@ func getServiceType(ctx *context.Context) string {
}
func updateServerInfo(ctx gocontext.Context, dir string) []byte {
- out, _, err := git.NewCommand("update-server-info").RunStdBytes(ctx, &git.RunOpts{Dir: dir})
+ out, _, err := gitcmd.NewCommand("update-server-info").RunStdBytes(ctx, &gitcmd.RunOpts{Dir: dir})
if err != nil {
log.Error(fmt.Sprintf("%v - %s", err, string(out)))
}
@@ -518,7 +519,7 @@ func GetInfoRefs(ctx *context.Context) {
}
h.environ = append(os.Environ(), h.environ...)
- refs, _, err := cmd.AddArguments("--stateless-rpc", "--advertise-refs", ".").RunStdBytes(ctx, &git.RunOpts{Env: h.environ, Dir: h.getRepoDir()})
+ refs, _, err := cmd.AddArguments("--stateless-rpc", "--advertise-refs", ".").RunStdBytes(ctx, &gitcmd.RunOpts{Env: h.environ, Dir: h.getRepoDir()})
if err != nil {
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
}
diff --git a/routers/web/repo/issue_list.go b/routers/web/repo/issue_list.go
index fd34422cfcc..a11d35da1eb 100644
--- a/routers/web/repo/issue_list.go
+++ b/routers/web/repo/issue_list.go
@@ -398,7 +398,7 @@ func BatchDeleteIssues(ctx *context.Context) {
return
}
for _, issue := range issues {
- if err := issue_service.DeleteIssue(ctx, ctx.Doer, ctx.Repo.GitRepo, issue); err != nil {
+ if err := issue_service.DeleteIssue(ctx, ctx.Doer, issue); err != nil {
ctx.ServerError("DeleteIssue", err)
return
}
diff --git a/routers/web/repo/issue_new.go b/routers/web/repo/issue_new.go
index 887019b146b..1393f62fa53 100644
--- a/routers/web/repo/issue_new.go
+++ b/routers/web/repo/issue_new.go
@@ -216,7 +216,7 @@ func DeleteIssue(ctx *context.Context) {
return
}
- if err := issue_service.DeleteIssue(ctx, ctx.Doer, ctx.Repo.GitRepo, issue); err != nil {
+ if err := issue_service.DeleteIssue(ctx, ctx.Doer, issue); err != nil {
ctx.ServerError("DeleteIssueByID", err)
return
}
diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go
index d0064e763ef..d9f6c33e3fb 100644
--- a/routers/web/repo/issue_view.go
+++ b/routers/web/repo/issue_view.go
@@ -12,6 +12,7 @@ import (
"strconv"
activities_model "code.gitea.io/gitea/models/activities"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
@@ -494,7 +495,7 @@ func preparePullViewSigning(ctx *context.Context, issue *issues_model.Issue) {
if ctx.Doer != nil {
sign, key, _, err := asymkey_service.SignMerge(ctx, pull, ctx.Doer, pull.BaseRepo.RepoPath(), pull.BaseBranch, pull.GetGitHeadRefName())
ctx.Data["WillSign"] = sign
- ctx.Data["SigningKey"] = key
+ ctx.Data["SigningKeyMergeDisplay"] = asymkey_model.GetDisplaySigningKey(key)
if err != nil {
if asymkey_service.IsErrWontSign(err) {
ctx.Data["WontSignReason"] = err.(*asymkey_service.ErrWontSign).Reason
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index 83aaf75363f..1ce2047b13d 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -26,7 +26,9 @@ import (
"code.gitea.io/gitea/modules/emoji"
"code.gitea.io/gitea/modules/fileicon"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful"
issue_template "code.gitea.io/gitea/modules/issue/template"
"code.gitea.io/gitea/modules/log"
@@ -46,8 +48,6 @@ import (
pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository"
user_service "code.gitea.io/gitea/services/user"
-
- "github.com/gobwas/glob"
)
const (
@@ -224,7 +224,7 @@ func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) stri
commitSHA, err = ctx.Repo.GitRepo.ReadPatchCommit(pull.Index)
if err == nil {
// Recreate pull head in files for next time
- if err := ctx.Repo.GitRepo.SetReference(pull.GetGitHeadRefName(), commitSHA); err != nil {
+ if err := gitrepo.UpdateRef(ctx, ctx.Repo.Repository, pull.GetGitHeadRefName(), commitSHA); err != nil {
log.Error("Could not write head file", err)
}
} else {
@@ -234,7 +234,7 @@ func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) stri
}
if commitSHA != "" {
// Get immediate parent of the first commit in the patch, grab history back
- parentCommit, _, err = git.NewCommand("rev-list", "-1", "--skip=1").AddDynamicArguments(commitSHA).RunStdString(ctx, &git.RunOpts{Dir: ctx.Repo.GitRepo.Path})
+ parentCommit, _, err = gitcmd.NewCommand("rev-list", "-1", "--skip=1").AddDynamicArguments(commitSHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: ctx.Repo.GitRepo.Path})
if err == nil {
parentCommit = strings.TrimSpace(parentCommit)
}
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 1b700aa6da0..2c137b64ab8 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -24,7 +24,6 @@ import (
"code.gitea.io/gitea/modules/optional"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/util"
@@ -376,53 +375,19 @@ func Download(ctx *context.Context) {
}
return
}
-
- archiver, err := aReq.Await(ctx)
- if err != nil {
- ctx.ServerError("archiver.Await", err)
- return
- }
-
- download(ctx, aReq.GetArchiveName(), archiver)
-}
-
-func download(ctx *context.Context, archiveName string, archiver *repo_model.RepoArchiver) {
- downloadName := ctx.Repo.Repository.Name + "-" + archiveName
-
- // Add nix format link header so tarballs lock correctly:
- // https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md
- ctx.Resp.Header().Add("Link", fmt.Sprintf(`<%s/archive/%s.tar.gz?rev=%s>; rel="immutable"`,
- ctx.Repo.Repository.APIURL(),
- archiver.CommitID, archiver.CommitID))
-
- rPath := archiver.RelativePath()
- if setting.RepoArchive.Storage.ServeDirect() {
- // If we have a signed url (S3, object storage), redirect to this directly.
- u, err := storage.RepoArchives.URL(rPath, downloadName, ctx.Req.Method, nil)
- if u != nil && err == nil {
- ctx.Redirect(u.String())
- return
- }
- }
-
- // If we have matched and access to release or issue
- fr, err := storage.RepoArchives.Open(rPath)
- if err != nil {
- ctx.ServerError("Open", err)
- return
- }
- defer fr.Close()
-
- ctx.ServeContent(fr, &context.ServeHeaderOptions{
- Filename: downloadName,
- LastModified: archiver.CreatedUnix.AsLocalTime(),
- })
+ archiver_service.ServeRepoArchive(ctx.Base, ctx.Repo.Repository, ctx.Repo.GitRepo, aReq)
}
// InitiateDownload will enqueue an archival request, as needed. It may submit
// a request that's already in-progress, but the archiver service will just
// kind of drop it on the floor if this is the case.
func InitiateDownload(ctx *context.Context) {
+ if setting.Repository.StreamArchives {
+ ctx.JSON(http.StatusOK, map[string]any{
+ "complete": true,
+ })
+ return
+ }
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*"))
if err != nil {
ctx.HTTPError(http.StatusBadRequest, "invalid archive request")
diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go
index 0eea5e3f340..152f67550cc 100644
--- a/routers/web/repo/setting/protected_branch.go
+++ b/routers/web/repo/setting/protected_branch.go
@@ -19,6 +19,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/web/repo"
@@ -26,8 +27,6 @@ import (
"code.gitea.io/gitea/services/forms"
pull_service "code.gitea.io/gitea/services/pull"
"code.gitea.io/gitea/services/repository"
-
- "github.com/gobwas/glob"
)
const (
diff --git a/routers/web/user/package.go b/routers/web/user/package.go
index d130d1dca18..924a10041b0 100644
--- a/routers/web/user/package.go
+++ b/routers/web/user/package.go
@@ -431,74 +431,81 @@ func PackageSettings(ctx *context.Context) {
ctx.Data["Title"] = pd.Package.Name
ctx.Data["IsPackagesPage"] = true
ctx.Data["PackageDescriptor"] = pd
-
- repos, _, _ := repo_model.GetUserRepositories(ctx, repo_model.SearchRepoOptions{
- Actor: pd.Owner,
- Private: true,
- })
- ctx.Data["Repos"] = repos
ctx.Data["CanWritePackages"] = ctx.Package.AccessMode >= perm.AccessModeWrite || ctx.IsUserSiteAdmin()
+ if pd.Package.RepoID > 0 {
+ repo, err := repo_model.GetRepositoryByID(ctx, pd.Package.RepoID)
+ if err != nil {
+ ctx.ServerError("GetRepositoryByID", err)
+ return
+ }
+ ctx.Data["LinkedRepoName"] = repo.Name
+ }
+
ctx.HTML(http.StatusOK, tplPackagesSettings)
}
// PackageSettingsPost updates the package settings
func PackageSettingsPost(ctx *context.Context) {
- pd := ctx.Package.Descriptor
-
form := web.GetForm(ctx).(*forms.PackageSettingForm)
switch form.Action {
case "link":
- success := func() bool {
- repoID := int64(0)
- if form.RepoID != 0 {
- repo, err := repo_model.GetRepositoryByID(ctx, form.RepoID)
- if err != nil {
- log.Error("Error getting repository: %v", err)
- return false
- }
-
- if repo.OwnerID != pd.Owner.ID {
- return false
- }
-
- repoID = repo.ID
- }
-
- if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repoID); err != nil {
- log.Error("Error updating package: %v", err)
- return false
- }
-
- return true
- }()
-
- if success {
- ctx.Flash.Success(ctx.Tr("packages.settings.link.success"))
- } else {
- ctx.Flash.Error(ctx.Tr("packages.settings.link.error"))
- }
-
- ctx.Redirect(ctx.Link)
- return
+ packageSettingsPostActionLink(ctx, form)
case "delete":
- err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version)
- if err != nil {
- log.Error("Error deleting package: %v", err)
- ctx.Flash.Error(ctx.Tr("packages.settings.delete.error"))
- } else {
- ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
+ packageSettingsPostActionDelete(ctx)
+ default:
+ ctx.NotFound(nil)
+ }
+}
+
+func packageSettingsPostActionLink(ctx *context.Context, form *forms.PackageSettingForm) {
+ pd := ctx.Package.Descriptor
+ if form.RepoName == "" { // remove the link
+ if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, 0); err != nil {
+ ctx.JSONError(ctx.Tr("packages.settings.unlink.error"))
+ return
}
- redirectURL := ctx.Package.Owner.HomeLink() + "/-/packages"
- // redirect to the package if there are still versions available
- if has, _ := packages_model.ExistVersion(ctx, &packages_model.PackageSearchOptions{PackageID: ctx.Package.Descriptor.Package.ID, IsInternal: optional.Some(false)}); has {
- redirectURL = ctx.Package.Descriptor.PackageWebLink()
- }
-
- ctx.Redirect(redirectURL)
+ ctx.Flash.Success(ctx.Tr("packages.settings.unlink.success"))
+ ctx.JSONRedirect("")
return
}
+
+ repo, err := repo_model.GetRepositoryByName(ctx, pd.Owner.ID, form.RepoName)
+ if err != nil {
+ if repo_model.IsErrRepoNotExist(err) {
+ ctx.JSONError(ctx.Tr("packages.settings.link.repo_not_found", form.RepoName))
+ } else {
+ ctx.ServerError("GetRepositoryByOwnerAndName", err)
+ }
+ return
+ }
+
+ if err := packages_model.SetRepositoryLink(ctx, pd.Package.ID, repo.ID); err != nil {
+ ctx.JSONError(ctx.Tr("packages.settings.link.error"))
+ return
+ }
+
+ ctx.Flash.Success(ctx.Tr("packages.settings.link.success"))
+ ctx.JSONRedirect("")
+}
+
+func packageSettingsPostActionDelete(ctx *context.Context) {
+ err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version)
+ if err != nil {
+ log.Error("Error deleting package: %v", err)
+ ctx.Flash.Error(ctx.Tr("packages.settings.delete.error"))
+ } else {
+ ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
+ }
+
+ redirectURL := ctx.Package.Owner.HomeLink() + "/-/packages"
+ // redirect to the package if there are still versions available
+ if has, _ := packages_model.ExistVersion(ctx, &packages_model.PackageSearchOptions{PackageID: ctx.Package.Descriptor.Package.ID, IsInternal: optional.Some(false)}); has {
+ redirectURL = ctx.Package.Descriptor.PackageWebLink()
+ }
+
+ ctx.Redirect(redirectURL)
}
// DownloadPackageFile serves the content of a package file
diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go
index b8bc20cdbb1..66916e93017 100644
--- a/services/actions/notifier_helper.go
+++ b/services/actions/notifier_helper.go
@@ -281,7 +281,7 @@ func skipWorkflows(ctx context.Context, input *notifyInput, commit *git.Commit)
return true
}
}
- // skip workflow runs events exceeding the maxiumum of 5 recursive events
+ // skip workflow runs events exceeding the maximum of 5 recursive events
log.Debug("repo %s: skipped workflow_run because of recursive event of 5", input.Repo.RepoPath())
return true
}
diff --git a/services/agit/agit.go b/services/agit/agit.go
index 9d2d122cfb3..4ed867b3583 100644
--- a/services/agit/agit.go
+++ b/services/agit/agit.go
@@ -15,6 +15,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
@@ -198,9 +199,9 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
}
if !forcePush.Value() {
- output, _, err := git.NewCommand("rev-list", "--max-count=1").
+ output, _, err := gitcmd.NewCommand("rev-list", "--max-count=1").
AddDynamicArguments(oldCommitID, "^"+opts.NewCommitIDs[i]).
- RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath(), Env: os.Environ()})
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath(), Env: os.Environ()})
if err != nil {
return nil, fmt.Errorf("failed to detect force push: %w", err)
} else if len(output) > 0 {
diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go
index 8fd2adc8b48..4fde342bea5 100644
--- a/services/asymkey/sign.go
+++ b/services/asymkey/sign.go
@@ -17,6 +17,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
@@ -116,16 +117,16 @@ func SigningKey(ctx context.Context, repoPath string) (*git.SigningKey, *git.Sig
if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" {
// Can ignore the error here as it means that commit.gpgsign is not set
- value, _, _ := git.NewCommand("config", "--get", "commit.gpgsign").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
+ value, _, _ := gitcmd.NewCommand("config", "--get", "commit.gpgsign").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
sign, valid := git.ParseBool(strings.TrimSpace(value))
if !sign || !valid {
return nil, nil
}
- format, _, _ := git.NewCommand("config", "--default", git.SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
- signingKey, _, _ := git.NewCommand("config", "--get", "user.signingkey").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
- signingName, _, _ := git.NewCommand("config", "--get", "user.name").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
- signingEmail, _, _ := git.NewCommand("config", "--get", "user.email").RunStdString(ctx, &git.RunOpts{Dir: repoPath})
+ format, _, _ := gitcmd.NewCommand("config", "--default", git.SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
+ signingKey, _, _ := gitcmd.NewCommand("config", "--get", "user.signingkey").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
+ signingName, _, _ := gitcmd.NewCommand("config", "--get", "user.name").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
+ signingEmail, _, _ := gitcmd.NewCommand("config", "--get", "user.email").RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
if strings.TrimSpace(signingKey) == "" {
return nil, nil
diff --git a/services/context/csrf.go b/services/context/csrf.go
index 7b475a8fd85..f190465bdb3 100644
--- a/services/context/csrf.go
+++ b/services/context/csrf.go
@@ -48,7 +48,7 @@ type csrfProtector struct {
opt CsrfOptions
// id must be unique per user.
id string
- // token is the valid one which wil be used by end user and passed via header, cookie, or hidden form value.
+ // token is the valid one which will be used by end user and passed via header, cookie, or hidden form value.
token string
}
diff --git a/services/context/repo.go b/services/context/repo.go
index afc6de9b166..04ddba70fe0 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -14,6 +14,7 @@ import (
"path"
"strings"
+ asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
@@ -99,7 +100,7 @@ type CommitFormOptions struct {
UserCanPush bool
RequireSigned bool
WillSign bool
- SigningKey *git.SigningKey
+ SigningKeyFormDisplay string
WontSignReason string
CanCreatePullRequest bool
CanCreateBasePullRequest bool
@@ -139,7 +140,7 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r
protectionRequireSigned = protectedBranch.RequireSignedCommits
}
- willSign, signKeyID, _, err := asymkey_service.SignCRUDAction(ctx, targetRepo.RepoPath(), doer, targetRepo.RepoPath(), refName.String())
+ willSign, signKey, _, err := asymkey_service.SignCRUDAction(ctx, targetRepo.RepoPath(), doer, targetRepo.RepoPath(), refName.String())
wontSignReason := ""
if asymkey_service.IsErrWontSign(err) {
wontSignReason = string(err.(*asymkey_service.ErrWontSign).Reason)
@@ -156,14 +157,14 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r
canCreatePullRequest := targetRepo.UnitEnabled(ctx, unit_model.TypePullRequests) || canCreateBasePullRequest
opts := &CommitFormOptions{
- TargetRepo: targetRepo,
- WillSubmitToFork: submitToForkedRepo,
- CanCommitToBranch: canCommitToBranch,
- UserCanPush: canPushWithProtection,
- RequireSigned: protectionRequireSigned,
- WillSign: willSign,
- SigningKey: signKeyID,
- WontSignReason: wontSignReason,
+ TargetRepo: targetRepo,
+ WillSubmitToFork: submitToForkedRepo,
+ CanCommitToBranch: canCommitToBranch,
+ UserCanPush: canPushWithProtection,
+ RequireSigned: protectionRequireSigned,
+ WillSign: willSign,
+ SigningKeyFormDisplay: asymkey_model.GetDisplaySigningKey(signKey),
+ WontSignReason: wontSignReason,
CanCreatePullRequest: canCreatePullRequest,
CanCreateBasePullRequest: canCreateBasePullRequest,
diff --git a/services/convert/issue.go b/services/convert/issue.go
index ecb3b93af1a..e26412bcca7 100644
--- a/services/convert/issue.go
+++ b/services/convert/issue.go
@@ -59,6 +59,8 @@ func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Iss
Created: issue.CreatedUnix.AsTime(),
Updated: issue.UpdatedUnix.AsTime(),
PinOrder: util.Iif(issue.PinOrder == -1, 0, issue.PinOrder), // -1 means loaded with no pin order
+
+ TimeEstimate: issue.TimeEstimate,
}
if issue.Repo != nil {
diff --git a/services/cron/tasks_basic.go b/services/cron/tasks_basic.go
index 841981787df..48380b7b9ad 100644
--- a/services/cron/tasks_basic.go
+++ b/services/cron/tasks_basic.go
@@ -11,7 +11,7 @@ import (
git_model "code.gitea.io/gitea/models/git"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/migrations"
@@ -59,7 +59,7 @@ func registerRepoHealthCheck() {
}, func(ctx context.Context, _ *user_model.User, config Config) error {
rhcConfig := config.(*RepoHealthCheckConfig)
// the git args are set by config, they can be safe to be trusted
- return repo_service.GitFsckRepos(ctx, rhcConfig.Timeout, git.ToTrustedCmdArgs(rhcConfig.Args))
+ return repo_service.GitFsckRepos(ctx, rhcConfig.Timeout, gitcmd.ToTrustedCmdArgs(rhcConfig.Args))
})
}
diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go
index 37471119842..74fb12430d1 100644
--- a/services/cron/tasks_extended.go
+++ b/services/cron/tasks_extended.go
@@ -10,7 +10,7 @@ import (
activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/system"
user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/updatechecker"
@@ -61,7 +61,7 @@ func registerGarbageCollectRepositories() {
}, func(ctx context.Context, _ *user_model.User, config Config) error {
rhcConfig := config.(*RepoHealthCheckConfig)
// the git args are set by config, they can be safe to be trusted
- return repo_service.GitGcRepos(ctx, rhcConfig.Timeout, git.ToTrustedCmdArgs(rhcConfig.Args))
+ return repo_service.GitGcRepos(ctx, rhcConfig.Timeout, gitcmd.ToTrustedCmdArgs(rhcConfig.Args))
})
}
diff --git a/services/doctor/heads.go b/services/doctor/heads.go
index bbfd40da5ec..43545058069 100644
--- a/services/doctor/heads.go
+++ b/services/doctor/heads.go
@@ -8,6 +8,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
)
@@ -18,9 +19,9 @@ func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool)
numReposUpdated := 0
err := iterateRepositories(ctx, func(repo *repo_model.Repository) error {
numRepos++
- _, _, defaultBranchErr := git.NewCommand("rev-parse").AddDashesAndList(repo.DefaultBranch).RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()})
+ _, _, defaultBranchErr := gitcmd.NewCommand("rev-parse").AddDashesAndList(repo.DefaultBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
- head, _, headErr := git.NewCommand("symbolic-ref", "--short", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()})
+ head, _, headErr := gitcmd.NewCommand("symbolic-ref", "--short", "HEAD").RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
// what we expect: default branch is valid, and HEAD points to it
if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch {
@@ -46,7 +47,7 @@ func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool)
}
// otherwise, let's try fixing HEAD
- err := git.NewCommand("symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch).Run(ctx, &git.RunOpts{Dir: repo.RepoPath()})
+ err := gitcmd.NewCommand("symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch).Run(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
if err != nil {
logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err)
return nil
diff --git a/services/doctor/mergebase.go b/services/doctor/mergebase.go
index cbd8aa59fdb..a078d54dad6 100644
--- a/services/doctor/mergebase.go
+++ b/services/doctor/mergebase.go
@@ -12,6 +12,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
"xorm.io/builder"
@@ -42,17 +43,17 @@ func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) erro
if !pr.HasMerged {
var err error
- pr.MergeBase, _, err = git.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, pr.GetGitHeadRefName()).RunStdString(ctx, &git.RunOpts{Dir: repoPath})
+ pr.MergeBase, _, err = gitcmd.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, pr.GetGitHeadRefName()).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
if err != nil {
var err2 error
- pr.MergeBase, _, err2 = git.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(ctx, &git.RunOpts{Dir: repoPath})
+ pr.MergeBase, _, err2 = gitcmd.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix+pr.BaseBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
if err2 != nil {
logger.Warn("Unable to get merge base for PR ID %d, #%d onto %s in %s/%s. Error: %v & %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err, err2)
return nil
}
}
} else {
- parentsString, _, err := git.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &git.RunOpts{Dir: repoPath})
+ parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
if err != nil {
logger.Warn("Unable to get parents for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err)
return nil
@@ -64,8 +65,8 @@ func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) erro
refs := append([]string{}, parents[1:]...)
refs = append(refs, pr.GetGitHeadRefName())
- cmd := git.NewCommand("merge-base").AddDashesAndList(refs...)
- pr.MergeBase, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath})
+ cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
+ pr.MergeBase, _, err = cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath})
if err != nil {
logger.Warn("Unable to get merge base for merged PR ID %d, #%d onto %s in %s/%s. Error: %v", pr.ID, pr.Index, pr.BaseBranch, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, err)
return nil
diff --git a/services/forms/user_form.go b/services/forms/user_form.go
index ddf2bd09b0b..618294d4341 100644
--- a/services/forms/user_form.go
+++ b/services/forms/user_form.go
@@ -416,8 +416,8 @@ func (f *WebauthnDeleteForm) Validate(req *http.Request, errs binding.Errors) bi
// PackageSettingForm form for package settings
type PackageSettingForm struct {
- Action string
- RepoID int64 `form:"repo_id"`
+ Action string
+ RepoName string `form:"repo_name"`
}
// Validate validates the fields
diff --git a/services/forms/user_form_test.go b/services/forms/user_form_test.go
index 09e9ec0f65c..4246f955b3e 100644
--- a/services/forms/user_form_test.go
+++ b/services/forms/user_form_test.go
@@ -6,10 +6,10 @@ package forms
import (
"testing"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
- "github.com/gobwas/glob"
"github.com/stretchr/testify/assert"
)
diff --git a/services/gitdiff/git_diff_tree.go b/services/gitdiff/git_diff_tree.go
index ed94bfbfe45..eeb354c1b6e 100644
--- a/services/gitdiff/git_diff_tree.go
+++ b/services/gitdiff/git_diff_tree.go
@@ -13,6 +13,7 @@ import (
"strings"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
)
@@ -55,12 +56,12 @@ func runGitDiffTree(ctx context.Context, gitRepo *git.Repository, useMergeBase b
return nil, err
}
- cmd := git.NewCommand("diff-tree", "--raw", "-r", "--find-renames", "--root")
+ cmd := gitcmd.NewCommand("diff-tree", "--raw", "-r", "--find-renames", "--root")
if useMergeBase {
cmd.AddArguments("--merge-base")
}
cmd.AddDynamicArguments(baseCommitID, headCommitID)
- stdout, _, runErr := cmd.RunStdString(ctx, &git.RunOpts{Dir: gitRepo.Path})
+ stdout, _, runErr := cmd.RunStdString(ctx, &gitcmd.RunOpts{Dir: gitRepo.Path})
if runErr != nil {
log.Warn("git diff-tree: %v", runErr)
return nil, runErr
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go
index 7c99e049d54..1bb7c05ba2c 100644
--- a/services/gitdiff/gitdiff.go
+++ b/services/gitdiff/gitdiff.go
@@ -26,6 +26,7 @@ import (
"code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/git/attribute"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/highlight"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
@@ -1090,7 +1091,7 @@ type DiffOptions struct {
MaxLines int
MaxLineCharacters int
MaxFiles int
- WhitespaceBehavior git.TrustedCmdArgs
+ WhitespaceBehavior gitcmd.TrustedCmdArgs
DirectComparison bool
}
@@ -1131,7 +1132,7 @@ func getDiffBasic(ctx context.Context, gitRepo *git.Repository, opts *DiffOption
return nil, nil, nil, err
}
- cmdDiff := git.NewCommand().
+ cmdDiff := gitcmd.NewCommand().
AddArguments("diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M").
AddArguments(opts.WhitespaceBehavior...)
@@ -1158,7 +1159,7 @@ func getDiffBasic(ctx context.Context, gitRepo *git.Repository, opts *DiffOption
go func() {
stderr := &bytes.Buffer{}
- if err := cmdDiff.Run(cmdCtx, &git.RunOpts{
+ if err := cmdDiff.Run(cmdCtx, &gitcmd.RunOpts{
Timeout: time.Duration(setting.Git.Timeout.Default) * time.Second,
Dir: repoPath,
Stdout: writer,
@@ -1395,8 +1396,8 @@ func CommentMustAsDiff(ctx context.Context, c *issues_model.Comment) *Diff {
}
// GetWhitespaceFlag returns git diff flag for treating whitespaces
-func GetWhitespaceFlag(whitespaceBehavior string) git.TrustedCmdArgs {
- whitespaceFlags := map[string]git.TrustedCmdArgs{
+func GetWhitespaceFlag(whitespaceBehavior string) gitcmd.TrustedCmdArgs {
+ whitespaceFlags := map[string]gitcmd.TrustedCmdArgs{
"ignore-all": {"-w"},
"ignore-change": {"-b"},
"ignore-eol": {"--ignore-space-at-eol"},
diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go
index 83815caeb56..7b64b6b5f8a 100644
--- a/services/gitdiff/gitdiff_test.go
+++ b/services/gitdiff/gitdiff_test.go
@@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting"
@@ -602,7 +603,7 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
require.NoError(t, err)
defer gitRepo.Close()
- for _, behavior := range []git.TrustedCmdArgs{{"-w"}, {"--ignore-space-at-eol"}, {"-b"}, nil} {
+ for _, behavior := range []gitcmd.TrustedCmdArgs{{"-w"}, {"--ignore-space-at-eol"}, {"-b"}, nil} {
diffs, err := GetDiffForAPI(t.Context(), gitRepo,
&DiffOptions{
AfterCommitID: "d8e0bbb45f200e67d9a784ce55bd90821af45ebd",
diff --git a/services/issue/issue.go b/services/issue/issue.go
index b9ee66c1f27..611fc6806b1 100644
--- a/services/issue/issue.go
+++ b/services/issue/issue.go
@@ -17,6 +17,7 @@ import (
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/gitrepo"
"code.gitea.io/gitea/modules/storage"
notify_service "code.gitea.io/gitea/services/notify"
)
@@ -165,7 +166,7 @@ func UpdateAssignees(ctx context.Context, issue *issues_model.Issue, oneAssignee
}
// DeleteIssue deletes an issue
-func DeleteIssue(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue) error {
+func DeleteIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) error {
// load issue before deleting it
if err := issue.LoadAttributes(ctx); err != nil {
return err
@@ -184,8 +185,11 @@ func DeleteIssue(ctx context.Context, doer *user_model.User, gitRepo *git.Reposi
}
// delete pull request related git data
- if issue.IsPull && gitRepo != nil {
- if err := gitRepo.RemoveReference(issue.PullRequest.GetGitHeadRefName()); err != nil {
+ if issue.IsPull {
+ if err := issue.PullRequest.LoadBaseRepo(ctx); err != nil {
+ return err
+ }
+ if err := gitrepo.RemoveRef(ctx, issue.PullRequest.BaseRepo, issue.PullRequest.GetGitHeadRefName()); err != nil {
return err
}
}
@@ -246,74 +250,67 @@ func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[i
// deleteIssue deletes the issue
func deleteIssue(ctx context.Context, issue *issues_model.Issue) ([]string, error) {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return nil, err
- }
- defer committer.Close()
-
- if _, err := db.GetEngine(ctx).ID(issue.ID).NoAutoCondition().Delete(issue); err != nil {
- return nil, err
- }
-
- // update the total issue numbers
- if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, false); err != nil {
- return nil, err
- }
- // if the issue is closed, update the closed issue numbers
- if issue.IsClosed {
- if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, true); err != nil {
+ return db.WithTx2(ctx, func(ctx context.Context) ([]string, error) {
+ if _, err := db.GetEngine(ctx).ID(issue.ID).NoAutoCondition().Delete(issue); err != nil {
return nil, err
}
- }
- if err := issues_model.UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil {
- return nil, fmt.Errorf("error updating counters for milestone id %d: %w",
- issue.MilestoneID, err)
- }
+ // update the total issue numbers
+ if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, false); err != nil {
+ return nil, err
+ }
+ // if the issue is closed, update the closed issue numbers
+ if issue.IsClosed {
+ if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, true); err != nil {
+ return nil, err
+ }
+ }
- if err := activities_model.DeleteIssueActions(ctx, issue.RepoID, issue.ID, issue.Index); err != nil {
- return nil, err
- }
+ if err := issues_model.UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil {
+ return nil, fmt.Errorf("error updating counters for milestone id %d: %w",
+ issue.MilestoneID, err)
+ }
- // find attachments related to this issue and remove them
- if err := issue.LoadAttachments(ctx); err != nil {
- return nil, err
- }
+ if err := activities_model.DeleteIssueActions(ctx, issue.RepoID, issue.ID, issue.Index); err != nil {
+ return nil, err
+ }
- var attachmentPaths []string
- for i := range issue.Attachments {
- attachmentPaths = append(attachmentPaths, issue.Attachments[i].RelativePath())
- }
+ // find attachments related to this issue and remove them
+ if err := issue.LoadAttachments(ctx); err != nil {
+ return nil, err
+ }
- // delete all database data still assigned to this issue
- if err := db.DeleteBeans(ctx,
- &issues_model.ContentHistory{IssueID: issue.ID},
- &issues_model.Comment{IssueID: issue.ID},
- &issues_model.IssueLabel{IssueID: issue.ID},
- &issues_model.IssueDependency{IssueID: issue.ID},
- &issues_model.IssueAssignees{IssueID: issue.ID},
- &issues_model.IssueUser{IssueID: issue.ID},
- &activities_model.Notification{IssueID: issue.ID},
- &issues_model.Reaction{IssueID: issue.ID},
- &issues_model.IssueWatch{IssueID: issue.ID},
- &issues_model.Stopwatch{IssueID: issue.ID},
- &issues_model.TrackedTime{IssueID: issue.ID},
- &project_model.ProjectIssue{IssueID: issue.ID},
- &repo_model.Attachment{IssueID: issue.ID},
- &issues_model.PullRequest{IssueID: issue.ID},
- &issues_model.Comment{RefIssueID: issue.ID},
- &issues_model.IssueDependency{DependencyID: issue.ID},
- &issues_model.Comment{DependentIssueID: issue.ID},
- &issues_model.IssuePin{IssueID: issue.ID},
- ); err != nil {
- return nil, err
- }
+ var attachmentPaths []string
+ for i := range issue.Attachments {
+ attachmentPaths = append(attachmentPaths, issue.Attachments[i].RelativePath())
+ }
- if err := committer.Commit(); err != nil {
- return nil, err
- }
- return attachmentPaths, nil
+ // delete all database data still assigned to this issue
+ if err := db.DeleteBeans(ctx,
+ &issues_model.ContentHistory{IssueID: issue.ID},
+ &issues_model.Comment{IssueID: issue.ID},
+ &issues_model.IssueLabel{IssueID: issue.ID},
+ &issues_model.IssueDependency{IssueID: issue.ID},
+ &issues_model.IssueAssignees{IssueID: issue.ID},
+ &issues_model.IssueUser{IssueID: issue.ID},
+ &activities_model.Notification{IssueID: issue.ID},
+ &issues_model.Reaction{IssueID: issue.ID},
+ &issues_model.IssueWatch{IssueID: issue.ID},
+ &issues_model.Stopwatch{IssueID: issue.ID},
+ &issues_model.TrackedTime{IssueID: issue.ID},
+ &project_model.ProjectIssue{IssueID: issue.ID},
+ &repo_model.Attachment{IssueID: issue.ID},
+ &issues_model.PullRequest{IssueID: issue.ID},
+ &issues_model.Comment{RefIssueID: issue.ID},
+ &issues_model.IssueDependency{DependencyID: issue.ID},
+ &issues_model.Comment{DependentIssueID: issue.ID},
+ &issues_model.IssuePin{IssueID: issue.ID},
+ ); err != nil {
+ return nil, err
+ }
+
+ return attachmentPaths, nil
+ })
}
// DeleteOrphanedIssues delete issues without a repo
diff --git a/services/migrations/dump.go b/services/migrations/dump.go
index 8edd567b082..385759800e4 100644
--- a/services/migrations/dump.go
+++ b/services/migrations/dump.go
@@ -18,6 +18,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
base "code.gitea.io/gitea/modules/migration"
"code.gitea.io/gitea/modules/repository"
@@ -488,7 +489,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
if pr.Head.CloneURL == "" || pr.Head.Ref == "" {
// Set head information if pr.Head.SHA is available
if pr.Head.SHA != "" {
- _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()})
+ _, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
if err != nil {
log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err)
}
@@ -518,7 +519,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
if !ok {
// Set head information if pr.Head.SHA is available
if pr.Head.SHA != "" {
- _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()})
+ _, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
if err != nil {
log.Error("PR #%d in %s/%s unable to update-ref for pr HEAD: %v", pr.Number, g.repoOwner, g.repoName, err)
}
@@ -553,7 +554,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
fetchArg = git.BranchPrefix + fetchArg
}
- _, _, err = git.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()})
+ _, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
if err != nil {
log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
// We need to continue here so that the Head.Ref is reset and we attempt to set the gitref for the PR
@@ -577,7 +578,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
pr.Head.SHA = headSha
}
if pr.Head.SHA != "" {
- _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.gitPath()})
+ _, _, err = gitcmd.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.gitPath()})
if err != nil {
log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err)
}
diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go
index 75eb06d01fa..02c61bd0f16 100644
--- a/services/migrations/gitea_uploader.go
+++ b/services/migrations/gitea_uploader.go
@@ -20,6 +20,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/label"
"code.gitea.io/gitea/modules/log"
@@ -662,7 +663,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba
fetchArg = git.BranchPrefix + fetchArg
}
- _, _, err = git.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()})
+ _, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.repo.RepoPath()})
if err != nil {
log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err)
return head, nil
@@ -681,8 +682,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba
pr.Head.SHA = headSha
}
- _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()})
- if err != nil {
+ if err = gitrepo.UpdateRef(ctx, g.repo, pr.GetGitHeadRefName(), pr.Head.SHA); err != nil {
return "", err
}
@@ -698,14 +698,13 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba
// The SHA is empty
log.Warn("Empty reference, no pull head for PR #%d in %s/%s", pr.Number, g.repoOwner, g.repoName)
} else {
- _, _, err = git.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()})
+ _, _, err = gitcmd.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(ctx, &gitcmd.RunOpts{Dir: g.repo.RepoPath()})
if err != nil {
// Git update-ref remove bad references with a relative path
log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitHeadRefName())
} else {
// set head information
- _, _, err = git.NewCommand("update-ref", "--no-deref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.Head.SHA).RunStdString(ctx, &git.RunOpts{Dir: g.repo.RepoPath()})
- if err != nil {
+ if err = gitrepo.UpdateRef(ctx, g.repo, pr.GetGitHeadRefName(), pr.Head.SHA); err != nil {
log.Error("unable to set %s as the local head for PR #%d from %s in %s/%s. Error: %v", pr.Head.SHA, pr.Number, pr.Head.Ref, g.repoOwner, g.repoName, err)
}
}
diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go
index 4856b66c6e1..08efef5de6d 100644
--- a/services/migrations/gitea_uploader_test.go
+++ b/services/migrations/gitea_uploader_test.go
@@ -18,6 +18,7 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
@@ -238,7 +239,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
baseRef := "master"
// this is very different from the real situation. It should be a bare repository for all the Gitea managed repositories
assert.NoError(t, git.InitRepository(t.Context(), fromRepo.RepoPath(), false, fromRepo.ObjectFormatName))
- err := git.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(t.Context(), &git.RunOpts{Dir: fromRepo.RepoPath()})
+ err := gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(t.Context(), &gitcmd.RunOpts{Dir: fromRepo.RepoPath()})
assert.NoError(t, err)
assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("# Testing Repository\n\nOriginally created in: "+fromRepo.RepoPath()), 0o644))
assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true))
@@ -262,7 +263,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
// fromRepo branch1
//
headRef := "branch1"
- _, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(headRef).RunStdString(t.Context(), &git.RunOpts{Dir: fromRepo.RepoPath()})
+ _, _, err = gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(headRef).RunStdString(t.Context(), &gitcmd.RunOpts{Dir: fromRepo.RepoPath()})
assert.NoError(t, err)
assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644))
assert.NoError(t, git.AddChanges(t.Context(), fromRepo.RepoPath(), true))
@@ -286,7 +287,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
assert.NoError(t, git.Clone(t.Context(), fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{
Branch: headRef,
}))
- _, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(t.Context(), &git.RunOpts{Dir: forkRepo.RepoPath()})
+ _, _, err = gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(t.Context(), &gitcmd.RunOpts{Dir: forkRepo.RepoPath()})
assert.NoError(t, err)
assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte("# branch2 "+forkRepo.RepoPath()), 0o644))
assert.NoError(t, git.AddChanges(t.Context(), forkRepo.RepoPath(), true))
diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go
index b9000f27034..6a87aa8a274 100644
--- a/services/mirror/mirror_pull.go
+++ b/services/mirror/mirror_pull.go
@@ -13,6 +13,7 @@ import (
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
giturl "code.gitea.io/gitea/modules/git/url"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/globallock"
@@ -255,7 +256,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
log.Trace("SyncMirrors [repo: %-v]: running git remote update...", m.Repo)
// use fetch but not remote update because git fetch support --tags but remote update doesn't
- cmd := git.NewCommand("fetch")
+ cmd := gitcmd.NewCommand("fetch")
if m.EnablePrune {
cmd.AddArguments("--prune")
}
@@ -271,7 +272,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
stdoutBuilder := strings.Builder{}
stderrBuilder := strings.Builder{}
- if err := cmd.Run(ctx, &git.RunOpts{
+ if err := cmd.Run(ctx, &gitcmd.RunOpts{
Timeout: timeout,
Dir: repoPath,
Env: envs,
@@ -296,7 +297,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
// Successful prune - reattempt mirror
stderrBuilder.Reset()
stdoutBuilder.Reset()
- if err = cmd.Run(ctx, &git.RunOpts{
+ if err = cmd.Run(ctx, &gitcmd.RunOpts{
Timeout: timeout,
Dir: repoPath,
Stdout: &stdoutBuilder,
diff --git a/services/org/org.go b/services/org/org.go
index 142a643f9fc..8da77c691c1 100644
--- a/services/org/org.go
+++ b/services/org/org.go
@@ -52,39 +52,34 @@ func deleteOrganization(ctx context.Context, org *org_model.Organization) error
// DeleteOrganization completely and permanently deletes everything of organization.
func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge bool) error {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if purge {
- err := repo_service.DeleteOwnerRepositoriesDirectly(ctx, org.AsUser())
- if err != nil {
- return err
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ if purge {
+ err := repo_service.DeleteOwnerRepositoriesDirectly(ctx, org.AsUser())
+ if err != nil {
+ return err
+ }
}
- }
- // Check ownership of repository.
- count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: org.ID})
- if err != nil {
- return fmt.Errorf("GetRepositoryCount: %w", err)
- } else if count > 0 {
- return repo_model.ErrUserOwnRepos{UID: org.ID}
- }
+ // Check ownership of repository.
+ count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: org.ID})
+ if err != nil {
+ return fmt.Errorf("GetRepositoryCount: %w", err)
+ } else if count > 0 {
+ return repo_model.ErrUserOwnRepos{UID: org.ID}
+ }
- // Check ownership of packages.
- if ownsPackages, err := packages_model.HasOwnerPackages(ctx, org.ID); err != nil {
- return fmt.Errorf("HasOwnerPackages: %w", err)
- } else if ownsPackages {
- return packages_model.ErrUserOwnPackages{UID: org.ID}
- }
+ // Check ownership of packages.
+ if ownsPackages, err := packages_model.HasOwnerPackages(ctx, org.ID); err != nil {
+ return fmt.Errorf("HasOwnerPackages: %w", err)
+ } else if ownsPackages {
+ return packages_model.ErrUserOwnPackages{UID: org.ID}
+ }
- if err := deleteOrganization(ctx, org); err != nil {
- return fmt.Errorf("DeleteOrganization: %w", err)
- }
-
- if err := committer.Commit(); err != nil {
+ if err := deleteOrganization(ctx, org); err != nil {
+ return fmt.Errorf("DeleteOrganization: %w", err)
+ }
+ return nil
+ }); err != nil {
return err
}
diff --git a/services/org/user.go b/services/org/user.go
index 26927253d25..68582718582 100644
--- a/services/org/user.go
+++ b/services/org/user.go
@@ -47,57 +47,52 @@ func RemoveOrgUser(ctx context.Context, org *organization.Organization, user *us
}
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ if _, err := db.DeleteByID[organization.OrgUser](ctx, ou.ID); err != nil {
+ return err
+ } else if _, err = db.Exec(ctx, "UPDATE `user` SET num_members=num_members-1 WHERE id=?", org.ID); err != nil {
+ return err
+ }
- if _, err := db.DeleteByID[organization.OrgUser](ctx, ou.ID); err != nil {
- return err
- } else if _, err = db.Exec(ctx, "UPDATE `user` SET num_members=num_members-1 WHERE id=?", org.ID); err != nil {
- return err
- }
+ // Delete all repository accesses and unwatch them.
+ env, err := repo_model.AccessibleReposEnv(ctx, org, user.ID)
+ if err != nil {
+ return fmt.Errorf("AccessibleReposEnv: %w", err)
+ }
+ repoIDs, err := env.RepoIDs(ctx)
+ if err != nil {
+ return fmt.Errorf("GetUserRepositories [%d]: %w", user.ID, err)
+ }
- // Delete all repository accesses and unwatch them.
- env, err := repo_model.AccessibleReposEnv(ctx, org, user.ID)
- if err != nil {
- return fmt.Errorf("AccessibleReposEnv: %w", err)
- }
- repoIDs, err := env.RepoIDs(ctx)
- if err != nil {
- return fmt.Errorf("GetUserRepositories [%d]: %w", user.ID, err)
- }
+ for _, repoID := range repoIDs {
+ repo, err := repo_model.GetRepositoryByID(ctx, repoID)
+ if err != nil {
+ return err
+ }
+ if err = repo_model.WatchRepo(ctx, user, repo, false); err != nil {
+ return err
+ }
+ }
- for _, repoID := range repoIDs {
- repo, err := repo_model.GetRepositoryByID(ctx, repoID)
+ if len(repoIDs) > 0 {
+ if _, err = db.GetEngine(ctx).
+ Where("user_id = ?", user.ID).
+ In("repo_id", repoIDs).
+ Delete(new(access_model.Access)); err != nil {
+ return err
+ }
+ }
+
+ // Delete member in their teams.
+ teams, err := organization.GetUserOrgTeams(ctx, org.ID, user.ID)
if err != nil {
return err
}
- if err = repo_model.WatchRepo(ctx, user, repo, false); err != nil {
- return err
+ for _, t := range teams {
+ if err = removeTeamMember(ctx, t, user); err != nil {
+ return err
+ }
}
- }
-
- if len(repoIDs) > 0 {
- if _, err = db.GetEngine(ctx).
- Where("user_id = ?", user.ID).
- In("repo_id", repoIDs).
- Delete(new(access_model.Access)); err != nil {
- return err
- }
- }
-
- // Delete member in their teams.
- teams, err := organization.GetUserOrgTeams(ctx, org.ID, user.ID)
- if err != nil {
- return err
- }
- for _, t := range teams {
- if err = removeTeamMember(ctx, t, user); err != nil {
- return err
- }
- }
-
- return committer.Commit()
+ return nil
+ })
}
diff --git a/services/pull/check.go b/services/pull/check.go
index 7fcec22f492..c2ee49b6bb4 100644
--- a/services/pull/check.go
+++ b/services/pull/check.go
@@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/globallock"
"code.gitea.io/gitea/modules/graceful"
@@ -280,9 +281,9 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com
prHeadRef := pr.GetGitHeadRefName()
// Check if the pull request is merged into BaseBranch
- if _, _, err := git.NewCommand("merge-base", "--is-ancestor").
+ if _, _, err := gitcmd.NewCommand("merge-base", "--is-ancestor").
AddDynamicArguments(prHeadRef, pr.BaseBranch).
- RunStdString(ctx, &git.RunOpts{Dir: pr.BaseRepo.RepoPath()}); err != nil {
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: pr.BaseRepo.RepoPath()}); err != nil {
if strings.Contains(err.Error(), "exit status 1") {
// prHeadRef is not an ancestor of the base branch
return nil, nil
@@ -308,9 +309,9 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com
objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
// Get the commit from BaseBranch where the pull request got merged
- mergeCommit, _, err := git.NewCommand("rev-list", "--ancestry-path", "--merges", "--reverse").
+ mergeCommit, _, err := gitcmd.NewCommand("rev-list", "--ancestry-path", "--merges", "--reverse").
AddDynamicArguments(prHeadCommitID+".."+pr.BaseBranch).
- RunStdString(ctx, &git.RunOpts{Dir: pr.BaseRepo.RepoPath()})
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: pr.BaseRepo.RepoPath()})
if err != nil {
return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %w", err)
} else if len(mergeCommit) < objectFormat.FullLength() {
diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go
index d15d3181497..e7c14a5e7aa 100644
--- a/services/pull/commit_status.go
+++ b/services/pull/commit_status.go
@@ -12,9 +12,9 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/commitstatus"
"code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log"
- "github.com/gobwas/glob"
"github.com/pkg/errors"
)
diff --git a/services/pull/merge.go b/services/pull/merge.go
index a941c204357..4d6afb8d338 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -26,6 +26,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/globallock"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
@@ -400,7 +401,7 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use
)
mergeCtx.env = append(mergeCtx.env, repo_module.EnvPushTrigger+"="+string(pushTrigger))
- pushCmd := git.NewCommand("push", "origin").AddDynamicArguments(baseBranch + ":" + git.BranchPrefix + pr.BaseBranch)
+ pushCmd := gitcmd.NewCommand("push", "origin").AddDynamicArguments(baseBranch + ":" + git.BranchPrefix + pr.BaseBranch)
// Push back to upstream.
// This cause an api call to "/api/internal/hook/post-receive/...",
@@ -430,7 +431,7 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use
}
func commitAndSignNoAuthor(ctx *mergeContext, message string) error {
- cmdCommit := git.NewCommand("commit").AddOptionFormat("--message=%s", message)
+ cmdCommit := gitcmd.NewCommand("commit").AddOptionFormat("--message=%s", message)
if ctx.signKey == nil {
cmdCommit.AddArguments("--no-gpg-sign")
} else {
@@ -499,7 +500,7 @@ func (err ErrMergeDivergingFastForwardOnly) Error() string {
return fmt.Sprintf("Merge DivergingFastForwardOnly Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
}
-func runMergeCommand(ctx *mergeContext, mergeStyle repo_model.MergeStyle, cmd *git.Command) error {
+func runMergeCommand(ctx *mergeContext, mergeStyle repo_model.MergeStyle, cmd *gitcmd.Command) error {
if err := cmd.Run(ctx, ctx.RunOpts()); err != nil {
// Merge will leave a MERGE_HEAD file in the .git folder if there is a conflict
if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "MERGE_HEAD")); statErr == nil {
diff --git a/services/pull/merge_ff_only.go b/services/pull/merge_ff_only.go
index 6c3a68b95b3..22a560e29ca 100644
--- a/services/pull/merge_ff_only.go
+++ b/services/pull/merge_ff_only.go
@@ -5,13 +5,13 @@ package pull
import (
repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
)
// doMergeStyleFastForwardOnly merges the tracking into the current HEAD - which is assumed to be staging branch (equal to the pr.BaseBranch)
func doMergeStyleFastForwardOnly(ctx *mergeContext) error {
- cmd := git.NewCommand("merge", "--ff-only").AddDynamicArguments(trackingBranch)
+ cmd := gitcmd.NewCommand("merge", "--ff-only").AddDynamicArguments(trackingBranch)
if err := runMergeCommand(ctx, repo_model.MergeStyleFastForwardOnly, cmd); err != nil {
log.Error("%-v Unable to merge tracking into base: %v", ctx.pr, err)
return err
diff --git a/services/pull/merge_merge.go b/services/pull/merge_merge.go
index 118d21c7cd9..bc94400f216 100644
--- a/services/pull/merge_merge.go
+++ b/services/pull/merge_merge.go
@@ -5,13 +5,13 @@ package pull
import (
repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
)
// doMergeStyleMerge merges the tracking branch into the current HEAD - which is assumed to be the staging branch (equal to the pr.BaseBranch)
func doMergeStyleMerge(ctx *mergeContext, message string) error {
- cmd := git.NewCommand("merge", "--no-ff", "--no-commit").AddDynamicArguments(trackingBranch)
+ cmd := gitcmd.NewCommand("merge", "--no-ff", "--no-commit").AddDynamicArguments(trackingBranch)
if err := runMergeCommand(ctx, repo_model.MergeStyleMerge, cmd); err != nil {
log.Error("%-v Unable to merge tracking into base: %v", ctx.pr, err)
return err
diff --git a/services/pull/merge_prepare.go b/services/pull/merge_prepare.go
index 31a1e137344..d7152560d21 100644
--- a/services/pull/merge_prepare.go
+++ b/services/pull/merge_prepare.go
@@ -18,6 +18,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
asymkey_service "code.gitea.io/gitea/services/asymkey"
)
@@ -31,10 +32,10 @@ type mergeContext struct {
env []string
}
-func (ctx *mergeContext) RunOpts() *git.RunOpts {
+func (ctx *mergeContext) RunOpts() *gitcmd.RunOpts {
ctx.outbuf.Reset()
ctx.errbuf.Reset()
- return &git.RunOpts{
+ return &gitcmd.RunOpts{
Env: ctx.env,
Dir: ctx.tmpBasePath,
Stdout: ctx.outbuf,
@@ -73,7 +74,7 @@ func createTemporaryRepoForMerge(ctx context.Context, pr *issues_model.PullReque
}
if expectedHeadCommitID != "" {
- trackingCommitID, _, err := git.NewCommand("show-ref", "--hash").AddDynamicArguments(git.BranchPrefix+trackingBranch).RunStdString(ctx, &git.RunOpts{Dir: mergeCtx.tmpBasePath})
+ trackingCommitID, _, err := gitcmd.NewCommand("show-ref", "--hash").AddDynamicArguments(git.BranchPrefix+trackingBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: mergeCtx.tmpBasePath})
if err != nil {
defer cancel()
log.Error("failed to get sha of head branch in %-v: show-ref[%s] --hash refs/heads/tracking: %v", mergeCtx.pr, mergeCtx.tmpBasePath, err)
@@ -151,7 +152,7 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error {
}
setConfig := func(key, value string) error {
- if err := git.NewCommand("config", "--local").AddDynamicArguments(key, value).
+ if err := gitcmd.NewCommand("config", "--local").AddDynamicArguments(key, value).
Run(ctx, ctx.RunOpts()); err != nil {
log.Error("git config [%s -> %q]: %v\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
return fmt.Errorf("git config [%s -> %q]: %w\n%s\n%s", key, value, err, ctx.outbuf.String(), ctx.errbuf.String())
@@ -184,7 +185,7 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error {
}
// Read base branch index
- if err := git.NewCommand("read-tree", "HEAD").
+ if err := gitcmd.NewCommand("read-tree", "HEAD").
Run(ctx, ctx.RunOpts()); err != nil {
log.Error("git read-tree HEAD: %v\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String())
return fmt.Errorf("Unable to read base branch in to the index: %w\n%s\n%s", err, ctx.outbuf.String(), ctx.errbuf.String())
@@ -221,8 +222,8 @@ func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string, o
return 0, nil, nil
}
- err = git.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-r", "-z", "--root").AddDynamicArguments(baseBranch, headBranch).
- Run(ctx, &git.RunOpts{
+ err = gitcmd.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-r", "-z", "--root").AddDynamicArguments(baseBranch, headBranch).
+ Run(ctx, &gitcmd.RunOpts{
Dir: repoPath,
Stdout: diffOutWriter,
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
@@ -272,7 +273,7 @@ func (err ErrRebaseConflicts) Error() string {
// if there is a conflict it will return an ErrRebaseConflicts
func rebaseTrackingOnToBase(ctx *mergeContext, mergeStyle repo_model.MergeStyle) error {
// Checkout head branch
- if err := git.NewCommand("checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch).
+ if err := gitcmd.NewCommand("checkout", "-b").AddDynamicArguments(stagingBranch, trackingBranch).
Run(ctx, ctx.RunOpts()); err != nil {
return fmt.Errorf("unable to git checkout tracking as staging in temp repo for %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
}
@@ -280,7 +281,7 @@ func rebaseTrackingOnToBase(ctx *mergeContext, mergeStyle repo_model.MergeStyle)
ctx.errbuf.Reset()
// Rebase before merging
- if err := git.NewCommand("rebase").AddDynamicArguments(baseBranch).
+ if err := gitcmd.NewCommand("rebase").AddDynamicArguments(baseBranch).
Run(ctx, ctx.RunOpts()); err != nil {
// Rebase will leave a REBASE_HEAD file in .git if there is a conflict
if _, statErr := os.Stat(filepath.Join(ctx.tmpBasePath, ".git", "REBASE_HEAD")); statErr == nil {
diff --git a/services/pull/merge_rebase.go b/services/pull/merge_rebase.go
index dd7c8761f00..1d7395ebca1 100644
--- a/services/pull/merge_rebase.go
+++ b/services/pull/merge_rebase.go
@@ -9,6 +9,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
)
@@ -16,7 +17,7 @@ import (
// getRebaseAmendMessage composes the message to amend commits in rebase merge of a pull request.
func getRebaseAmendMessage(ctx *mergeContext, baseGitRepo *git.Repository) (message string, err error) {
// Get existing commit message.
- commitMessage, _, err := git.NewCommand("show", "--format=%B", "-s").RunStdString(ctx, &git.RunOpts{Dir: ctx.tmpBasePath})
+ commitMessage, _, err := gitcmd.NewCommand("show", "--format=%B", "-s").RunStdString(ctx, &gitcmd.RunOpts{Dir: ctx.tmpBasePath})
if err != nil {
return "", err
}
@@ -42,7 +43,7 @@ func doMergeRebaseFastForward(ctx *mergeContext) error {
return fmt.Errorf("Failed to get full commit id for HEAD: %w", err)
}
- cmd := git.NewCommand("merge", "--ff-only").AddDynamicArguments(stagingBranch)
+ cmd := gitcmd.NewCommand("merge", "--ff-only").AddDynamicArguments(stagingBranch)
if err := runMergeCommand(ctx, repo_model.MergeStyleRebase, cmd); err != nil {
log.Error("Unable to merge staging into base: %v", err)
return err
@@ -73,7 +74,7 @@ func doMergeRebaseFastForward(ctx *mergeContext) error {
}
if newMessage != "" {
- if err := git.NewCommand("commit", "--amend").AddOptionFormat("--message=%s", newMessage).Run(ctx, &git.RunOpts{Dir: ctx.tmpBasePath}); err != nil {
+ if err := gitcmd.NewCommand("commit", "--amend").AddOptionFormat("--message=%s", newMessage).Run(ctx, &gitcmd.RunOpts{Dir: ctx.tmpBasePath}); err != nil {
log.Error("Unable to amend commit message: %v", err)
return err
}
@@ -84,7 +85,7 @@ func doMergeRebaseFastForward(ctx *mergeContext) error {
// Perform rebase merge with merge commit.
func doMergeRebaseMergeCommit(ctx *mergeContext, message string) error {
- cmd := git.NewCommand("merge").AddArguments("--no-ff", "--no-commit").AddDynamicArguments(stagingBranch)
+ cmd := gitcmd.NewCommand("merge").AddArguments("--no-ff", "--no-commit").AddDynamicArguments(stagingBranch)
if err := runMergeCommand(ctx, repo_model.MergeStyleRebaseMerge, cmd); err != nil {
log.Error("Unable to merge staging into base: %v", err)
@@ -105,7 +106,7 @@ func doMergeStyleRebase(ctx *mergeContext, mergeStyle repo_model.MergeStyle, mes
}
// Checkout base branch again
- if err := git.NewCommand("checkout").AddDynamicArguments(baseBranch).
+ if err := gitcmd.NewCommand("checkout").AddDynamicArguments(baseBranch).
Run(ctx, ctx.RunOpts()); err != nil {
log.Error("git checkout base prior to merge post staging rebase %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
return fmt.Errorf("git checkout base prior to merge post staging rebase %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String())
diff --git a/services/pull/merge_squash.go b/services/pull/merge_squash.go
index 0049c0b117d..99c4311e045 100644
--- a/services/pull/merge_squash.go
+++ b/services/pull/merge_squash.go
@@ -10,6 +10,7 @@ import (
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/git/gitcmd"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
@@ -57,7 +58,7 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error {
return fmt.Errorf("getAuthorSignatureSquash: %w", err)
}
- cmdMerge := git.NewCommand("merge", "--squash").AddDynamicArguments(trackingBranch)
+ cmdMerge := gitcmd.NewCommand("merge", "--squash").AddDynamicArguments(trackingBranch)
if err := runMergeCommand(ctx, repo_model.MergeStyleSquash, cmdMerge); err != nil {
log.Error("%-v Unable to merge --squash tracking into base: %v", ctx.pr, err)
return err
@@ -68,7 +69,7 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error {
message = AddCommitMessageTailer(message, "Co-authored-by", sig.String())
message = AddCommitMessageTailer(message, "Co-committed-by", sig.String()) // FIXME: this one should be removed, it is not really used or widely used
}
- cmdCommit := git.NewCommand("commit").
+ cmdCommit := gitcmd.NewCommand("commit").
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email).
AddOptionFormat("--message=%s", message)
if ctx.signKey == nil {
diff --git a/services/pull/patch.go b/services/pull/patch.go
index 9d9b8d0d076..674ae012535 100644
--- a/services/pull/patch.go
+++ b/services/pull/patch.go
@@ -18,14 +18,14 @@ import (
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
-
- "github.com/gobwas/glob"
)
// DownloadDiffOrPatch will write the patch for the pr to the writer
@@ -91,7 +91,7 @@ func testPullRequestTmpRepoBranchMergeable(ctx context.Context, prCtx *prTmpRepo
defer gitRepo.Close()
// 1. update merge base
- pr.MergeBase, _, err = git.NewCommand("merge-base", "--", "base", "tracking").RunStdString(ctx, &git.RunOpts{Dir: prCtx.tmpBasePath})
+ pr.MergeBase, _, err = gitcmd.NewCommand("merge-base", "--", "base", "tracking").RunStdString(ctx, &gitcmd.RunOpts{Dir: prCtx.tmpBasePath})
if err != nil {
var err2 error
pr.MergeBase, err2 = gitRepo.GetRefCommitID(git.BranchPrefix + "base")
@@ -191,7 +191,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
}
// Need to get the objects from the object db to attempt to merge
- root, _, err := git.NewCommand("unpack-file").AddDynamicArguments(file.stage1.sha).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath})
+ root, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage1.sha).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
if err != nil {
return fmt.Errorf("unable to get root object: %s at path: %s for merging. Error: %w", file.stage1.sha, file.stage1.path, err)
}
@@ -200,7 +200,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
_ = util.Remove(filepath.Join(tmpBasePath, root))
}()
- base, _, err := git.NewCommand("unpack-file").AddDynamicArguments(file.stage2.sha).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath})
+ base, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage2.sha).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
if err != nil {
return fmt.Errorf("unable to get base object: %s at path: %s for merging. Error: %w", file.stage2.sha, file.stage2.path, err)
}
@@ -208,7 +208,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
defer func() {
_ = util.Remove(base)
}()
- head, _, err := git.NewCommand("unpack-file").AddDynamicArguments(file.stage3.sha).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath})
+ head, _, err := gitcmd.NewCommand("unpack-file").AddDynamicArguments(file.stage3.sha).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
if err != nil {
return fmt.Errorf("unable to get head object:%s at path: %s for merging. Error: %w", file.stage3.sha, file.stage3.path, err)
}
@@ -218,13 +218,13 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, f
}()
// now git merge-file annoyingly takes a different order to the merge-tree ...
- _, _, conflictErr := git.NewCommand("merge-file").AddDynamicArguments(base, root, head).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath})
+ _, _, conflictErr := gitcmd.NewCommand("merge-file").AddDynamicArguments(base, root, head).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
if conflictErr != nil {
return &errMergeConflict{file.stage2.path}
}
// base now contains the merged data
- hash, _, err := git.NewCommand("hash-object", "-w", "--path").AddDynamicArguments(file.stage2.path, base).RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath})
+ hash, _, err := gitcmd.NewCommand("hash-object", "-w", "--path").AddDynamicArguments(file.stage2.path, base).RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
if err != nil {
return err
}
@@ -249,7 +249,7 @@ func AttemptThreeWayMerge(ctx context.Context, gitPath string, gitRepo *git.Repo
defer cancel()
// First we use read-tree to do a simple three-way merge
- if _, _, err := git.NewCommand("read-tree", "-m").AddDynamicArguments(base, ours, theirs).RunStdString(ctx, &git.RunOpts{Dir: gitPath}); err != nil {
+ if _, _, err := gitcmd.NewCommand("read-tree", "-m").AddDynamicArguments(base, ours, theirs).RunStdString(ctx, &gitcmd.RunOpts{Dir: gitPath}); err != nil {
log.Error("Unable to run read-tree -m! Error: %v", err)
return false, nil, fmt.Errorf("unable to run read-tree -m! Error: %w", err)
}
@@ -323,9 +323,9 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
// No conflicts detected so we need to check if the patch is empty...
// a. Write the newly merged tree and check the new tree-hash
var treeHash string
- treeHash, _, err = git.NewCommand("write-tree").RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath})
+ treeHash, _, err = gitcmd.NewCommand("write-tree").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
if err != nil {
- lsfiles, _, _ := git.NewCommand("ls-files", "-u").RunStdString(ctx, &git.RunOpts{Dir: tmpBasePath})
+ lsfiles, _, _ := gitcmd.NewCommand("ls-files", "-u").RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
return false, fmt.Errorf("unable to write unconflicted tree: %w\n`git ls-files -u`:\n%s", err, lsfiles)
}
treeHash = strings.TrimSpace(treeHash)
@@ -382,7 +382,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
log.Trace("PullRequest[%d].testPullRequestTmpRepoBranchMergeable (patchPath): %s", pr.ID, patchPath)
// 4. Read the base branch in to the index of the temporary repository
- _, _, err = git.NewCommand("read-tree", "base").RunStdString(gitRepo.Ctx, &git.RunOpts{Dir: tmpBasePath})
+ _, _, err = gitcmd.NewCommand("read-tree", "base").RunStdString(gitRepo.Ctx, &gitcmd.RunOpts{Dir: tmpBasePath})
if err != nil {
return false, fmt.Errorf("git read-tree %s: %w", pr.BaseBranch, err)
}
@@ -395,7 +395,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
prConfig := prUnit.PullRequestsConfig()
// 6. Prepare the arguments to apply the patch against the index
- cmdApply := git.NewCommand("apply", "--check", "--cached")
+ cmdApply := gitcmd.NewCommand("apply", "--check", "--cached")
if prConfig.IgnoreWhitespaceConflicts {
cmdApply.AddArguments("--ignore-whitespace")
}
@@ -426,7 +426,7 @@ func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *
// 8. Run the check command
conflict = false
- err = cmdApply.Run(gitRepo.Ctx, &git.RunOpts{
+ err = cmdApply.Run(gitRepo.Ctx, &gitcmd.RunOpts{
Dir: tmpBasePath,
Stderr: stderrWriter,
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
diff --git a/services/pull/patch_unmerged.go b/services/pull/patch_unmerged.go
index 200d2233e93..91640354807 100644
--- a/services/pull/patch_unmerged.go
+++ b/services/pull/patch_unmerged.go
@@ -13,7 +13,7 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
)
@@ -72,8 +72,8 @@ func readUnmergedLsFileLines(ctx context.Context, tmpBasePath string, outputChan
}()
stderr := &strings.Builder{}
- err = git.NewCommand("ls-files", "-u", "-z").
- Run(ctx, &git.RunOpts{
+ err = gitcmd.NewCommand("ls-files", "-u", "-z").
+ Run(ctx, &gitcmd.RunOpts{
Dir: tmpBasePath,
Stdout: lsFilesWriter,
Stderr: stderr,
@@ -116,7 +116,7 @@ func readUnmergedLsFileLines(ctx context.Context, tmpBasePath string, outputChan
},
})
if err != nil {
- outputChan <- &lsFileLine{err: fmt.Errorf("git ls-files -u -z: %w", git.ConcatenateError(err, stderr.String()))}
+ outputChan <- &lsFileLine{err: fmt.Errorf("git ls-files -u -z: %w", gitcmd.ConcatenateError(err, stderr.String()))}
}
}
diff --git a/services/pull/pull.go b/services/pull/pull.go
index 8144aee1b0c..51a22171ef4 100644
--- a/services/pull/pull.go
+++ b/services/pull/pull.go
@@ -25,6 +25,7 @@ import (
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/globallock"
"code.gitea.io/gitea/modules/graceful"
@@ -107,13 +108,6 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
assigneeCommentMap := make(map[int64]*issues_model.Comment)
- // add first push codes comment
- baseGitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
- if err != nil {
- return err
- }
- defer baseGitRepo.Close()
-
permDoer, err := access_model.GetUserRepoPermission(ctx, repo, issue.Poster)
if err != nil {
return err
@@ -145,6 +139,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
return err
}
+ // add first push codes comment
if _, err := CreatePushPullComment(ctx, issue.Poster, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName(), false); err != nil {
return err
}
@@ -198,12 +193,11 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
return nil
}); err != nil {
// cleanup: this will only remove the reference, the real commit will be clean up when next GC
- if err1 := baseGitRepo.RemoveReference(pr.GetGitHeadRefName()); err1 != nil {
- log.Error("RemoveReference: %v", err1)
+ if err1 := gitrepo.RemoveRef(ctx, pr.BaseRepo, pr.GetGitHeadRefName()); err1 != nil {
+ log.Error("RemoveRef: %v", err1)
}
return err
}
- baseGitRepo.Close() // close immediately to avoid notifications will open the repository again
reviewRequestNotify(ctx, issue, issue.Poster, reviewNotifiers)
@@ -546,14 +540,14 @@ func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest,
return false, fmt.Errorf("GetMergeBase: %w", err)
}
- cmd := git.NewCommand("diff", "--name-only", "-z").AddDynamicArguments(newCommitID, oldCommitID, base)
+ cmd := gitcmd.NewCommand("diff", "--name-only", "-z").AddDynamicArguments(newCommitID, oldCommitID, base)
stdoutReader, stdoutWriter, err := os.Pipe()
if err != nil {
return false, fmt.Errorf("unable to open pipe for to run diff: %w", err)
}
stderr := new(bytes.Buffer)
- if err := cmd.Run(ctx, &git.RunOpts{
+ if err := cmd.Run(ctx, &gitcmd.RunOpts{
Dir: prCtx.tmpBasePath,
Stdout: stdoutWriter,
Stderr: stderr,
@@ -568,7 +562,7 @@ func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest,
if err == util.ErrNotEmpty {
return true, nil
}
- err = git.ConcatenateError(err, stderr.String())
+ err = gitcmd.ConcatenateError(err, stderr.String())
log.Error("Unable to run diff on %s %s %s in tempRepo for PR[%d]%s/%s...%s/%s: Error: %v",
newCommitID, oldCommitID, base,
@@ -670,8 +664,7 @@ func UpdateRef(ctx context.Context, pr *issues_model.PullRequest) (err error) {
return err
}
- _, _, err = git.NewCommand("update-ref").AddDynamicArguments(pr.GetGitHeadRefName(), pr.HeadCommitID).RunStdString(ctx, &git.RunOpts{Dir: pr.BaseRepo.RepoPath()})
- if err != nil {
+ if err := gitrepo.UpdateRef(ctx, pr.BaseRepo, pr.GetGitHeadRefName(), pr.HeadCommitID); err != nil {
log.Error("Unable to update ref in base repository for PR[%d] Error: %v", pr.ID, err)
}
diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go
index 89f150fd92e..8750b4288a4 100644
--- a/services/pull/temp_repo.go
+++ b/services/pull/temp_repo.go
@@ -15,6 +15,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
@@ -36,10 +37,10 @@ type prTmpRepoContext struct {
errbuf *strings.Builder // any use should be preceded by a Reset and preferably after use
}
-func (ctx *prTmpRepoContext) RunOpts() *git.RunOpts {
+func (ctx *prTmpRepoContext) RunOpts() *gitcmd.RunOpts {
ctx.outbuf.Reset()
ctx.errbuf.Reset()
- return &git.RunOpts{
+ return &gitcmd.RunOpts{
Dir: ctx.tmpBasePath,
Stdout: ctx.outbuf,
Stderr: ctx.errbuf,
@@ -101,7 +102,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
remoteRepoName := "head_repo"
baseBranch := "base"
- fetchArgs := git.TrustedCmdArgs{"--no-tags"}
+ fetchArgs := gitcmd.TrustedCmdArgs{"--no-tags"}
if git.DefaultFeatures().CheckVersionAtLeast("2.25.0") {
// Writing the commit graph can be slow and is not needed here
fetchArgs = append(fetchArgs, "--no-write-commit-graph")
@@ -131,21 +132,21 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
return nil, nil, fmt.Errorf("Unable to add base repository to temporary repo [%s -> tmpBasePath]: %w", pr.BaseRepo.FullName(), err)
}
- if err := git.NewCommand("remote", "add", "-t").AddDynamicArguments(pr.BaseBranch).AddArguments("-m").AddDynamicArguments(pr.BaseBranch).AddDynamicArguments("origin", baseRepoPath).
+ if err := gitcmd.NewCommand("remote", "add", "-t").AddDynamicArguments(pr.BaseBranch).AddArguments("-m").AddDynamicArguments(pr.BaseBranch).AddDynamicArguments("origin", baseRepoPath).
Run(ctx, prCtx.RunOpts()); err != nil {
log.Error("%-v Unable to add base repository as origin [%s -> %s]: %v\n%s\n%s", pr, pr.BaseRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
cancel()
return nil, nil, fmt.Errorf("Unable to add base repository as origin [%s -> tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), err, prCtx.outbuf.String(), prCtx.errbuf.String())
}
- if err := git.NewCommand("fetch", "origin").AddArguments(fetchArgs...).AddDashesAndList(pr.BaseBranch+":"+baseBranch, pr.BaseBranch+":original_"+baseBranch).
+ if err := gitcmd.NewCommand("fetch", "origin").AddArguments(fetchArgs...).AddDashesAndList(pr.BaseBranch+":"+baseBranch, pr.BaseBranch+":original_"+baseBranch).
Run(ctx, prCtx.RunOpts()); err != nil {
log.Error("%-v Unable to fetch origin base branch [%s:%s -> base, original_base in %s]: %v:\n%s\n%s", pr, pr.BaseRepo.FullName(), pr.BaseBranch, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
cancel()
return nil, nil, fmt.Errorf("Unable to fetch origin base branch [%s:%s -> base, original_base in tmpBasePath]: %w\n%s\n%s", pr.BaseRepo.FullName(), pr.BaseBranch, err, prCtx.outbuf.String(), prCtx.errbuf.String())
}
- if err := git.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseBranch).
+ if err := gitcmd.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseBranch).
Run(ctx, prCtx.RunOpts()); err != nil {
log.Error("%-v Unable to set HEAD as base branch in [%s]: %v\n%s\n%s", pr, tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
cancel()
@@ -158,7 +159,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
return nil, nil, fmt.Errorf("Unable to add head base repository to temporary repo [%s -> tmpBasePath]: %w", pr.HeadRepo.FullName(), err)
}
- if err := git.NewCommand("remote", "add").AddDynamicArguments(remoteRepoName, headRepoPath).
+ if err := gitcmd.NewCommand("remote", "add").AddDynamicArguments(remoteRepoName, headRepoPath).
Run(ctx, prCtx.RunOpts()); err != nil {
log.Error("%-v Unable to add head repository as head_repo [%s -> %s]: %v\n%s\n%s", pr, pr.HeadRepo.FullName(), tmpBasePath, err, prCtx.outbuf.String(), prCtx.errbuf.String())
cancel()
@@ -176,7 +177,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
} else {
headBranch = pr.GetGitHeadRefName()
}
- if err := git.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch).
+ if err := gitcmd.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch).
Run(ctx, prCtx.RunOpts()); err != nil {
cancel()
if !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) {
diff --git a/services/pull/update_rebase.go b/services/pull/update_rebase.go
index 9ff062f99c6..3b5d3afba5b 100644
--- a/services/pull/update_rebase.go
+++ b/services/pull/update_rebase.go
@@ -12,6 +12,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
@@ -27,7 +28,7 @@ func updateHeadByRebaseOnToBase(ctx context.Context, pr *issues_model.PullReques
defer cancel()
// Determine the old merge-base before the rebase - we use this for LFS push later on
- oldMergeBase, _, _ := git.NewCommand("merge-base").AddDashesAndList(baseBranch, trackingBranch).RunStdString(ctx, &git.RunOpts{Dir: mergeCtx.tmpBasePath})
+ oldMergeBase, _, _ := gitcmd.NewCommand("merge-base").AddDashesAndList(baseBranch, trackingBranch).RunStdString(ctx, &gitcmd.RunOpts{Dir: mergeCtx.tmpBasePath})
oldMergeBase = strings.TrimSpace(oldMergeBase)
// Rebase the tracking branch on to the base as the staging branch
@@ -62,7 +63,7 @@ func updateHeadByRebaseOnToBase(ctx context.Context, pr *issues_model.PullReques
headUser = pr.HeadRepo.Owner
}
- pushCmd := git.NewCommand("push", "-f", "head_repo").
+ pushCmd := gitcmd.NewCommand("push", "-f", "head_repo").
AddDynamicArguments(stagingBranch + ":" + git.BranchPrefix + pr.HeadBranch)
// Push back to the head repository.
@@ -71,7 +72,7 @@ func updateHeadByRebaseOnToBase(ctx context.Context, pr *issues_model.PullReques
mergeCtx.outbuf.Reset()
mergeCtx.errbuf.Reset()
- if err := pushCmd.Run(ctx, &git.RunOpts{
+ if err := pushCmd.Run(ctx, &gitcmd.RunOpts{
Env: repo_module.FullPushingEnvironment(
headUser,
doer,
diff --git a/services/release/release.go b/services/release/release.go
index 0b8a74252a0..3c5392c9938 100644
--- a/services/release/release.go
+++ b/services/release/release.go
@@ -15,6 +15,7 @@ import (
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/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
@@ -267,74 +268,69 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo
}
rel.LowerTagName = strings.ToLower(rel.TagName)
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
oldRelease, err := repo_model.GetReleaseByID(ctx, rel.ID)
if err != nil {
return err
}
isConvertedFromTag := oldRelease.IsTag && !rel.IsTag
- if err = repo_model.UpdateRelease(ctx, rel); err != nil {
- return err
- }
-
- if err = repo_model.AddReleaseAttachments(ctx, rel.ID, addAttachmentUUIDs); err != nil {
- return fmt.Errorf("AddReleaseAttachments: %w", err)
- }
-
- deletedUUIDs := make(container.Set[string])
- if len(delAttachmentUUIDs) > 0 {
- // Check attachments
- attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs)
- if err != nil {
- return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %w", delAttachmentUUIDs, err)
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ if err = repo_model.UpdateRelease(ctx, rel); err != nil {
+ return err
}
- for _, attach := range attachments {
- if attach.ReleaseID != rel.ID {
- return util.NewPermissionDeniedErrorf("delete attachment of release permission denied")
+
+ if err = repo_model.AddReleaseAttachments(ctx, rel.ID, addAttachmentUUIDs); err != nil {
+ return fmt.Errorf("AddReleaseAttachments: %w", err)
+ }
+
+ deletedUUIDs := make(container.Set[string])
+ if len(delAttachmentUUIDs) > 0 {
+ // Check attachments
+ attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, delAttachmentUUIDs)
+ if err != nil {
+ return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %w", delAttachmentUUIDs, err)
+ }
+ for _, attach := range attachments {
+ if attach.ReleaseID != rel.ID {
+ return util.NewPermissionDeniedErrorf("delete attachment of release permission denied")
+ }
+ deletedUUIDs.Add(attach.UUID)
}
- deletedUUIDs.Add(attach.UUID)
- }
- if _, err := repo_model.DeleteAttachments(ctx, attachments, true); err != nil {
- return fmt.Errorf("DeleteAttachments [uuids: %v]: %w", delAttachmentUUIDs, err)
- }
- }
-
- if len(editAttachments) > 0 {
- updateAttachmentsList := make([]string, 0, len(editAttachments))
- for k := range editAttachments {
- updateAttachmentsList = append(updateAttachmentsList, k)
- }
- // Check attachments
- attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, updateAttachmentsList)
- if err != nil {
- return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %w", updateAttachmentsList, err)
- }
- for _, attach := range attachments {
- if attach.ReleaseID != rel.ID {
- return util.NewPermissionDeniedErrorf("update attachment of release permission denied")
+ if _, err := repo_model.DeleteAttachments(ctx, attachments, true); err != nil {
+ return fmt.Errorf("DeleteAttachments [uuids: %v]: %w", delAttachmentUUIDs, err)
}
}
- for uuid, newName := range editAttachments {
- if !deletedUUIDs.Contains(uuid) {
- if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{
- UUID: uuid,
- Name: newName,
- }, "name"); err != nil {
- return err
+ if len(editAttachments) > 0 {
+ updateAttachmentsList := make([]string, 0, len(editAttachments))
+ for k := range editAttachments {
+ updateAttachmentsList = append(updateAttachmentsList, k)
+ }
+ // Check attachments
+ attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, updateAttachmentsList)
+ if err != nil {
+ return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %w", updateAttachmentsList, err)
+ }
+ for _, attach := range attachments {
+ if attach.ReleaseID != rel.ID {
+ return util.NewPermissionDeniedErrorf("update attachment of release permission denied")
+ }
+ }
+
+ for uuid, newName := range editAttachments {
+ if !deletedUUIDs.Contains(uuid) {
+ if err = repo_model.UpdateAttachmentByUUID(ctx, &repo_model.Attachment{
+ UUID: uuid,
+ Name: newName,
+ }, "name"); err != nil {
+ return err
+ }
}
}
}
- }
-
- if err := committer.Commit(); err != nil {
+ return nil
+ }); err != nil {
return err
}
@@ -375,8 +371,8 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re
}
}
- if stdout, _, err := git.NewCommand("tag", "-d").AddDashesAndList(rel.TagName).
- RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil && !strings.Contains(err.Error(), "not found") {
+ if stdout, _, err := gitcmd.NewCommand("tag", "-d").AddDashesAndList(rel.TagName).
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()}); err != nil && !strings.Contains(err.Error(), "not found") {
log.Error("DeleteReleaseByID (git tag -d): %d in %v Failed:\nStdout: %s\nError: %v", rel.ID, repo, stdout, err)
return fmt.Errorf("git tag -d: %w", err)
}
diff --git a/services/repository/adopt.go b/services/repository/adopt.go
index a17111dfafb..8d8e59b0531 100644
--- a/services/repository/adopt.go
+++ b/services/repository/adopt.go
@@ -17,6 +17,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
@@ -24,8 +25,6 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
notify_service "code.gitea.io/gitea/services/notify"
-
- "github.com/gobwas/glob"
)
func deleteFailedAdoptRepository(repoID int64) error {
diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go
index a657e3884c4..0aa8fd596ba 100644
--- a/services/repository/archiver/archiver.go
+++ b/services/repository/archiver/archiver.go
@@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"io"
+ "net/http"
"os"
"strings"
"time"
@@ -17,11 +18,13 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/queue"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
+ gitea_context "code.gitea.io/gitea/services/context"
)
// ArchiveRequest defines the parameters of an archive request, which notably
@@ -138,6 +141,25 @@ func (aReq *ArchiveRequest) Await(ctx context.Context) (*repo_model.RepoArchiver
}
}
+// Stream satisfies the ArchiveRequest being passed in. Processing
+// will occur directly in this routine.
+func (aReq *ArchiveRequest) Stream(ctx context.Context, gitRepo *git.Repository, w io.Writer) error {
+ if aReq.Type == git.ArchiveBundle {
+ return gitRepo.CreateBundle(
+ ctx,
+ aReq.CommitID,
+ w,
+ )
+ }
+ return gitRepo.CreateArchive(
+ ctx,
+ aReq.Type,
+ w,
+ setting.Repository.PrefixArchiveFiles,
+ aReq.CommitID,
+ )
+}
+
// doArchive satisfies the ArchiveRequest being passed in. Processing
// will occur in a separate goroutine, as this phase may take a while to
// complete. If the archive already exists, doArchive will not do
@@ -204,31 +226,17 @@ func doArchive(ctx context.Context, r *ArchiveRequest) (*repo_model.RepoArchiver
}
defer gitRepo.Close()
- go func(done chan error, w *io.PipeWriter, archiver *repo_model.RepoArchiver, gitRepo *git.Repository) {
+ go func(done chan error, w *io.PipeWriter, archiveReq *ArchiveRequest, gitRepo *git.Repository) {
defer func() {
if r := recover(); r != nil {
done <- fmt.Errorf("%v", r)
}
}()
- if archiver.Type == git.ArchiveBundle {
- err = gitRepo.CreateBundle(
- ctx,
- archiver.CommitID,
- w,
- )
- } else {
- err = gitRepo.CreateArchive(
- ctx,
- archiver.Type,
- w,
- setting.Repository.PrefixArchiveFiles,
- archiver.CommitID,
- )
- }
+ err := archiveReq.Stream(ctx, gitRepo, w)
_ = w.CloseWithError(err)
done <- err
- }(done, w, archiver, gitRepo)
+ }(done, w, r, gitRepo)
// TODO: add lfs data to zip
// TODO: add submodule data to zip
@@ -338,3 +346,54 @@ func DeleteRepositoryArchives(ctx context.Context) error {
}
return storage.Clean(storage.RepoArchives)
}
+
+func ServeRepoArchive(ctx *gitea_context.Base, repo *repo_model.Repository, gitRepo *git.Repository, archiveReq *ArchiveRequest) {
+ // Add nix format link header so tarballs lock correctly:
+ // https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md
+ ctx.Resp.Header().Add("Link", fmt.Sprintf(`<%s/archive/%s.%s?rev=%s>; rel="immutable"`,
+ repo.APIURL(),
+ archiveReq.CommitID,
+ archiveReq.Type.String(),
+ archiveReq.CommitID,
+ ))
+ downloadName := repo.Name + "-" + archiveReq.GetArchiveName()
+
+ if setting.Repository.StreamArchives {
+ httplib.ServeSetHeaders(ctx.Resp, &httplib.ServeHeaderOptions{Filename: downloadName})
+ if err := archiveReq.Stream(ctx, gitRepo, ctx.Resp); err != nil && !ctx.Written() {
+ log.Error("Archive %v streaming failed: %v", archiveReq, err)
+ ctx.HTTPError(http.StatusInternalServerError)
+ }
+ return
+ }
+
+ archiver, err := archiveReq.Await(ctx)
+ if err != nil {
+ log.Error("Archive %v await failed: %v", archiveReq, err)
+ ctx.HTTPError(http.StatusInternalServerError)
+ return
+ }
+
+ rPath := archiver.RelativePath()
+ if setting.RepoArchive.Storage.ServeDirect() {
+ // If we have a signed url (S3, object storage), redirect to this directly.
+ u, err := storage.RepoArchives.URL(rPath, downloadName, ctx.Req.Method, nil)
+ if u != nil && err == nil {
+ ctx.Redirect(u.String())
+ return
+ }
+ }
+
+ fr, err := storage.RepoArchives.Open(rPath)
+ if err != nil {
+ log.Error("Archive %v open file failed: %v", archiveReq, err)
+ ctx.HTTPError(http.StatusInternalServerError)
+ return
+ }
+ defer fr.Close()
+
+ ctx.ServeContent(fr, &gitea_context.ServeHeaderOptions{
+ Filename: downloadName,
+ LastModified: archiver.CreatedUnix.AsLocalTime(),
+ })
+}
diff --git a/services/repository/check.go b/services/repository/check.go
index 46eb4d7e7c1..46394ba48e4 100644
--- a/services/repository/check.go
+++ b/services/repository/check.go
@@ -13,7 +13,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
system_model "code.gitea.io/gitea/models/system"
user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
@@ -23,7 +23,7 @@ import (
)
// GitFsckRepos calls 'git fsck' to check repository health.
-func GitFsckRepos(ctx context.Context, timeout time.Duration, args git.TrustedCmdArgs) error {
+func GitFsckRepos(ctx context.Context, timeout time.Duration, args gitcmd.TrustedCmdArgs) error {
log.Trace("Doing: GitFsck")
if err := db.Iterate(
@@ -47,7 +47,7 @@ func GitFsckRepos(ctx context.Context, timeout time.Duration, args git.TrustedCm
}
// GitFsckRepo calls 'git fsck' to check an individual repository's health.
-func GitFsckRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Duration, args git.TrustedCmdArgs) error {
+func GitFsckRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Duration, args gitcmd.TrustedCmdArgs) error {
log.Trace("Running health check on repository %-v", repo.FullName())
if err := gitrepo.Fsck(ctx, repo, timeout, args); err != nil {
log.Warn("Failed to health check repository (%-v): %v", repo.FullName(), err)
@@ -59,7 +59,7 @@ func GitFsckRepo(ctx context.Context, repo *repo_model.Repository, timeout time.
}
// GitGcRepos calls 'git gc' to remove unnecessary files and optimize the local repository
-func GitGcRepos(ctx context.Context, timeout time.Duration, args git.TrustedCmdArgs) error {
+func GitGcRepos(ctx context.Context, timeout time.Duration, args gitcmd.TrustedCmdArgs) error {
log.Trace("Doing: GitGcRepos")
if err := db.Iterate(
@@ -84,12 +84,12 @@ func GitGcRepos(ctx context.Context, timeout time.Duration, args git.TrustedCmdA
}
// GitGcRepo calls 'git gc' to remove unnecessary files and optimize the local repository
-func GitGcRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Duration, args git.TrustedCmdArgs) error {
+func GitGcRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Duration, args gitcmd.TrustedCmdArgs) error {
log.Trace("Running git gc on %-v", repo)
- command := git.NewCommand("gc").AddArguments(args...)
+ command := gitcmd.NewCommand("gc").AddArguments(args...)
var stdout string
var err error
- stdout, _, err = command.RunStdString(ctx, &git.RunOpts{Timeout: timeout, Dir: repo.RepoPath()})
+ stdout, _, err = command.RunStdString(ctx, &gitcmd.RunOpts{Timeout: timeout, Dir: repo.RepoPath()})
if err != nil {
log.Error("Repository garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err)
desc := fmt.Sprintf("Repository garbage collection failed for %s. Stdout: %s\nError: %v", repo.RepoPath(), stdout, err)
diff --git a/services/repository/commitstatus/commitstatus.go b/services/repository/commitstatus/commitstatus.go
index fa7a89882a1..c0a8b8e8243 100644
--- a/services/repository/commitstatus/commitstatus.go
+++ b/services/repository/commitstatus/commitstatus.go
@@ -120,7 +120,7 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato
return nil
}
-// FindReposLastestCommitStatuses loading repository default branch latest combinded commit status with cache
+// FindReposLastestCommitStatuses loading repository default branch latest combined commit status with cache
func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Repository) ([]*git_model.CommitStatus, error) {
results := make([]*git_model.CommitStatus, len(repos))
allCached := true
diff --git a/services/repository/contributors_graph.go b/services/repository/contributors_graph.go
index a4ae5053139..a7fb130cb57 100644
--- a/services/repository/contributors_graph.go
+++ b/services/repository/contributors_graph.go
@@ -19,6 +19,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
@@ -125,13 +126,13 @@ func getExtendedCommitStats(repo *git.Repository, revision string /*, limit int
_ = stdoutWriter.Close()
}()
- gitCmd := git.NewCommand("log", "--shortstat", "--no-merges", "--pretty=format:---%n%aN%n%aE%n%as", "--reverse")
+ gitCmd := gitcmd.NewCommand("log", "--shortstat", "--no-merges", "--pretty=format:---%n%aN%n%aE%n%as", "--reverse")
// AddOptionFormat("--max-count=%d", limit)
gitCmd.AddDynamicArguments(baseCommit.ID.String())
var extendedCommitStats []*ExtendedCommitStats
stderr := new(strings.Builder)
- err = gitCmd.Run(repo.Ctx, &git.RunOpts{
+ err = gitCmd.Run(repo.Ctx, &gitcmd.RunOpts{
Dir: repo.Path,
Stdout: stdoutWriter,
Stderr: stderr,
diff --git a/services/repository/create.go b/services/repository/create.go
index 9f0716c191f..3006bfaeaf0 100644
--- a/services/repository/create.go
+++ b/services/repository/create.go
@@ -22,6 +22,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
@@ -68,8 +69,8 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir
)
// Clone to temporary path and do the init commit.
- if stdout, _, err := git.NewCommand("clone").AddDynamicArguments(repo.RepoPath(), tmpDir).
- RunStdString(ctx, &git.RunOpts{Dir: "", Env: env}); err != nil {
+ if stdout, _, err := gitcmd.NewCommand("clone").AddDynamicArguments(repo.RepoPath(), tmpDir).
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: "", Env: env}); err != nil {
log.Error("Failed to clone from %v into %s: stdout: %s\nError: %v", repo, tmpDir, stdout, err)
return fmt.Errorf("git clone: %w", err)
}
@@ -313,7 +314,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, owner *user_model.User,
licenses = append(licenses, opts.License)
var stdout string
- stdout, _, err = git.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()})
+ stdout, _, err = gitcmd.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()})
if err != nil {
log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err)
return nil, fmt.Errorf("CreateRepository(git rev-parse HEAD): %w", err)
@@ -474,8 +475,8 @@ func updateGitRepoAfterCreate(ctx context.Context, repo *repo_model.Repository)
return fmt.Errorf("checkDaemonExportOK: %w", err)
}
- if stdout, _, err := git.NewCommand("update-server-info").
- RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil {
+ if stdout, _, err := gitcmd.NewCommand("update-server-info").
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: repo.RepoPath()}); err != nil {
log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err)
return fmt.Errorf("CreateRepository(git update-server-info): %w", err)
}
diff --git a/services/repository/files/patch.go b/services/repository/files/patch.go
index 11a8744b7f4..093072dff20 100644
--- a/services/repository/files/patch.go
+++ b/services/repository/files/patch.go
@@ -12,6 +12,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
@@ -159,12 +160,12 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user
stdout := &strings.Builder{}
stderr := &strings.Builder{}
- cmdApply := git.NewCommand("apply", "--index", "--recount", "--cached", "--ignore-whitespace", "--whitespace=fix", "--binary")
+ cmdApply := gitcmd.NewCommand("apply", "--index", "--recount", "--cached", "--ignore-whitespace", "--whitespace=fix", "--binary")
if git.DefaultFeatures().CheckVersionAtLeast("2.32") {
cmdApply.AddArguments("-3")
}
- if err := cmdApply.Run(ctx, &git.RunOpts{
+ if err := cmdApply.Run(ctx, &gitcmd.RunOpts{
Dir: t.basePath,
Stdout: stdout,
Stderr: stderr,
diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go
index c2f61c82234..dcbe368357b 100644
--- a/services/repository/files/temp_repo.go
+++ b/services/repository/files/temp_repo.go
@@ -17,6 +17,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
@@ -53,7 +54,7 @@ func (t *TemporaryUploadRepository) Close() {
// Clone the base repository to our path and set branch as the HEAD
func (t *TemporaryUploadRepository) Clone(ctx context.Context, branch string, bare bool) error {
- cmd := git.NewCommand("clone", "-s", "-b").AddDynamicArguments(branch, t.repo.RepoPath(), t.basePath)
+ cmd := gitcmd.NewCommand("clone", "-s", "-b").AddDynamicArguments(branch, t.repo.RepoPath(), t.basePath)
if bare {
cmd.AddArguments("--bare")
}
@@ -97,7 +98,7 @@ func (t *TemporaryUploadRepository) Init(ctx context.Context, objectFormatName s
// SetDefaultIndex sets the git index to our HEAD
func (t *TemporaryUploadRepository) SetDefaultIndex(ctx context.Context) error {
- if _, _, err := git.NewCommand("read-tree", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: t.basePath}); err != nil {
+ if _, _, err := gitcmd.NewCommand("read-tree", "HEAD").RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath}); err != nil {
return fmt.Errorf("SetDefaultIndex: %w", err)
}
return nil
@@ -105,7 +106,7 @@ func (t *TemporaryUploadRepository) SetDefaultIndex(ctx context.Context) error {
// RefreshIndex looks at the current index and checks to see if merges or updates are needed by checking stat() information.
func (t *TemporaryUploadRepository) RefreshIndex(ctx context.Context) error {
- if _, _, err := git.NewCommand("update-index", "--refresh").RunStdString(ctx, &git.RunOpts{Dir: t.basePath}); err != nil {
+ if _, _, err := gitcmd.NewCommand("update-index", "--refresh").RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath}); err != nil {
return fmt.Errorf("RefreshIndex: %w", err)
}
return nil
@@ -116,8 +117,8 @@ func (t *TemporaryUploadRepository) LsFiles(ctx context.Context, filenames ...st
stdOut := new(bytes.Buffer)
stdErr := new(bytes.Buffer)
- if err := git.NewCommand("ls-files", "-z").AddDashesAndList(filenames...).
- Run(ctx, &git.RunOpts{
+ if err := gitcmd.NewCommand("ls-files", "-z").AddDashesAndList(filenames...).
+ Run(ctx, &gitcmd.RunOpts{
Dir: t.basePath,
Stdout: stdOut,
Stderr: stdErr,
@@ -152,8 +153,8 @@ func (t *TemporaryUploadRepository) RemoveFilesFromIndex(ctx context.Context, fi
}
}
- if err := git.NewCommand("update-index", "--remove", "-z", "--index-info").
- Run(ctx, &git.RunOpts{
+ if err := gitcmd.NewCommand("update-index", "--remove", "-z", "--index-info").
+ Run(ctx, &gitcmd.RunOpts{
Dir: t.basePath,
Stdin: stdIn,
Stdout: stdOut,
@@ -169,8 +170,8 @@ func (t *TemporaryUploadRepository) HashObjectAndWrite(ctx context.Context, cont
stdOut := new(bytes.Buffer)
stdErr := new(bytes.Buffer)
- if err := git.NewCommand("hash-object", "-w", "--stdin").
- Run(ctx, &git.RunOpts{
+ if err := gitcmd.NewCommand("hash-object", "-w", "--stdin").
+ Run(ctx, &gitcmd.RunOpts{
Dir: t.basePath,
Stdin: content,
Stdout: stdOut,
@@ -185,7 +186,7 @@ func (t *TemporaryUploadRepository) HashObjectAndWrite(ctx context.Context, cont
// AddObjectToIndex adds the provided object hash to the index with the provided mode and path
func (t *TemporaryUploadRepository) AddObjectToIndex(ctx context.Context, mode, objectHash, objectPath string) error {
- if _, _, err := git.NewCommand("update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, objectHash, objectPath).RunStdString(ctx, &git.RunOpts{Dir: t.basePath}); err != nil {
+ if _, _, err := gitcmd.NewCommand("update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, objectHash, objectPath).RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath}); err != nil {
stderr := err.Error()
if matched, _ := regexp.MatchString(".*Invalid path '.*", stderr); matched {
return ErrFilePathInvalid{
@@ -201,7 +202,7 @@ func (t *TemporaryUploadRepository) AddObjectToIndex(ctx context.Context, mode,
// WriteTree writes the current index as a tree to the object db and returns its hash
func (t *TemporaryUploadRepository) WriteTree(ctx context.Context) (string, error) {
- stdout, _, err := git.NewCommand("write-tree").RunStdString(ctx, &git.RunOpts{Dir: t.basePath})
+ stdout, _, err := gitcmd.NewCommand("write-tree").RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath})
if err != nil {
log.Error("Unable to write tree in temporary repo: %s(%s): Error: %v", t.repo.FullName(), t.basePath, err)
return "", fmt.Errorf("Unable to write-tree in temporary repo for: %s Error: %w", t.repo.FullName(), err)
@@ -219,7 +220,7 @@ func (t *TemporaryUploadRepository) GetLastCommitByRef(ctx context.Context, ref
if ref == "" {
ref = "HEAD"
}
- stdout, _, err := git.NewCommand("rev-parse").AddDynamicArguments(ref).RunStdString(ctx, &git.RunOpts{Dir: t.basePath})
+ stdout, _, err := gitcmd.NewCommand("rev-parse").AddDynamicArguments(ref).RunStdString(ctx, &gitcmd.RunOpts{Dir: t.basePath})
if err != nil {
log.Error("Unable to get last ref for %s in temporary repo: %s(%s): Error: %v", ref, t.repo.FullName(), t.basePath, err)
return "", fmt.Errorf("Unable to rev-parse %s in temporary repo for: %s Error: %w", ref, t.repo.FullName(), err)
@@ -287,7 +288,7 @@ func (t *TemporaryUploadRepository) CommitTree(ctx context.Context, opts *Commit
_, _ = messageBytes.WriteString(opts.CommitMessage)
_, _ = messageBytes.WriteString("\n")
- cmdCommitTree := git.NewCommand("commit-tree").AddDynamicArguments(opts.TreeHash)
+ cmdCommitTree := gitcmd.NewCommand("commit-tree").AddDynamicArguments(opts.TreeHash)
if opts.ParentCommitID != "" {
cmdCommitTree.AddOptionValues("-p", opts.ParentCommitID)
}
@@ -337,7 +338,7 @@ func (t *TemporaryUploadRepository) CommitTree(ctx context.Context, opts *Commit
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
if err := cmdCommitTree.
- Run(ctx, &git.RunOpts{
+ Run(ctx, &gitcmd.RunOpts{
Env: env,
Dir: t.basePath,
Stdin: messageBytes,
@@ -389,8 +390,8 @@ func (t *TemporaryUploadRepository) DiffIndex(ctx context.Context) (*gitdiff.Dif
}()
stderr := new(bytes.Buffer)
var diff *gitdiff.Diff
- err = git.NewCommand("diff-index", "--src-prefix=\\a/", "--dst-prefix=\\b/", "--cached", "-p", "HEAD").
- Run(ctx, &git.RunOpts{
+ err = gitcmd.NewCommand("diff-index", "--src-prefix=\\a/", "--dst-prefix=\\b/", "--cached", "-p", "HEAD").
+ Run(ctx, &gitcmd.RunOpts{
Timeout: 30 * time.Second,
Dir: t.basePath,
Stdout: stdoutWriter,
diff --git a/services/repository/fork.go b/services/repository/fork.go
index 8bd3498b171..05909f0e0d5 100644
--- a/services/repository/fork.go
+++ b/services/repository/fork.go
@@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
@@ -146,13 +147,13 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
}
// 3 - Clone the repository
- cloneCmd := git.NewCommand("clone", "--bare")
+ cloneCmd := gitcmd.NewCommand("clone", "--bare")
if opts.SingleBranch != "" {
cloneCmd.AddArguments("--single-branch", "--branch").AddDynamicArguments(opts.SingleBranch)
}
var stdout []byte
if stdout, _, err = cloneCmd.AddDynamicArguments(opts.BaseRepo.RepoPath(), repo.RepoPath()).
- RunStdBytes(ctx, &git.RunOpts{Timeout: 10 * time.Minute}); err != nil {
+ RunStdBytes(ctx, &gitcmd.RunOpts{Timeout: 10 * time.Minute}); err != nil {
log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err)
return nil, fmt.Errorf("git clone: %w", err)
}
diff --git a/services/repository/generate.go b/services/repository/generate.go
index 867b5d78554..c03d9b51a79 100644
--- a/services/repository/generate.go
+++ b/services/repository/generate.go
@@ -18,13 +18,14 @@ import (
git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
- "github.com/gobwas/glob"
"github.com/huandu/xstrings"
)
@@ -234,8 +235,8 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r
return err
}
- if stdout, _, err := git.NewCommand("remote", "add", "origin").AddDynamicArguments(repo.RepoPath()).
- RunStdString(ctx, &git.RunOpts{Dir: tmpDir, Env: env}); err != nil {
+ if stdout, _, err := gitcmd.NewCommand("remote", "add", "origin").AddDynamicArguments(repo.RepoPath()).
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpDir, Env: env}); err != nil {
log.Error("Unable to add %v as remote origin to temporary repo to %s: stdout %s\nError: %v", repo, tmpDir, stdout, err)
return fmt.Errorf("git remote add: %w", err)
}
diff --git a/services/repository/gitgraph/graph.go b/services/repository/gitgraph/graph.go
index d06d18c1b4d..3bc97b7bbc7 100644
--- a/services/repository/gitgraph/graph.go
+++ b/services/repository/gitgraph/graph.go
@@ -11,6 +11,7 @@ import (
"strings"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/setting"
)
@@ -22,7 +23,7 @@ func GetCommitGraph(r *git.Repository, page, maxAllowedColors int, hidePRRefs bo
page = 1
}
- graphCmd := git.NewCommand("log", "--graph", "--date-order", "--decorate=full")
+ graphCmd := gitcmd.NewCommand("log", "--graph", "--date-order", "--decorate=full")
if hidePRRefs {
graphCmd.AddArguments("--exclude=" + git.PullPrefix + "*")
@@ -53,7 +54,7 @@ func GetCommitGraph(r *git.Repository, page, maxAllowedColors int, hidePRRefs bo
scanner := bufio.NewScanner(stdoutReader)
- if err := graphCmd.Run(r.Ctx, &git.RunOpts{
+ if err := graphCmd.Run(r.Ctx, &gitcmd.RunOpts{
Dir: r.Path,
Stdout: stdoutWriter,
Stderr: stderr,
diff --git a/services/repository/gitgraph/graph_models.go b/services/repository/gitgraph/graph_models.go
index 02b0268cd9a..fc2eb85b87f 100644
--- a/services/repository/gitgraph/graph_models.go
+++ b/services/repository/gitgraph/graph_models.go
@@ -182,7 +182,7 @@ func (flow *Flow) AddGlyph(row, column int, glyph byte) {
})
}
-// Glyph represents a co-ordinate and glyph
+// Glyph represents a coordinate and glyph
type Glyph struct {
Row int
Column int
@@ -244,7 +244,7 @@ func newRefsFromRefNames(refNames []byte) []git.Reference {
return refs
}
-// Commit represents a commit at co-ordinate X, Y with the data
+// Commit represents a commit at coordinate X, Y with the data
type Commit struct {
Commit *git.Commit
User *user_model.User
diff --git a/services/repository/init.go b/services/repository/init.go
index 1eeeb4aa4fa..c905d1f6a30 100644
--- a/services/repository/init.go
+++ b/services/repository/init.go
@@ -11,7 +11,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
@@ -33,13 +33,13 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi
committerName := sig.Name
committerEmail := sig.Email
- if stdout, _, err := git.NewCommand("add", "--all").
- RunStdString(ctx, &git.RunOpts{Dir: tmpPath}); err != nil {
+ if stdout, _, err := gitcmd.NewCommand("add", "--all").
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpPath}); err != nil {
log.Error("git add --all failed: Stdout: %s\nError: %v", stdout, err)
return fmt.Errorf("git add --all: %w", err)
}
- cmd := git.NewCommand("commit", "--message=Initial commit").
+ cmd := gitcmd.NewCommand("commit", "--message=Initial commit").
AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email)
sign, key, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u)
@@ -64,7 +64,7 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi
)
if stdout, _, err := cmd.
- RunStdString(ctx, &git.RunOpts{Dir: tmpPath, Env: env}); err != nil {
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpPath, Env: env}); err != nil {
log.Error("Failed to commit: %v: Stdout: %s\nError: %v", cmd.LogString(), stdout, err)
return fmt.Errorf("git commit: %w", err)
}
@@ -73,8 +73,8 @@ func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi
defaultBranch = setting.Repository.DefaultBranch
}
- if stdout, _, err := git.NewCommand("push", "origin").AddDynamicArguments("HEAD:"+defaultBranch).
- RunStdString(ctx, &git.RunOpts{Dir: tmpPath, Env: repo_module.InternalPushingEnvironment(u, repo)}); err != nil {
+ if stdout, _, err := gitcmd.NewCommand("push", "origin").AddDynamicArguments("HEAD:"+defaultBranch).
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: tmpPath, Env: repo_module.InternalPushingEnvironment(u, repo)}); err != nil {
log.Error("Failed to push back to HEAD: Stdout: %s\nError: %v", stdout, err)
return fmt.Errorf("git push: %w", err)
}
diff --git a/services/repository/migrate.go b/services/repository/migrate.go
index 664f0cf0974..db1f020b9f8 100644
--- a/services/repository/migrate.go
+++ b/services/repository/migrate.go
@@ -16,6 +16,7 @@ import (
unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
@@ -173,92 +174,88 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
}
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return nil, err
- }
- defer committer.Close()
-
- if opts.Mirror {
- remoteAddress, err := util.SanitizeURL(opts.CloneAddr)
- if err != nil {
- return repo, err
- }
- mirrorModel := repo_model.Mirror{
- RepoID: repo.ID,
- Interval: setting.Mirror.DefaultInterval,
- EnablePrune: true,
- NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval),
- LFS: opts.LFS,
- RemoteAddress: remoteAddress,
- }
- if opts.LFS {
- mirrorModel.LFSEndpoint = opts.LFSEndpoint
- }
-
- if opts.MirrorInterval != "" {
- parsedInterval, err := time.ParseDuration(opts.MirrorInterval)
+ return db.WithTx2(ctx, func(ctx context.Context) (*repo_model.Repository, error) {
+ if opts.Mirror {
+ remoteAddress, err := util.SanitizeURL(opts.CloneAddr)
if err != nil {
- log.Error("Failed to set Interval: %v", err)
return repo, err
}
- if parsedInterval == 0 {
- mirrorModel.Interval = 0
- mirrorModel.NextUpdateUnix = 0
- } else if parsedInterval < setting.Mirror.MinInterval {
- err := fmt.Errorf("interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval)
- log.Error("Interval: %s is too frequent", opts.MirrorInterval)
- return repo, err
- } else {
- mirrorModel.Interval = parsedInterval
- mirrorModel.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(parsedInterval)
+ mirrorModel := repo_model.Mirror{
+ RepoID: repo.ID,
+ Interval: setting.Mirror.DefaultInterval,
+ EnablePrune: true,
+ NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval),
+ LFS: opts.LFS,
+ RemoteAddress: remoteAddress,
+ }
+ if opts.LFS {
+ mirrorModel.LFSEndpoint = opts.LFSEndpoint
+ }
+
+ if opts.MirrorInterval != "" {
+ parsedInterval, err := time.ParseDuration(opts.MirrorInterval)
+ if err != nil {
+ log.Error("Failed to set Interval: %v", err)
+ return repo, err
+ }
+ if parsedInterval == 0 {
+ mirrorModel.Interval = 0
+ mirrorModel.NextUpdateUnix = 0
+ } else if parsedInterval < setting.Mirror.MinInterval {
+ err := fmt.Errorf("interval %s is set below Minimum Interval of %s", parsedInterval, setting.Mirror.MinInterval)
+ log.Error("Interval: %s is too frequent", opts.MirrorInterval)
+ return repo, err
+ } else {
+ mirrorModel.Interval = parsedInterval
+ mirrorModel.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(parsedInterval)
+ }
+ }
+
+ if err = repo_model.InsertMirror(ctx, &mirrorModel); err != nil {
+ return repo, fmt.Errorf("InsertOne: %w", err)
+ }
+
+ repo.IsMirror = true
+ if err = repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "num_watches", "is_empty", "default_branch", "default_wiki_branch", "is_mirror"); err != nil {
+ return nil, err
+ }
+
+ if err = repo_module.UpdateRepoSize(ctx, repo); err != nil {
+ log.Error("Failed to update size for repository: %v", err)
+ }
+
+ // this is necessary for sync local tags from remote
+ configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName())
+ if stdout, _, err := gitcmd.NewCommand("config").
+ AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`).
+ RunStdString(ctx, &gitcmd.RunOpts{Dir: repoPath}); err != nil {
+ log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err)
+ return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err)
+ }
+ } else {
+ if err = repo_module.UpdateRepoSize(ctx, repo); err != nil {
+ log.Error("Failed to update size for repository: %v", err)
+ }
+ if repo, err = CleanUpMigrateInfo(ctx, repo); err != nil {
+ return nil, err
}
}
- if err = repo_model.InsertMirror(ctx, &mirrorModel); err != nil {
- return repo, fmt.Errorf("InsertOne: %w", err)
+ var enableRepoUnits []repo_model.RepoUnit
+ if opts.Releases && !unit_model.TypeReleases.UnitGlobalDisabled() {
+ enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeReleases})
}
-
- repo.IsMirror = true
- if err = repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "num_watches", "is_empty", "default_branch", "default_wiki_branch", "is_mirror"); err != nil {
- return nil, err
+ if opts.Wiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
+ enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeWiki})
}
-
- if err = repo_module.UpdateRepoSize(ctx, repo); err != nil {
- log.Error("Failed to update size for repository: %v", err)
+ if len(enableRepoUnits) > 0 {
+ err = UpdateRepositoryUnits(ctx, repo, enableRepoUnits, nil)
+ if err != nil {
+ return nil, err
+ }
}
-
- // this is necessary for sync local tags from remote
- configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName())
- if stdout, _, err := git.NewCommand("config").
- AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`).
- RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil {
- log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err)
- return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err)
- }
- } else {
- if err = repo_module.UpdateRepoSize(ctx, repo); err != nil {
- log.Error("Failed to update size for repository: %v", err)
- }
- if repo, err = CleanUpMigrateInfo(ctx, repo); err != nil {
- return nil, err
- }
- }
-
- var enableRepoUnits []repo_model.RepoUnit
- if opts.Releases && !unit_model.TypeReleases.UnitGlobalDisabled() {
- enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeReleases})
- }
- if opts.Wiki && !unit_model.TypeWiki.UnitGlobalDisabled() {
- enableRepoUnits = append(enableRepoUnits, repo_model.RepoUnit{RepoID: repo.ID, Type: unit_model.TypeWiki})
- }
- if len(enableRepoUnits) > 0 {
- err = UpdateRepositoryUnits(ctx, repo, enableRepoUnits, nil)
- if err != nil {
- return nil, err
- }
- }
- return repo, committer.Commit()
+ return repo, nil
+ })
}
// CleanUpMigrateInfo finishes migrating repository and/or wiki with things that don't need to be done for mirrors.
diff --git a/services/user/email_test.go b/services/user/email_test.go
index 78770633d20..76770a92301 100644
--- a/services/user/email_test.go
+++ b/services/user/email_test.go
@@ -9,9 +9,9 @@ import (
organization_model "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/setting"
- "github.com/gobwas/glob"
"github.com/stretchr/testify/assert"
)
diff --git a/services/user/user.go b/services/user/user.go
index c7252430dea..d8abf199c3f 100644
--- a/services/user/user.go
+++ b/services/user/user.go
@@ -210,65 +210,59 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error {
}
}
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ // Note: A user owns any repository or belongs to any organization
+ // cannot perform delete operation. This causes a race with the purge above
+ // however consistency requires that we ensure that this is the case
+
+ // Check ownership of repository.
+ count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: u.ID})
+ if err != nil {
+ return fmt.Errorf("GetRepositoryCount: %w", err)
+ } else if count > 0 {
+ return repo_model.ErrUserOwnRepos{UID: u.ID}
+ }
+
+ // Check membership of organization.
+ count, err = organization.GetOrganizationCount(ctx, u)
+ if err != nil {
+ return fmt.Errorf("GetOrganizationCount: %w", err)
+ } else if count > 0 {
+ return organization.ErrUserHasOrgs{UID: u.ID}
+ }
+
+ // Check ownership of packages.
+ if ownsPackages, err := packages_model.HasOwnerPackages(ctx, u.ID); err != nil {
+ return fmt.Errorf("HasOwnerPackages: %w", err)
+ } else if ownsPackages {
+ return packages_model.ErrUserOwnPackages{UID: u.ID}
+ }
+
+ if err := deleteUser(ctx, u, purge); err != nil {
+ return fmt.Errorf("DeleteUser: %w", err)
+ }
+ return nil
+ }); err != nil {
return err
}
- defer committer.Close()
- // Note: A user owns any repository or belongs to any organization
- // cannot perform delete operation. This causes a race with the purge above
- // however consistency requires that we ensure that this is the case
-
- // Check ownership of repository.
- count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: u.ID})
- if err != nil {
- return fmt.Errorf("GetRepositoryCount: %w", err)
- } else if count > 0 {
- return repo_model.ErrUserOwnRepos{UID: u.ID}
- }
-
- // Check membership of organization.
- count, err = organization.GetOrganizationCount(ctx, u)
- if err != nil {
- return fmt.Errorf("GetOrganizationCount: %w", err)
- } else if count > 0 {
- return organization.ErrUserHasOrgs{UID: u.ID}
- }
-
- // Check ownership of packages.
- if ownsPackages, err := packages_model.HasOwnerPackages(ctx, u.ID); err != nil {
- return fmt.Errorf("HasOwnerPackages: %w", err)
- } else if ownsPackages {
- return packages_model.ErrUserOwnPackages{UID: u.ID}
- }
-
- if err := deleteUser(ctx, u, purge); err != nil {
- return fmt.Errorf("DeleteUser: %w", err)
- }
-
- if err := committer.Commit(); err != nil {
+ if err := asymkey_service.RewriteAllPublicKeys(ctx); err != nil {
return err
}
- _ = committer.Close()
-
- if err = asymkey_service.RewriteAllPublicKeys(ctx); err != nil {
- return err
- }
- if err = asymkey_service.RewriteAllPrincipalKeys(ctx); err != nil {
+ if err := asymkey_service.RewriteAllPrincipalKeys(ctx); err != nil {
return err
}
// Note: There are something just cannot be roll back, so just keep error logs of those operations.
path := user_model.UserPath(u.Name)
- if err = util.RemoveAll(path); err != nil {
+ if err := util.RemoveAll(path); err != nil {
err = fmt.Errorf("failed to RemoveAll %s: %w", path, err)
_ = system_model.CreateNotice(ctx, system_model.NoticeTask, fmt.Sprintf("delete user '%s': %v", u.Name, err))
}
if u.Avatar != "" {
avatarPath := u.CustomAvatarRelativePath()
- if err = storage.Avatars.Delete(avatarPath); err != nil {
+ if err := storage.Avatars.Delete(avatarPath); err != nil {
err = fmt.Errorf("failed to remove %s: %w", avatarPath, err)
_ = system_model.CreateNotice(ctx, system_model.NoticeTask, fmt.Sprintf("delete user '%s': %v", u.Name, err))
}
diff --git a/services/webhook/deliver.go b/services/webhook/deliver.go
index e8e6ed19c14..b6611a3576d 100644
--- a/services/webhook/deliver.go
+++ b/services/webhook/deliver.go
@@ -21,6 +21,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/hostmatcher"
"code.gitea.io/gitea/modules/log"
@@ -30,8 +31,6 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
webhook_module "code.gitea.io/gitea/modules/webhook"
-
- "github.com/gobwas/glob"
)
func newDefaultRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (req *http.Request, body []byte, err error) {
diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go
index 182078b39d4..2b276207a13 100644
--- a/services/webhook/webhook.go
+++ b/services/webhook/webhook.go
@@ -15,6 +15,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/glob"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
@@ -23,8 +24,6 @@ import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
-
- "github.com/gobwas/glob"
)
type Requester func(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error)
diff --git a/templates/org/team/repositories.tmpl b/templates/org/team/repositories.tmpl
index 4f4667ca8bf..2f38071e89f 100644
--- a/templates/org/team/repositories.tmpl
+++ b/templates/org/team/repositories.tmpl
@@ -12,7 +12,7 @@