Skip to content

Commit e9ea4a5

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Fix slow patch checking with commits that add or remove many files (go-gitea#31548) Add typescript guideline and typescript-specific eslint plugins and fix issues (go-gitea#31521)
2 parents b021c13 + b88e5fc commit e9ea4a5

File tree

13 files changed

+274
-167
lines changed

13 files changed

+274
-167
lines changed

Diff for: .eslintrc.yaml

+127-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ parserOptions:
1313
ecmaVersion: latest
1414
project: true
1515
extraFileExtensions: [".vue"]
16+
parser: "@typescript-eslint/parser" # for vue plugin - https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
1617

1718
settings:
1819
import/extensions: [".js", ".ts"]
@@ -24,7 +25,9 @@ settings:
2425
plugins:
2526
- "@eslint-community/eslint-plugin-eslint-comments"
2627
- "@stylistic/eslint-plugin-js"
28+
- "@typescript-eslint/eslint-plugin"
2729
- eslint-plugin-array-func
30+
- eslint-plugin-deprecation
2831
- eslint-plugin-github
2932
- eslint-plugin-i
3033
- eslint-plugin-no-jquery
@@ -209,6 +212,123 @@ rules:
209212
"@stylistic/js/wrap-iife": [2, inside]
210213
"@stylistic/js/wrap-regex": [0]
211214
"@stylistic/js/yield-star-spacing": [2, after]
215+
"@typescript-eslint/adjacent-overload-signatures": [0]
216+
"@typescript-eslint/array-type": [0]
217+
"@typescript-eslint/await-thenable": [2]
218+
"@typescript-eslint/ban-ts-comment": [2, {'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': false, 'ts-check': false}]
219+
"@typescript-eslint/ban-tslint-comment": [0]
220+
"@typescript-eslint/ban-types": [2, {extendDefaults: true, types: {Function: false}}]
221+
"@typescript-eslint/class-literal-property-style": [0]
222+
"@typescript-eslint/class-methods-use-this": [0]
223+
"@typescript-eslint/consistent-generic-constructors": [0]
224+
"@typescript-eslint/consistent-indexed-object-style": [0]
225+
"@typescript-eslint/consistent-return": [0]
226+
"@typescript-eslint/consistent-type-assertions": [2, {assertionStyle: as, objectLiteralTypeAssertions: allow}]
227+
"@typescript-eslint/consistent-type-definitions": [2, type]
228+
"@typescript-eslint/consistent-type-exports": [2, {fixMixedExportsWithInlineTypeSpecifier: false}]
229+
"@typescript-eslint/consistent-type-imports": [2, {prefer: type-imports, fixStyle: separate-type-imports, disallowTypeAnnotations: true}]
230+
"@typescript-eslint/default-param-last": [0]
231+
"@typescript-eslint/dot-notation": [0]
232+
"@typescript-eslint/explicit-function-return-type": [0]
233+
"@typescript-eslint/explicit-member-accessibility": [0]
234+
"@typescript-eslint/explicit-module-boundary-types": [0]
235+
"@typescript-eslint/init-declarations": [0]
236+
"@typescript-eslint/max-params": [0]
237+
"@typescript-eslint/member-ordering": [0]
238+
"@typescript-eslint/method-signature-style": [0]
239+
"@typescript-eslint/naming-convention": [0]
240+
"@typescript-eslint/no-array-constructor": [2]
241+
"@typescript-eslint/no-array-delete": [2]
242+
"@typescript-eslint/no-base-to-string": [0]
243+
"@typescript-eslint/no-confusing-non-null-assertion": [2]
244+
"@typescript-eslint/no-confusing-void-expression": [0]
245+
"@typescript-eslint/no-dupe-class-members": [0]
246+
"@typescript-eslint/no-duplicate-enum-values": [2]
247+
"@typescript-eslint/no-duplicate-type-constituents": [2, {ignoreUnions: true}]
248+
"@typescript-eslint/no-dynamic-delete": [0]
249+
"@typescript-eslint/no-empty-function": [0]
250+
"@typescript-eslint/no-empty-interface": [0]
251+
"@typescript-eslint/no-explicit-any": [0]
252+
"@typescript-eslint/no-extra-non-null-assertion": [2]
253+
"@typescript-eslint/no-extraneous-class": [0]
254+
"@typescript-eslint/no-floating-promises": [0]
255+
"@typescript-eslint/no-for-in-array": [2]
256+
"@typescript-eslint/no-implied-eval": [2]
257+
"@typescript-eslint/no-import-type-side-effects": [0] # dupe with consistent-type-imports
258+
"@typescript-eslint/no-inferrable-types": [0]
259+
"@typescript-eslint/no-invalid-this": [0]
260+
"@typescript-eslint/no-invalid-void-type": [0]
261+
"@typescript-eslint/no-loop-func": [0]
262+
"@typescript-eslint/no-loss-of-precision": [2]
263+
"@typescript-eslint/no-magic-numbers": [0]
264+
"@typescript-eslint/no-meaningless-void-operator": [0]
265+
"@typescript-eslint/no-misused-new": [2]
266+
"@typescript-eslint/no-misused-promises": [2, {checksVoidReturn: {attributes: false, arguments: false}}]
267+
"@typescript-eslint/no-mixed-enums": [0]
268+
"@typescript-eslint/no-namespace": [2]
269+
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": [0]
270+
"@typescript-eslint/no-non-null-asserted-optional-chain": [2]
271+
"@typescript-eslint/no-non-null-assertion": [0]
272+
"@typescript-eslint/no-redeclare": [0]
273+
"@typescript-eslint/no-redundant-type-constituents": [2]
274+
"@typescript-eslint/no-require-imports": [0]
275+
"@typescript-eslint/no-restricted-imports": [0]
276+
"@typescript-eslint/no-shadow": [0]
277+
"@typescript-eslint/no-this-alias": [0] # handled by unicorn/no-this-assignment
278+
"@typescript-eslint/no-unnecessary-boolean-literal-compare": [0]
279+
"@typescript-eslint/no-unnecessary-condition": [0]
280+
"@typescript-eslint/no-unnecessary-qualifier": [0]
281+
"@typescript-eslint/no-unnecessary-template-expression": [0]
282+
"@typescript-eslint/no-unnecessary-type-arguments": [0]
283+
"@typescript-eslint/no-unnecessary-type-assertion": [2]
284+
"@typescript-eslint/no-unnecessary-type-constraint": [2]
285+
"@typescript-eslint/no-unsafe-argument": [0]
286+
"@typescript-eslint/no-unsafe-assignment": [0]
287+
"@typescript-eslint/no-unsafe-call": [0]
288+
"@typescript-eslint/no-unsafe-declaration-merging": [2]
289+
"@typescript-eslint/no-unsafe-enum-comparison": [2]
290+
"@typescript-eslint/no-unsafe-member-access": [0]
291+
"@typescript-eslint/no-unsafe-return": [0]
292+
"@typescript-eslint/no-unsafe-unary-minus": [2]
293+
"@typescript-eslint/no-unused-expressions": [0]
294+
"@typescript-eslint/no-unused-vars": [2, {vars: all, args: all, caughtErrors: all, ignoreRestSiblings: false, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_}]
295+
"@typescript-eslint/no-use-before-define": [0]
296+
"@typescript-eslint/no-useless-constructor": [0]
297+
"@typescript-eslint/no-useless-empty-export": [0]
298+
"@typescript-eslint/no-var-requires": [2]
299+
"@typescript-eslint/non-nullable-type-assertion-style": [0]
300+
"@typescript-eslint/only-throw-error": [2]
301+
"@typescript-eslint/parameter-properties": [0]
302+
"@typescript-eslint/prefer-as-const": [2]
303+
"@typescript-eslint/prefer-destructuring": [0]
304+
"@typescript-eslint/prefer-enum-initializers": [0]
305+
"@typescript-eslint/prefer-find": [2]
306+
"@typescript-eslint/prefer-for-of": [2]
307+
"@typescript-eslint/prefer-function-type": [2]
308+
"@typescript-eslint/prefer-includes": [2]
309+
"@typescript-eslint/prefer-literal-enum-member": [0]
310+
"@typescript-eslint/prefer-namespace-keyword": [0]
311+
"@typescript-eslint/prefer-nullish-coalescing": [0]
312+
"@typescript-eslint/prefer-optional-chain": [2, {requireNullish: true}]
313+
"@typescript-eslint/prefer-promise-reject-errors": [0]
314+
"@typescript-eslint/prefer-readonly": [0]
315+
"@typescript-eslint/prefer-readonly-parameter-types": [0]
316+
"@typescript-eslint/prefer-reduce-type-parameter": [0]
317+
"@typescript-eslint/prefer-regexp-exec": [0]
318+
"@typescript-eslint/prefer-return-this-type": [0]
319+
"@typescript-eslint/prefer-string-starts-ends-with": [2, {allowSingleElementEquality: always}]
320+
"@typescript-eslint/promise-function-async": [0]
321+
"@typescript-eslint/require-array-sort-compare": [0]
322+
"@typescript-eslint/require-await": [0]
323+
"@typescript-eslint/restrict-plus-operands": [2]
324+
"@typescript-eslint/restrict-template-expressions": [0]
325+
"@typescript-eslint/return-await": [0]
326+
"@typescript-eslint/strict-boolean-expressions": [0]
327+
"@typescript-eslint/switch-exhaustiveness-check": [0]
328+
"@typescript-eslint/triple-slash-reference": [2]
329+
"@typescript-eslint/typedef": [0]
330+
"@typescript-eslint/unbound-method": [2]
331+
"@typescript-eslint/unified-signatures": [2]
212332
accessor-pairs: [2]
213333
array-callback-return: [2, {checkForEach: true}]
214334
array-func/avoid-reverse: [2]
@@ -230,6 +350,7 @@ rules:
230350
default-case-last: [2]
231351
default-case: [0]
232352
default-param-last: [0]
353+
deprecation/deprecation: [2]
233354
dot-notation: [0]
234355
eqeqeq: [2]
235356
for-direction: [2]
@@ -321,7 +442,7 @@ rules:
321442
multiline-comment-style: [2, separate-lines]
322443
new-cap: [0]
323444
no-alert: [0]
324-
no-array-constructor: [2]
445+
no-array-constructor: [0] # handled by @typescript-eslint/no-array-constructor
325446
no-async-promise-executor: [0]
326447
no-await-in-loop: [0]
327448
no-bitwise: [0]
@@ -365,7 +486,7 @@ rules:
365486
no-global-assign: [2]
366487
no-implicit-coercion: [2]
367488
no-implicit-globals: [0]
368-
no-implied-eval: [2]
489+
no-implied-eval: [0] # handled by @typescript-eslint/no-implied-eval
369490
no-import-assign: [2]
370491
no-inline-comments: [0]
371492
no-inner-declarations: [2]
@@ -471,7 +592,7 @@ rules:
471592
no-lone-blocks: [2]
472593
no-lonely-if: [0]
473594
no-loop-func: [0]
474-
no-loss-of-precision: [2]
595+
no-loss-of-precision: [0] # handled by @typescript-eslint/no-loss-of-precision
475596
no-magic-numbers: [0]
476597
no-misleading-character-class: [2]
477598
no-multi-assign: [0]
@@ -493,7 +614,7 @@ rules:
493614
no-promise-executor-return: [0]
494615
no-proto: [2]
495616
no-prototype-builtins: [2]
496-
no-redeclare: [2]
617+
no-redeclare: [0] # must be disabled for typescript overloads
497618
no-regex-spaces: [2]
498619
no-restricted-exports: [0]
499620
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename]
@@ -526,7 +647,7 @@ rules:
526647
no-unused-expressions: [2]
527648
no-unused-labels: [2]
528649
no-unused-private-class-members: [2]
529-
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
650+
no-unused-vars: [0] # handled by @typescript-eslint/no-unused-vars
530651
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
531652
no-use-extend-native/no-use-extend-native: [2]
532653
no-useless-backreference: [2]
@@ -641,7 +762,7 @@ rules:
641762
regexp/unicode-escape: [0]
642763
regexp/use-ignore-case: [0]
643764
require-atomic-updates: [0]
644-
require-await: [0]
765+
require-await: [0] # handled by @typescript-eslint/require-await
645766
require-unicode-regexp: [0]
646767
require-yield: [2]
647768
sonarjs/cognitive-complexity: [0]

Diff for: docs/content/contributing/guidelines-frontend.en-us.md

+16
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ We use htmx for simple interactions. You can see an example for simple interacti
7979
Although mixing different frameworks is discouraged,
8080
it should also work if the mixing is necessary and the code is well-designed and maintainable.
8181

82+
### Typescript
83+
84+
Gitea is in the process of migrating to type-safe Typescript. Here are some specific guidelines regarding Typescript in the codebase:
85+
86+
#### Use type aliases instead of interfaces
87+
88+
Prefer to use type aliases because they can represent any type and are generally more flexible to use than interfaces.
89+
90+
#### Use separate type imports
91+
92+
We use `verbatimModuleSyntax` so type and non-type imports from the same file must be split into two `import type` statements. This enables the typescript compiler to completely eliminate the type import statements during compilation.
93+
94+
#### Use `@ts-expect-error` instead of `@ts-ignore`
95+
96+
Both annotations should be avoided, but if you have to use them, use `@ts-expect-error` because it will not leave ineffective statements after the issue is fixed.
97+
8298
### `async` Functions
8399

84100
Only mark a function as `async` if and only if there are `await` calls

Diff for: modules/git/repo_index.go

+27-8
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,8 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error {
104104
buffer := new(bytes.Buffer)
105105
for _, file := range filenames {
106106
if file != "" {
107-
buffer.WriteString("0 ")
108-
buffer.WriteString(objectFormat.EmptyObjectID().String())
109-
buffer.WriteByte('\t')
110-
buffer.WriteString(file)
111-
buffer.WriteByte('\000')
107+
// using format: mode SP type SP sha1 TAB path
108+
buffer.WriteString("0 blob " + objectFormat.EmptyObjectID().String() + "\t" + file + "\000")
112109
}
113110
}
114111
return cmd.Run(&RunOpts{
@@ -119,11 +116,33 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error {
119116
})
120117
}
121118

119+
type IndexObjectInfo struct {
120+
Mode string
121+
Object ObjectID
122+
Filename string
123+
}
124+
125+
// AddObjectsToIndex adds the provided object hashes to the index at the provided filenames
126+
func (repo *Repository) AddObjectsToIndex(objects ...IndexObjectInfo) error {
127+
cmd := NewCommand(repo.Ctx, "update-index", "--add", "--replace", "-z", "--index-info")
128+
stdout := new(bytes.Buffer)
129+
stderr := new(bytes.Buffer)
130+
buffer := new(bytes.Buffer)
131+
for _, object := range objects {
132+
// using format: mode SP type SP sha1 TAB path
133+
buffer.WriteString(object.Mode + " blob " + object.Object.String() + "\t" + object.Filename + "\000")
134+
}
135+
return cmd.Run(&RunOpts{
136+
Dir: repo.Path,
137+
Stdin: bytes.NewReader(buffer.Bytes()),
138+
Stdout: stdout,
139+
Stderr: stderr,
140+
})
141+
}
142+
122143
// AddObjectToIndex adds the provided object hash to the index at the provided filename
123144
func (repo *Repository) AddObjectToIndex(mode string, object ObjectID, filename string) error {
124-
cmd := NewCommand(repo.Ctx, "update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, object.String(), filename)
125-
_, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path})
126-
return err
145+
return repo.AddObjectsToIndex(IndexObjectInfo{Mode: mode, Object: object, Filename: filename})
127146
}
128147

129148
// WriteTree writes the current index as a tree to the object db and returns its hash

0 commit comments

Comments
 (0)