From 3e1b63f75b9185573d1b578387803e182e91bc5f Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Fri, 24 Jan 2025 00:31:03 +0000 Subject: [PATCH 001/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_pt-PT.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 270728582a..88308271a7 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -1952,6 +1952,7 @@ pulls.upstream_diverging_prompt_behind_1=Este ramo está %[1]d cometimento atrá pulls.upstream_diverging_prompt_behind_n=Este ramo está %[1]d cometimentos atrás de %[2]s pulls.upstream_diverging_prompt_base_newer=O ramo base %s tem novas modificações pulls.upstream_diverging_merge=Sincronizar derivação +pulls.upstream_diverging_merge_confirm=Gostaria de integrar "%[1]s" em "%[2]s"? pull.deleted_branch=(eliminado):%s pull.agit_documentation=Rever a documentação sobre o AGit @@ -3366,6 +3367,8 @@ monitor.previous=Execução anterior monitor.execute_times=Execuções monitor.process=Processos em execução monitor.stacktrace=Vestígios da pilha +monitor.trace=Rastreio +monitor.performance_logs=Registos de desempenho monitor.processes_count=%d processos monitor.download_diagnosis_report=Descarregar relatório de diagnóstico monitor.desc=Descrição From 9e028d8d578f5372efe3c3bac2044c001e01d93b Mon Sep 17 00:00:00 2001 From: Typed SIGTERM Date: Sat, 25 Jan 2025 01:09:57 +0800 Subject: [PATCH 002/655] Fix comment header padding (#33377) --- templates/repo/diff/comments.tmpl | 2 +- templates/repo/issue/view_content.tmpl | 2 +- templates/repo/issue/view_content/comments.tmpl | 10 +++++----- templates/repo/issue/view_content/conversation.tmpl | 2 +- web_src/css/repo.css | 8 ++------ 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl index 2d716688b9..ec52934a9d 100644 --- a/templates/repo/diff/comments.tmpl +++ b/templates/repo/diff/comments.tmpl @@ -8,7 +8,7 @@ {{template "shared/user/avatarlink" dict "user" .Poster}} {{end}}
-
+
{{if .OriginalAuthor}} diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index 1a68781ecd..50a41654f3 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -13,7 +13,7 @@ {{end}}
-
+
{{if .Issue.OriginalAuthor}} diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 2e1a67edcc..c1ad64a118 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -26,7 +26,7 @@ {{end}}
-
+
{{if .OriginalAuthor}} @@ -393,7 +393,7 @@ {{if or .Content .Attachments}}
-
+
{{if gt .Poster.ID 0}} @@ -633,8 +633,8 @@
{{if .Content}}
-
-
+
+ -
+
{{if .RenderedContent}} {{.RenderedContent}} diff --git a/templates/repo/issue/view_content/conversation.tmpl b/templates/repo/issue/view_content/conversation.tmpl index 14803298b8..e30784929f 100644 --- a/templates/repo/issue/view_content/conversation.tmpl +++ b/templates/repo/issue/view_content/conversation.tmpl @@ -57,7 +57,7 @@ {{$createdSubStr:= DateUtils.TimeSince .CreatedUnix}}
-
+
{{if not .OriginalAuthor}} diff --git a/web_src/css/repo.css b/web_src/css/repo.css index e86f81f13c..c40b175638 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1480,16 +1480,12 @@ td .commit-summary { } .comment-header { - border: none !important; background: var(--color-box-header); - border-bottom: 1px solid var(--color-secondary) !important; - font-weight: var(--font-weight-normal) !important; - padding: 0.5rem 1rem; - margin: 0 !important; + border-bottom: 1px solid var(--color-secondary); + padding: 0 1rem; position: relative; color: var(--color-text); min-height: 41px; - background-color: var(--color-box-header); display: flex; justify-content: space-between; align-items: center; From 642e8c1122d40fd260f31cb9e2e2ee32c777aed5 Mon Sep 17 00:00:00 2001 From: silverwind Date: Fri, 24 Jan 2025 18:35:28 +0100 Subject: [PATCH 003/655] Repo homepage styling tweaks (#33289) Reduce it to a value that results in `.repo-home-sidebar-top` and `.repo-home-sidebar-bottom` having 240px content width, the same as GitHub. Before: Screenshot 2025-01-15 at 18 28 34 After: Screenshot 2025-01-15 at 18 28 27 --- templates/repo/home_sidebar_top.tmpl | 2 +- templates/repo/sub_menu.tmpl | 2 +- web_src/css/repo/home.css | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/templates/repo/home_sidebar_top.tmpl b/templates/repo/home_sidebar_top.tmpl index d7c2b8336f..8d3d7c6f86 100644 --- a/templates/repo/home_sidebar_top.tmpl +++ b/templates/repo/home_sidebar_top.tmpl @@ -1,5 +1,5 @@
-
+
{{template "shared/search/button"}}
diff --git a/templates/repo/sub_menu.tmpl b/templates/repo/sub_menu.tmpl index 3533bfed0b..66ab86cb55 100644 --- a/templates/repo/sub_menu.tmpl +++ b/templates/repo/sub_menu.tmpl @@ -1,5 +1,5 @@ {{if and (not .HideRepoInfo) (not .IsBlame)}} -
+
From fae69bc6d4cbe3c93db9d33dc25e52f0ef267ddb Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 27 Jan 2025 00:32:12 +0000 Subject: [PATCH 013/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_fr-FR.ini | 12 ++++++++++++ options/locale/locale_ga-IE.ini | 17 ++++++++++++++--- options/locale/locale_ja-JP.ini | 13 +++++++++++++ options/locale/locale_pt-BR.ini | 4 ++-- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 0df4f5a00c..ced3ed7bd1 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -1115,6 +1115,7 @@ blame.ignore_revs=Les révisions dans .git-blame-ignore-revs so blame.ignore_revs.failed=Impossible d'ignorer les révisions dans .git-blame-ignore-revs. user_search_tooltip=Affiche un maximum de 30 utilisateurs +tree_path_not_found=Le chemin %[1]s n’existe pas dans %[2]s transfer.accept=Accepter le transfert transfer.accept_desc=Transférer à « %s » @@ -1683,13 +1684,16 @@ issues.timetracker_timer_manually_add=Pointer du temps issues.time_estimate_set=Définir le temps estimé issues.time_estimate_display=Estimation : %s +issues.change_time_estimate_at=a changé le temps estimé à %[1]s %[2]s issues.remove_time_estimate_at=a supprimé le temps estimé %s issues.time_estimate_invalid=Le format du temps estimé est invalide issues.start_tracking_history=`a commencé son travail %s.` issues.tracker_auto_close=Le minuteur sera automatiquement arrêté quand le ticket sera fermé. issues.tracking_already_started=`Vous avez déjà un minuteur en cours sur un autre ticket !` +issues.stop_tracking_history=a travaillé sur %[1]s %[2]s issues.cancel_tracking_history=`a abandonné son minuteur %s.` issues.del_time=Supprimer ce minuteur du journal +issues.add_time_history=a pointé du temps de travail sur %[1]s, %[2]s issues.del_time_history=`a supprimé son temps de travail %s.` issues.add_time_manually=Temps pointé manuellement issues.add_time_hours=Heures @@ -1948,6 +1952,7 @@ pulls.upstream_diverging_prompt_behind_1=Cette branche est en retard de %d révi pulls.upstream_diverging_prompt_behind_n=Cette branche est en retard de %d révisions sur %s pulls.upstream_diverging_prompt_base_newer=La branche de base %s a de nouveaux changements pulls.upstream_diverging_merge=Synchroniser la bifurcation +pulls.upstream_diverging_merge_confirm=Voulez-vous fusionner la branche par défaut du dépôt de base sur la branche %s de ce dépôt ? pull.deleted_branch=(supprimé) : %s pull.agit_documentation=Voir la documentation sur AGit @@ -2153,6 +2158,7 @@ settings.advanced_settings=Paramètres avancés settings.wiki_desc=Activer le wiki du dépôt settings.use_internal_wiki=Utiliser le wiki interne settings.default_wiki_branch_name=Nom de la branche du Wiki par défaut +settings.default_permission_everyone_access=Autorisation d’accès par défaut pour tous les utilisateurs connectés : settings.failed_to_change_default_wiki_branch=Impossible de modifier la branche du wiki par défaut. settings.use_external_wiki=Utiliser un wiki externe settings.external_wiki_url=URL Wiki externe @@ -2707,6 +2713,8 @@ branch.create_branch_operation=Créer une branche branch.new_branch=Créer une nouvelle branche branch.new_branch_from=`Créer une nouvelle branche à partir de "%s"` branch.renamed=La branche %s à été renommée en %s. +branch.rename_default_or_protected_branch_error=Seuls les administrateurs peuvent renommer les branches par défaut ou protégées. +branch.rename_protected_branch_failed=Cette branche est protégée par des règles de protection basées sur des globs. tag.create_tag=Créer l'étiquette %s tag.create_tag_operation=Créer une étiquette @@ -3359,6 +3367,8 @@ monitor.previous=Précédent monitor.execute_times=Exécutions monitor.process=Processus en cours d'exécution monitor.stacktrace=Piles d'execution +monitor.trace=Trace +monitor.performance_logs=Journaux de performance monitor.processes_count=%d processus monitor.download_diagnosis_report=Télécharger le rapport de diagnostic monitor.desc=Description @@ -3563,6 +3573,8 @@ conda.install=Pour installer le paquet en utilisant Conda, exécutez la commande container.details.type=Type d'image container.details.platform=Plateforme container.pull=Tirez l'image depuis un terminal : +container.images=Images +container.digest=Empreinte container.multi_arch=SE / Arch container.layers=Calques d'image container.labels=Labels diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index e6b4be6da1..a7309ee648 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -576,7 +576,7 @@ size_error=` ní mór méid %s.` min_size_error=` ní mór go mbeadh carachtar %s ar a laghad ann.` max_size_error=caithfidh %s carachtar ar a mhéad a bheith ann. email_error=`ní seoladh ríomhphoist bailí é.` -url_error=`ní URL bailí é `"%s". ` +url_error=`ní URL bailí é "%s".` include_error=` ní mór fotheaghrán a bheith ann "%s".` glob_pattern_error=` tá patrún glob neamhbhailí: %s.` regex_pattern_error=`tá patrún regex neamhbhailí: %s.` @@ -1278,7 +1278,7 @@ ambiguous_runes_header=`Tá carachtair Unicode débhríoch sa chomhad seo ` ambiguous_runes_description=`Tá carachtair Unicode sa chomhad seo a d'fhéadfadh a bheith mearbhall le carachtair eile. Má cheapann tú go bhfuil sé seo d'aon ghnó, is féidir leat neamhaird a dhéanamh go sábháilte don rabhadh seo Úsáid an cnaipe Escape chun iad a nochtadh. ` invisible_runes_line=`Tá carachtair unicode dofheicthe ag an líne seo ` ambiguous_runes_line=`Tá carachtair unicode débhríoch ag an líne seo ` -ambiguous_character=Is féidir `%[1]c [U+%04[1]X] a mheascadh le %[2]c [U+%04[2]X]` +ambiguous_character=`Is féidir %[1]c [U+%04[1]X] a mheascadh le %[2]c [U+%04[2]X]` escape_control_characters=Éalú unescape_control_characters=Dí-Éalú @@ -1646,7 +1646,7 @@ issues.label.filter_sort.by_size=Méid is lú issues.label.filter_sort.reverse_by_size=Méid is mó issues.num_participants=%d Rannpháirtithe issues.attachment.open_tab=`Cliceáil chun "%s" a fheiceáil i gcluaisín nua` -issues.attachment.download=`Cliceáil chun "%s" a íoslódáil +issues.attachment.download=Cliceáil chun "%s" a íoslódáil issues.subscribe=Liostáil issues.unsubscribe=Díliostáil issues.unpin=Díphoráil @@ -1684,13 +1684,16 @@ issues.timetracker_timer_manually_add=Cuir Am leis issues.time_estimate_set=Socraigh am measta issues.time_estimate_display=Meastachán: %s +issues.change_time_estimate_at=d'athraigh an meastachán ama go %[1]s %[2]s issues.remove_time_estimate_at=baineadh meastachán ama %s issues.time_estimate_invalid=Tá formáid meastachán ama neamhbhailí issues.start_tracking_history=thosaigh ag obair %s issues.tracker_auto_close=Stopfar ama go huathoibríoch nuair a dhúnfar an tsaincheist seo issues.tracking_already_started=`Tá tús curtha agat cheana féin ag rianú ama ar eagrán eile!` +issues.stop_tracking_history=d'oibrigh do %[1]s %[2]s issues.cancel_tracking_history=`rianú ama curtha ar ceal %s` issues.del_time=Scrios an log ama seo +issues.add_time_history=cuireadh am caite %[1]s %[2]s leis issues.del_time_history=`an t-am caite scriosta %s` issues.add_time_manually=Cuir Am leis de Láimh issues.add_time_hours=Uaireanta @@ -1949,6 +1952,7 @@ pulls.upstream_diverging_prompt_behind_1=Tá an brainse seo %[1]d tiomantas taob pulls.upstream_diverging_prompt_behind_n=Tá an brainse seo %[1]d geallta taobh thiar de %[2]s pulls.upstream_diverging_prompt_base_newer=Tá athruithe nua ar an mbunbhrainse %s pulls.upstream_diverging_merge=Forc sionc +pulls.upstream_diverging_merge_confirm=Ar mhaith leat "%[1]s" a chumasc le "%[2]s"? pull.deleted_branch=(scriosta): %s pull.agit_documentation=Déan athbhreithniú ar dhoiciméid faoi AGit @@ -2154,6 +2158,7 @@ settings.advanced_settings=Ardsocruithe settings.wiki_desc=Cumasaigh Stór Vicí settings.use_internal_wiki=Úsáid Vicí Insuite settings.default_wiki_branch_name=Ainm Brainse Réamhshocraithe Vicí +settings.default_permission_everyone_access=Cead rochtana réamhshocraithe do gach úsáideoir sínithe isteach: settings.failed_to_change_default_wiki_branch=Theip ar an brainse réamhshocraithe vicí a athrú. settings.use_external_wiki=Úsáid Vicí Seachtrach settings.external_wiki_url=URL Vicí Seachtrach @@ -2708,6 +2713,8 @@ branch.create_branch_operation=Cruthaigh brainse branch.new_branch=Cruthaigh brainse nua branch.new_branch_from=`Cruthaigh brainse nua ó "%s"` branch.renamed=Ainmníodh brainse %s go %s. +branch.rename_default_or_protected_branch_error=Ní féidir ach le riarthóirí brainsí réamhshocraithe nó cosanta a athainmniú. +branch.rename_protected_branch_failed=Tá an brainse seo faoi chosaint ag rialacha cosanta domhanda. tag.create_tag=Cruthaigh clib %s tag.create_tag_operation=Cruthaigh clib @@ -3360,6 +3367,8 @@ monitor.previous=Am Roimhe Seo monitor.execute_times=Forghníomhaíochtaí monitor.process=Próisis reatha monitor.stacktrace=Rian cruachta +monitor.trace=Rian +monitor.performance_logs=Logaí Feidhmíochta monitor.processes_count=Próisis %d monitor.download_diagnosis_report=Íoslódáil tuairisc diagnóis monitor.desc=Cur síos @@ -3564,6 +3573,8 @@ conda.install=Chun an pacáiste a shuiteáil ag úsáid Conda, reáchtáil an t- container.details.type=Cineál Íomhá container.details.platform=Ardán container.pull=Tarraing an íomhá ón líne ordaithe: +container.images=Íomhánna +container.digest=Díleáigh container.multi_arch=Córas Oibriúcháin / Ailtireacht container.layers=Sraitheanna Íomhá container.labels=Lipéid diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 31a5ee9d30..925d0249b7 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -1115,6 +1115,7 @@ blame.ignore_revs=.git-blame-ignore-revs で指定されたリ blame.ignore_revs.failed=.git-blame-ignore-revs によるリビジョンの無視は失敗しました。 user_search_tooltip=最大30人までのユーザーを表示 +tree_path_not_found=パス %[1]s は %[2]s に存在しません transfer.accept=移転を承認 transfer.accept_desc=`"%s" に移転` @@ -1951,6 +1952,7 @@ pulls.upstream_diverging_prompt_behind_1=このブランチは %[2]s よりも % pulls.upstream_diverging_prompt_behind_n=このブランチは %[2]s よりも %[1]d コミット遅れています pulls.upstream_diverging_prompt_base_newer=ベースブランチ %s に新しい変更があります pulls.upstream_diverging_merge=フォークを同期 +pulls.upstream_diverging_merge_confirm=`"%[2]s" に "%[1]s" をマージしてよろしいですか?` pull.deleted_branch=(削除済み):%s pull.agit_documentation=AGitに関するドキュメントを確認する @@ -2156,6 +2158,7 @@ settings.advanced_settings=拡張設定 settings.wiki_desc=Wikiを有効にする settings.use_internal_wiki=ビルトインのWikiを使用する settings.default_wiki_branch_name=デフォルトのWikiブランチ名 +settings.default_permission_everyone_access=すべてのサインインユーザーにデフォルトで許可するアクセス権限: settings.failed_to_change_default_wiki_branch=デフォルトのWikiブランチを変更できませんでした。 settings.use_external_wiki=外部のWikiを使用する settings.external_wiki_url=外部WikiのURL @@ -2623,6 +2626,9 @@ diff.image.overlay=オーバーレイ diff.has_escaped=この行には不可視Unicode文字があります diff.show_file_tree=ファイルツリーを表示 diff.hide_file_tree=ファイルツリーを隠す +diff.submodule_added=サブモジュール %[1]s が %[2]s で追加されました +diff.submodule_deleted=サブモジュール %[1]s が %[2]s から削除されました +diff.submodule_updated=サブモジュール %[1]s が更新されました: %[2]s releases.desc=プロジェクトバージョンとダウンロードの追跡。 release.releases=リリース @@ -2707,6 +2713,8 @@ branch.create_branch_operation=ブランチを作成 branch.new_branch=新しいブランチの作成 branch.new_branch_from=`"%s" から新しいブランチを作成` branch.renamed=ブランチ %s は %s にリネームされました。 +branch.rename_default_or_protected_branch_error=デフォルトブランチや保護ブランチのリネームが可能なのは管理者だけです。 +branch.rename_protected_branch_failed=このブランチはglobベースの保護ルールに従って保護されています。 tag.create_tag=タグ %s を作成 tag.create_tag_operation=タグの作成 @@ -3359,6 +3367,8 @@ monitor.previous=前回 monitor.execute_times=実行回数 monitor.process=実行中のプロセス monitor.stacktrace=スタックトレース +monitor.trace=トレース +monitor.performance_logs=パフォーマンスログ monitor.processes_count=%d プロセス monitor.download_diagnosis_report=診断レポートをダウンロード monitor.desc=説明 @@ -3533,6 +3543,7 @@ versions=バージョン versions.view_all=すべて表示 dependency.id=ID dependency.version=バージョン +search_in_external_registry=%s で検索 alpine.registry=あなたの /etc/apk/repositories ファイルにURLを追加して、このレジストリをセットアップします: alpine.registry.key=インデックス署名の検証のため、レジストリのRSA公開鍵を /etc/apk/keys/ フォルダにダウンロードします: alpine.registry.info=$branch と $repository は下にあるリストから選んでください。 @@ -3562,6 +3573,7 @@ conda.install=Conda を使用してパッケージをインストールするに container.details.type=イメージタイプ container.details.platform=プラットフォーム container.pull=コマンドラインでイメージを取得します: +container.images=イメージ container.digest=ダイジェスト container.multi_arch=OS / アーキテクチャ container.layers=イメージレイヤー @@ -3758,6 +3770,7 @@ workflow.not_found=ワークフロー '%s' が見つかりません。 workflow.run_success=ワークフロー '%s' は正常に実行されました。 workflow.from_ref=使用するワークフローの取得元 workflow.has_workflow_dispatch=このワークフローには workflow_dispatch イベントトリガーがあります。 +workflow.has_no_workflow_dispatch=ワークフロー '%s' には workflow_dispatch イベントトリガーがありません。 need_approval_desc=フォークプルリクエストのワークフローを実行するには承認が必要です。 diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 65d6b4569b..d3ccc711b2 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -1135,9 +1135,9 @@ file_view_raw=Ver original file_permalink=Link permanente file_too_large=O arquivo é muito grande para ser mostrado. invisible_runes_header=`Este arquivo contém caracteres Unicode invisíveis` -invisible_runes_description=`Este arquivo contém caracteres Unicode invisíveis que são indistinguíveis para humanos, mas que podem ser processados de forma diferente por um computador. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los +invisible_runes_description=Este arquivo contém caracteres Unicode invisíveis que são indistinguíveis para humanos, mas que podem ser processados de forma diferente por um computador. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los ambiguous_runes_header=`Este arquivo contém caracteres Unicode ambíguos` -ambiguous_runes_description=`Este arquivo contém caracteres Unicode que podem ser confundidos com outros caracteres. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los +ambiguous_runes_description=Este arquivo contém caracteres Unicode que podem ser confundidos com outros caracteres. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los invisible_runes_line=`Esta linha tem caracteres unicode invisíveis` ambiguous_runes_line=`Esta linha tem caracteres unicode ambíguos` From 517a367abea52fc96a1a8002c87bc20b8528dcd3 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 27 Jan 2025 09:14:08 +0800 Subject: [PATCH 014/655] Use ProtonMail/go-crypto to replace keybase/go-crypto (#33402) Fix #33400 The keybase/go-crypto is no longer maintained and it generates malformed signatures, ProtonMail/go-crypto is the actively maintained fork. --- assets/go-licenses.json | 5 ---- go.mod | 1 - go.sum | 2 -- models/asymkey/gpg_key.go | 12 ++++++--- models/asymkey/gpg_key_add.go | 8 +++--- models/asymkey/gpg_key_commit_verification.go | 2 +- models/asymkey/gpg_key_common.go | 12 ++++----- models/asymkey/gpg_key_test.go | 25 ++++++++++++++++++- routers/web/user/home.go | 4 +-- services/packages/arch/repository.go | 6 ++--- services/packages/debian/repository.go | 8 +++--- tests/integration/user_test.go | 9 +++---- 12 files changed, 55 insertions(+), 39 deletions(-) diff --git a/assets/go-licenses.json b/assets/go-licenses.json index a20494184b..29ed0848b8 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -744,11 +744,6 @@ "path": "github.com/kevinburke/ssh_config/LICENSE", "licenseText": "Copyright (c) 2017 Kevin Burke.\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\n===================\n\nThe lexer and parser borrow heavily from github.com/pelletier/go-toml. The\nlicense for that project is copied below.\n\nThe MIT License (MIT)\n\nCopyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton\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.\n" }, - { - "name": "github.com/keybase/go-crypto", - "path": "github.com/keybase/go-crypto/LICENSE", - "licenseText": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\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\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" - }, { "name": "github.com/klauspost/compress", "path": "github.com/klauspost/compress/LICENSE", diff --git a/go.mod b/go.mod index 0ee4257f13..e2ccdd5ae6 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,6 @@ require ( github.com/jhillyerd/enmime v1.3.0 github.com/json-iterator/go v1.1.12 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 - github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 github.com/klauspost/compress v1.17.11 github.com/klauspost/cpuid/v2 v2.2.8 github.com/lib/pq v1.10.9 diff --git a/go.sum b/go.sum index c145fa6beb..bc0265c51f 100644 --- a/go.sum +++ b/go.sum @@ -506,8 +506,6 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+4tLukHoB9iqHOu3LmLhRmgUxZo6Vp4= -github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= diff --git a/models/asymkey/gpg_key.go b/models/asymkey/gpg_key.go index 5236b2d450..e921340730 100644 --- a/models/asymkey/gpg_key.go +++ b/models/asymkey/gpg_key.go @@ -13,8 +13,8 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/timeutil" - "github.com/keybase/go-crypto/openpgp" - "github.com/keybase/go-crypto/openpgp/packet" + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/packet" "xorm.io/builder" ) @@ -141,7 +141,11 @@ func parseGPGKey(ctx context.Context, ownerID int64, e *openpgp.Entity, verified // Parse Subkeys subkeys := make([]*GPGKey, len(e.Subkeys)) for i, k := range e.Subkeys { - subs, err := parseSubGPGKey(ownerID, pubkey.KeyIdString(), k.PublicKey, expiry) + subkeyExpiry := expiry + if k.Sig.KeyLifetimeSecs != nil { + subkeyExpiry = k.PublicKey.CreationTime.Add(time.Duration(*k.Sig.KeyLifetimeSecs) * time.Second) + } + subs, err := parseSubGPGKey(ownerID, pubkey.KeyIdString(), k.PublicKey, subkeyExpiry) if err != nil { return nil, ErrGPGKeyParsing{ParseError: err} } @@ -156,7 +160,7 @@ func parseGPGKey(ctx context.Context, ownerID int64, e *openpgp.Entity, verified emails := make([]*user_model.EmailAddress, 0, len(e.Identities)) for _, ident := range e.Identities { - if ident.Revocation != nil { + if ident.Revoked(time.Now()) { continue } email := strings.ToLower(strings.TrimSpace(ident.UserId.Email)) diff --git a/models/asymkey/gpg_key_add.go b/models/asymkey/gpg_key_add.go index 11124b1366..6c0f6e01a7 100644 --- a/models/asymkey/gpg_key_add.go +++ b/models/asymkey/gpg_key_add.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/log" - "github.com/keybase/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp" ) // __________________ ________ ____ __. @@ -83,12 +83,12 @@ func AddGPGKey(ctx context.Context, ownerID int64, content, token, signature str verified := false // Handle provided signature if signature != "" { - signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(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)) + 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)) + signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil) } if err != nil { log.Error("Unable to validate token signature. Error: %v", err) diff --git a/models/asymkey/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go index 26fad3bb3f..9219a509df 100644 --- a/models/asymkey/gpg_key_commit_verification.go +++ b/models/asymkey/gpg_key_commit_verification.go @@ -16,7 +16,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/keybase/go-crypto/openpgp/packet" + "github.com/ProtonMail/go-crypto/openpgp/packet" ) // __________________ ________ ____ __. diff --git a/models/asymkey/gpg_key_common.go b/models/asymkey/gpg_key_common.go index 28cb8f4e76..92c34a2569 100644 --- a/models/asymkey/gpg_key_common.go +++ b/models/asymkey/gpg_key_common.go @@ -13,9 +13,9 @@ import ( "strings" "time" - "github.com/keybase/go-crypto/openpgp" - "github.com/keybase/go-crypto/openpgp/armor" - "github.com/keybase/go-crypto/openpgp/packet" + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/armor" + "github.com/ProtonMail/go-crypto/openpgp/packet" ) // __________________ ________ ____ __. @@ -80,7 +80,7 @@ func base64DecPubKey(content string) (*packet.PublicKey, error) { return pkey, nil } -// getExpiryTime extract the expire time of primary key based on sig +// getExpiryTime extract the expiry time of primary key based on sig func getExpiryTime(e *openpgp.Entity) time.Time { expiry := time.Time{} // Extract self-sign for expire date based on : https://github.com/golang/crypto/blob/master/openpgp/keys.go#L165 @@ -88,12 +88,12 @@ func getExpiryTime(e *openpgp.Entity) time.Time { for _, ident := range e.Identities { if selfSig == nil { selfSig = ident.SelfSignature - } else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId { + } else if ident.SelfSignature != nil && ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId { selfSig = ident.SelfSignature break } } - if selfSig.KeyLifetimeSecs != nil { + if selfSig != nil && selfSig.KeyLifetimeSecs != nil { expiry = e.PrimaryKey.CreationTime.Add(time.Duration(*selfSig.KeyLifetimeSecs) * time.Second) } return expiry diff --git a/models/asymkey/gpg_key_test.go b/models/asymkey/gpg_key_test.go index 0bccbb51b5..d7f0ff5364 100644 --- a/models/asymkey/gpg_key_test.go +++ b/models/asymkey/gpg_key_test.go @@ -13,7 +13,8 @@ import ( "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" - "github.com/keybase/go-crypto/openpgp/packet" + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/packet" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -403,3 +404,25 @@ func TestTryGetKeyIDFromSignature(t *testing.T) { IssuerFingerprint: []uint8{0xb, 0x23, 0x24, 0xc7, 0xe6, 0xfe, 0x4f, 0x3a, 0x6, 0x26, 0xc1, 0x21, 0x3, 0x8d, 0x1a, 0x3e, 0xad, 0xdb, 0xea, 0x9c}, })) } + +func TestParseGPGKey(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + assert.NoError(t, db.Insert(db.DefaultContext, &user_model.EmailAddress{UID: 1, Email: "email1@example.com", IsActivated: true})) + + // create a key for test email + e, err := openpgp.NewEntity("name", "comment", "email1@example.com", nil) + require.NoError(t, err) + k, err := parseGPGKey(db.DefaultContext, 1, e, true) + require.NoError(t, err) + assert.NotEmpty(t, k.KeyID) + assert.NotEmpty(t, k.Emails) // the key is valid, matches the email + + // then revoke the key + for _, id := range e.Identities { + id.Revocations = append(id.Revocations, &packet.Signature{RevocationReason: util.ToPointer(packet.KeyCompromised)}) + } + k, err = parseGPGKey(db.DefaultContext, 1, e, true) + require.NoError(t, err) + assert.NotEmpty(t, k.KeyID) + assert.Empty(t, k.Emails) // the key is revoked, matches no email +} diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 235a7c6f39..c4ed242f71 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -41,8 +41,8 @@ import ( issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" - "github.com/keybase/go-crypto/openpgp" - "github.com/keybase/go-crypto/openpgp/armor" + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/armor" "xorm.io/builder" ) diff --git a/services/packages/arch/repository.go b/services/packages/arch/repository.go index 6731d9a1ac..7fb4222cf6 100644 --- a/services/packages/arch/repository.go +++ b/services/packages/arch/repository.go @@ -26,9 +26,9 @@ import ( "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" - "github.com/keybase/go-crypto/openpgp" - "github.com/keybase/go-crypto/openpgp/armor" - "github.com/keybase/go-crypto/openpgp/packet" + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/armor" + "github.com/ProtonMail/go-crypto/openpgp/packet" ) const ( diff --git a/services/packages/debian/repository.go b/services/packages/debian/repository.go index 13e98a820e..34b52b45cf 100644 --- a/services/packages/debian/repository.go +++ b/services/packages/debian/repository.go @@ -23,10 +23,10 @@ import ( "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" - "github.com/keybase/go-crypto/openpgp" - "github.com/keybase/go-crypto/openpgp/armor" - "github.com/keybase/go-crypto/openpgp/clearsign" - "github.com/keybase/go-crypto/openpgp/packet" + "github.com/ProtonMail/go-crypto/openpgp" + "github.com/ProtonMail/go-crypto/openpgp/armor" + "github.com/ProtonMail/go-crypto/openpgp/clearsign" + "github.com/ProtonMail/go-crypto/openpgp/packet" "github.com/ulikunitz/xz" ) diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index 5b6f28d1ff..bf248a4dde 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -134,8 +134,7 @@ Note: This user hasn't uploaded any GPG keys. =twTO ------END PGP PUBLIC KEY BLOCK----- -`) +-----END PGP PUBLIC KEY BLOCK-----`) // Import key // User1 session := loginUser(t, "user1") @@ -169,8 +168,7 @@ C0TLXKur6NVYQMn01iyL+FZzRpEWNuYF3f9QeeLJ/+l2DafESNhNTy17+RPmacK6 7XhJ1v6JYuh8kaYaEz8OpZDeh7f6Ho6PzJrsy/TKTKhGgZNINj1iaPFyOkQgKR5M GrE0MHOxUbc9tbtyk0F1SuzREUBH =DDXw ------END PGP PUBLIC KEY BLOCK----- -`) +-----END PGP PUBLIC KEY BLOCK-----`) // Export new key testExportUserGPGKeys(t, "user1", `-----BEGIN PGP PUBLIC KEY BLOCK----- @@ -201,8 +199,7 @@ C0TLXKur6NVYQMn01iyL+FZzRpEWNuYF3f9QeeLJ/+l2DafESNhNTy17+RPmacK6 7XhJ1v6JYuh8kaYaEz8OpZDeh7f6Ho6PzJrsy/TKTKhGgZNINj1iaPFyOkQgKR5M GrE0MHOxUbc9tbtyk0F1SuzREUBH =WFf5 ------END PGP PUBLIC KEY BLOCK----- -`) +-----END PGP PUBLIC KEY BLOCK-----`) } func testExportUserGPGKeys(t *testing.T, user, expected string) { From 26b51aa0328e90032283d3d707508ab3824ad9ed Mon Sep 17 00:00:00 2001 From: hiifong Date: Mon, 27 Jan 2025 09:44:09 +0800 Subject: [PATCH 015/655] Optimize makefile help information generation (#33390) Get help information from the target's comments. ![image](https://github.com/user-attachments/assets/ee259545-99b7-4163-a8da-011159f8301b) --- Makefile | 176 +++++++++++++++++++------------------------------------ 1 file changed, 60 insertions(+), 116 deletions(-) diff --git a/Makefile b/Makefile index a2cb30022e..8a7855bd5a 100644 --- a/Makefile +++ b/Makefile @@ -189,67 +189,11 @@ TEST_MSSQL_PASSWORD ?= MwantsaSecurePassword1 all: build .PHONY: help -help: - @echo "Make Routines:" - @echo " - \"\" equivalent to \"build\"" - @echo " - build build everything" - @echo " - frontend build frontend files" - @echo " - backend build backend files" - @echo " - watch watch everything and continuously rebuild" - @echo " - watch-frontend watch frontend files and continuously rebuild" - @echo " - watch-backend watch backend files and continuously rebuild" - @echo " - clean delete backend and integration files" - @echo " - clean-all delete backend, frontend and integration files" - @echo " - deps install dependencies" - @echo " - deps-frontend install frontend dependencies" - @echo " - deps-backend install backend dependencies" - @echo " - deps-tools install tool dependencies" - @echo " - deps-py install python dependencies" - @echo " - lint lint everything" - @echo " - lint-fix lint everything and fix issues" - @echo " - lint-actions lint action workflow files" - @echo " - lint-frontend lint frontend files" - @echo " - lint-frontend-fix lint frontend files and fix issues" - @echo " - lint-backend lint backend files" - @echo " - lint-backend-fix lint backend files and fix issues" - @echo " - lint-go lint go files" - @echo " - lint-go-fix lint go files and fix issues" - @echo " - lint-go-vet lint go files with vet" - @echo " - lint-go-gopls lint go files with gopls" - @echo " - lint-js lint js files" - @echo " - lint-js-fix lint js files and fix issues" - @echo " - lint-css lint css files" - @echo " - lint-css-fix lint css files and fix issues" - @echo " - lint-md lint markdown files" - @echo " - lint-swagger lint swagger files" - @echo " - lint-templates lint template files" - @echo " - lint-yaml lint yaml files" - @echo " - lint-spell lint spelling" - @echo " - lint-spell-fix lint spelling and fix issues" - @echo " - checks run various consistency checks" - @echo " - checks-frontend check frontend files" - @echo " - checks-backend check backend files" - @echo " - test test everything" - @echo " - test-frontend test frontend files" - @echo " - test-backend test backend files" - @echo " - test-e2e[\#TestSpecificName] test end to end using playwright" - @echo " - update update js and py dependencies" - @echo " - update-js update js dependencies" - @echo " - update-py update py dependencies" - @echo " - webpack build webpack files" - @echo " - svg build svg files" - @echo " - fomantic build fomantic files" - @echo " - generate run \"go generate\"" - @echo " - fmt format the Go code" - @echo " - generate-license update license files" - @echo " - generate-gitignore update gitignore files" - @echo " - generate-manpage generate manpage" - @echo " - generate-swagger generate the swagger spec from code comments" - @echo " - swagger-validate check if the swagger spec is valid" - @echo " - go-licenses regenerate go licenses" - @echo " - tidy run go mod tidy" - @echo " - test[\#TestSpecificName] run unit test" - @echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite" +help: Makefile ## print Makefile help information. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m[TARGETS] default target: build\033[0m\n\n\033[35mTargets:\033[0m\n"} /^[0-9A-Za-z._-]+:.*?##/ { printf " \033[36m%-45s\033[0m %s\n", $$1, $$2 }' Makefile #$(MAKEFILE_LIST) + @printf " \033[36m%-46s\033[0m %s\n" "test-e2e[#TestSpecificName]" "test end to end using playwright" + @printf " \033[36m%-46s\033[0m %s\n" "test[#TestSpecificName]" "run unit test" + @printf " \033[36m%-46s\033[0m %s\n" "test-sqlite[#TestSpecificName]" "run integration test for sqlite" .PHONY: go-check go-check: @@ -280,11 +224,11 @@ node-check: fi .PHONY: clean-all -clean-all: clean +clean-all: clean ## delete backend, frontend and integration files rm -rf $(WEBPACK_DEST_ENTRIES) node_modules .PHONY: clean -clean: +clean: ## delete backend and integration files rm -rf $(EXECUTABLE) $(DIST) $(BINDATA_DEST) $(BINDATA_HASH) \ integrations*.test \ e2e*.test \ @@ -296,7 +240,7 @@ clean: tests/e2e/reports/ tests/e2e/test-artifacts/ tests/e2e/test-snapshots/ .PHONY: fmt -fmt: +fmt: ## format the Go code @GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}' $(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl')) @# strip whitespace after '{{' or '(' and before '}}' or ')' unless there is only @@ -325,7 +269,7 @@ TAGS_PREREQ := $(TAGS_EVIDENCE) endif .PHONY: generate-swagger -generate-swagger: $(SWAGGER_SPEC) +generate-swagger: $(SWAGGER_SPEC) ## generate the swagger spec from code comments $(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA) $(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)' @@ -342,78 +286,78 @@ swagger-check: generate-swagger fi .PHONY: swagger-validate -swagger-validate: +swagger-validate: ## check if the swagger spec is valid $(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)' $(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' .PHONY: checks -checks: checks-frontend checks-backend +checks: checks-frontend checks-backend ## run various consistency checks .PHONY: checks-frontend -checks-frontend: lockfile-check svg-check +checks-frontend: lockfile-check svg-check ## check frontend files .PHONY: checks-backend -checks-backend: tidy-check swagger-check fmt-check swagger-validate security-check +checks-backend: tidy-check swagger-check fmt-check swagger-validate security-check ## check backend files .PHONY: lint -lint: lint-frontend lint-backend lint-spell +lint: lint-frontend lint-backend lint-spell ## lint everything .PHONY: lint-fix -lint-fix: lint-frontend-fix lint-backend-fix lint-spell-fix +lint-fix: lint-frontend-fix lint-backend-fix lint-spell-fix ## lint everything and fix issues .PHONY: lint-frontend -lint-frontend: lint-js lint-css +lint-frontend: lint-js lint-css ## lint frontend files .PHONY: lint-frontend-fix -lint-frontend-fix: lint-js-fix lint-css-fix +lint-frontend-fix: lint-js-fix lint-css-fix ## lint frontend files and fix issues .PHONY: lint-backend -lint-backend: lint-go lint-go-vet lint-go-gopls lint-editorconfig +lint-backend: lint-go lint-go-vet lint-go-gopls lint-editorconfig ## lint backend files .PHONY: lint-backend-fix -lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig +lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig ## lint backend files and fix issues .PHONY: lint-js -lint-js: node_modules +lint-js: node_modules ## lint js files npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) npx vue-tsc .PHONY: lint-js-fix -lint-js-fix: node_modules +lint-js-fix: node_modules ## lint js files and fix issues npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) --fix npx vue-tsc .PHONY: lint-css -lint-css: node_modules +lint-css: node_modules ## lint css files npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) .PHONY: lint-css-fix -lint-css-fix: node_modules +lint-css-fix: node_modules ## lint css files and fix issues npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix .PHONY: lint-swagger -lint-swagger: node_modules +lint-swagger: node_modules ## lint swagger files npx spectral lint -q -F hint $(SWAGGER_SPEC) .PHONY: lint-md -lint-md: node_modules +lint-md: node_modules ## lint markdown files npx markdownlint *.md .PHONY: lint-spell -lint-spell: +lint-spell: ## lint spelling @go run $(MISSPELL_PACKAGE) -dict tools/misspellings.csv -error $(SPELLCHECK_FILES) .PHONY: lint-spell-fix -lint-spell-fix: +lint-spell-fix: ## lint spelling and fix issues @go run $(MISSPELL_PACKAGE) -dict tools/misspellings.csv -w $(SPELLCHECK_FILES) .PHONY: lint-go -lint-go: +lint-go: ## lint go files $(GO) run $(GOLANGCI_LINT_PACKAGE) run .PHONY: lint-go-fix -lint-go-fix: +lint-go-fix: ## lint go files and fix issues $(GO) run $(GOLANGCI_LINT_PACKAGE) run --fix # workaround step for the lint-go-windows CI task because 'go run' can not @@ -424,13 +368,13 @@ lint-go-windows: golangci-lint run .PHONY: lint-go-vet -lint-go-vet: +lint-go-vet: ## lint go files with vet @echo "Running go vet..." @GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet @$(GO) vet -vettool=gitea-vet ./... .PHONY: lint-go-gopls -lint-go-gopls: +lint-go-gopls: ## lint go files with gopls @echo "Running gopls check..." @GO=$(GO) GOPLS_PACKAGE=$(GOPLS_PACKAGE) tools/lint-go-gopls.sh $(GO_SOURCES_NO_BINDATA) @@ -439,41 +383,41 @@ lint-editorconfig: @$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) $(EDITORCONFIG_FILES) .PHONY: lint-actions -lint-actions: +lint-actions: ## lint action workflow files $(GO) run $(ACTIONLINT_PACKAGE) .PHONY: lint-templates -lint-templates: .venv node_modules +lint-templates: .venv node_modules ## lint template files @node tools/lint-templates-svg.js @poetry run djlint $(shell find templates -type f -iname '*.tmpl') .PHONY: lint-yaml -lint-yaml: .venv +lint-yaml: .venv ## lint yaml files @poetry run yamllint . .PHONY: watch -watch: +watch: ## watch everything and continuously rebuild @bash tools/watch.sh .PHONY: watch-frontend -watch-frontend: node-check node_modules +watch-frontend: node-check node_modules ## watch frontend files and continuously rebuild @rm -rf $(WEBPACK_DEST_ENTRIES) NODE_ENV=development npx webpack --watch --progress .PHONY: watch-backend -watch-backend: go-check +watch-backend: go-check ## watch backend files and continuously rebuild GITEA_RUN_MODE=dev $(GO) run $(AIR_PACKAGE) -c .air.toml .PHONY: test -test: test-frontend test-backend +test: test-frontend test-backend ## test everything .PHONY: test-backend -test-backend: +test-backend: ## test frontend files @echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." @$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_TEST_PACKAGES) .PHONY: test-frontend -test-frontend: node_modules +test-frontend: node_modules ## test backend files npx vitest .PHONY: test-check @@ -505,7 +449,7 @@ unit-test-coverage: @$(GO) test $(GOTESTFLAGS) -timeout=20m -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_TEST_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1 .PHONY: tidy -tidy: +tidy: ## run go mod tidy $(eval MIN_GO_VERSION := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2)) $(GO) mod tidy -compat=$(MIN_GO_VERSION) @$(MAKE) --no-print-directory $(GO_LICENSE_FILE) @@ -524,7 +468,7 @@ tidy-check: tidy fi .PHONY: go-licenses -go-licenses: $(GO_LICENSE_FILE) +go-licenses: $(GO_LICENSE_FILE) ## regenerate go licenses $(GO_LICENSE_FILE): go.mod go.sum -$(GO) run $(GO_LICENSES_PACKAGE) save . --force --save_path=$(GO_LICENSE_TMP_DIR) 2>/dev/null @@ -771,17 +715,17 @@ install: $(wildcard *.go) CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) install -v -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' .PHONY: build -build: frontend backend +build: frontend backend ## build everything .PHONY: frontend -frontend: $(WEBPACK_DEST) +frontend: $(WEBPACK_DEST) ## build frontend files .PHONY: backend -backend: go-check generate-backend $(EXECUTABLE) +backend: go-check generate-backend $(EXECUTABLE) ## build backend files # We generate the backend before the frontend in case we in future we want to generate things in the frontend from generated files in backend .PHONY: generate -generate: generate-backend +generate: generate-backend ## run "go generate" .PHONY: generate-backend generate-backend: $(TAGS_PREREQ) generate-go @@ -846,20 +790,20 @@ release-sources: | $(DIST_DIRS) rm -f $(STORED_VERSION_FILE) .PHONY: deps -deps: deps-frontend deps-backend deps-tools deps-py +deps: deps-frontend deps-backend deps-tools deps-py ## install dependencies .PHONY: deps-py -deps-py: .venv +deps-py: .venv ## install python dependencies .PHONY: deps-frontend -deps-frontend: node_modules +deps-frontend: node_modules ## install frontend dependencies .PHONY: deps-backend -deps-backend: +deps-backend: ## install backend dependencies $(GO) mod download .PHONY: deps-tools -deps-tools: +deps-tools: ## install tool dependencies $(GO) install $(AIR_PACKAGE) & \ $(GO) install $(EDITORCONFIG_CHECKER_PACKAGE) & \ $(GO) install $(GOFUMPT_PACKAGE) & \ @@ -883,10 +827,10 @@ node_modules: package-lock.json @touch .venv .PHONY: update -update: update-js update-py +update: update-js update-py ## update js and py dependencies .PHONY: update-js -update-js: node-check | node_modules +update-js: node-check | node_modules ## update js dependencies npx updates -u -f package.json rm -rf node_modules package-lock.json npm install --package-lock @@ -895,14 +839,14 @@ update-js: node-check | node_modules @touch node_modules .PHONY: update-py -update-py: node-check | node_modules +update-py: node-check | node_modules ## update py dependencies npx updates -u -f pyproject.toml rm -rf .venv poetry.lock poetry install @touch .venv .PHONY: fomantic -fomantic: +fomantic: ## build fomantic files rm -rf $(FOMANTIC_WORK_DIR)/build cd $(FOMANTIC_WORK_DIR) && npm install --no-save cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config @@ -915,7 +859,7 @@ fomantic: rm -f $(FOMANTIC_WORK_DIR)/build/*.min.* .PHONY: webpack -webpack: $(WEBPACK_DEST) +webpack: $(WEBPACK_DEST) ## build webpack files $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json @$(MAKE) -s node-check node_modules @@ -925,7 +869,7 @@ $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json @touch $(WEBPACK_DEST) .PHONY: svg -svg: node-check | node_modules +svg: node-check | node_modules ## build svg files rm -rf $(SVG_DEST_DIR) node tools/generate-svg.js @@ -961,11 +905,11 @@ update-translations: rmdir ./translations .PHONY: generate-license -generate-license: +generate-license: ## update license files $(GO) run build/generate-licenses.go .PHONY: generate-gitignore -generate-gitignore: +generate-gitignore: ## update gitignore files $(GO) run build/generate-gitignores.go .PHONY: generate-images @@ -974,7 +918,7 @@ generate-images: | node_modules node tools/generate-images.js $(TAGS) .PHONY: generate-manpage -generate-manpage: +generate-manpage: ## generate manpage @[ -f gitea ] || make backend @mkdir -p man/man1/ man/man5 @./gitea docs --man > man/man1/gitea.1 From c79adf00b830ea206d1c46ce298c86802c5404d9 Mon Sep 17 00:00:00 2001 From: Wesley van Tilburg Date: Mon, 27 Jan 2025 03:07:39 +0100 Subject: [PATCH 016/655] Add basic auth support to rss/atom feeds (#33371) Allows RSS readers to access private feeds using their basic auth capabilities. Not all clients feature the ability to add cookies or headers. fixes #32458 Tested with miniflux no credentials: ![image](https://github.com/user-attachments/assets/8c3369f2-1cf6-4ce3-ac6e-84447e454928) basic auth entered: ![image](https://github.com/user-attachments/assets/c93ff22c-1429-4a80-898f-91d9f35c7c61) ![image](https://github.com/user-attachments/assets/60d83afd-9dde-4973-a440-ff8138799e87) --------- Co-authored-by: wxiaoguang --- services/auth/auth.go | 20 ++++++++++++--- services/auth/auth_test.go | 51 +++++++++++++++++++++++++++----------- services/auth/basic.go | 5 ++-- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/services/auth/auth.go b/services/auth/auth.go index eb90202d24..7deca9bc3d 100644 --- a/services/auth/auth.go +++ b/services/auth/auth.go @@ -26,13 +26,17 @@ type globalVarsStruct struct { gitRawOrAttachPathRe *regexp.Regexp lfsPathRe *regexp.Regexp archivePathRe *regexp.Regexp + feedPathRe *regexp.Regexp + feedRefPathRe *regexp.Regexp } var globalVars = sync.OnceValue(func() *globalVarsStruct { return &globalVarsStruct{ - gitRawOrAttachPathRe: regexp.MustCompile(`^/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+/(?:(?:git-(?:(?:upload)|(?:receive))-pack$)|(?:info/refs$)|(?:HEAD$)|(?:objects/)|(?:raw/)|(?:releases/download/)|(?:attachments/))`), - lfsPathRe: regexp.MustCompile(`^/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+/info/lfs/`), - archivePathRe: regexp.MustCompile(`^/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+/archive/`), + gitRawOrAttachPathRe: regexp.MustCompile(`^/[-.\w]+/[-.\w]+/(?:(?:git-(?:(?:upload)|(?:receive))-pack$)|(?:info/refs$)|(?:HEAD$)|(?:objects/)|(?:raw/)|(?:releases/download/)|(?:attachments/))`), + lfsPathRe: regexp.MustCompile(`^/[-.\w]+/[-.\w]+/info/lfs/`), + archivePathRe: regexp.MustCompile(`^/[-.\w]+/[-.\w]+/archive/`), + feedPathRe: regexp.MustCompile(`^/[-.\w]+(/[-.\w]+)?\.(rss|atom)$`), // "/owner.rss" or "/owner/repo.atom" + feedRefPathRe: regexp.MustCompile(`^/[-.\w]+/[-.\w]+/(rss|atom)/`), // "/owner/repo/rss/branch/..." } }) @@ -61,6 +65,16 @@ func (a *authPathDetector) isAttachmentDownload() bool { return strings.HasPrefix(a.req.URL.Path, "/attachments/") && a.req.Method == "GET" } +func (a *authPathDetector) isFeedRequest(req *http.Request) bool { + if !setting.Other.EnableFeed { + return false + } + if req.Method != "GET" { + return false + } + return a.vars.feedPathRe.MatchString(req.URL.Path) || a.vars.feedRefPathRe.MatchString(req.URL.Path) +} + // isContainerPath checks if the request targets the container endpoint func (a *authPathDetector) isContainerPath() bool { return strings.HasPrefix(a.req.URL.Path, "/v2/") diff --git a/services/auth/auth_test.go b/services/auth/auth_test.go index 55ffdebe2d..b8d3396163 100644 --- a/services/auth/auth_test.go +++ b/services/auth/auth_test.go @@ -9,6 +9,7 @@ import ( "testing" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "github.com/stretchr/testify/assert" ) @@ -92,6 +93,19 @@ func Test_isGitRawOrLFSPath(t *testing.T) { true, }, } + + defer test.MockVariableValue(&setting.LFS.StartServer)() + for _, tt := range tests { + t.Run(tt.path, func(t *testing.T) { + req, _ := http.NewRequest("POST", "http://localhost"+tt.path, nil) + setting.LFS.StartServer = false + assert.Equal(t, tt.want, newAuthPathDetector(req).isGitRawOrAttachOrLFSPath()) + + setting.LFS.StartServer = true + assert.Equal(t, tt.want, newAuthPathDetector(req).isGitRawOrAttachOrLFSPath()) + }) + } + lfsTests := []string{ "/owner/repo/info/lfs/", "/owner/repo/info/lfs/objects/batch", @@ -103,19 +117,6 @@ func Test_isGitRawOrLFSPath(t *testing.T) { "/owner/repo/info/lfs/locks/verify", "/owner/repo/info/lfs/locks/123/unlock", } - - origLFSStartServer := setting.LFS.StartServer - - for _, tt := range tests { - t.Run(tt.path, func(t *testing.T) { - req, _ := http.NewRequest("POST", "http://localhost"+tt.path, nil) - setting.LFS.StartServer = false - assert.Equal(t, tt.want, newAuthPathDetector(req).isGitRawOrAttachOrLFSPath()) - - setting.LFS.StartServer = true - assert.Equal(t, tt.want, newAuthPathDetector(req).isGitRawOrAttachOrLFSPath()) - }) - } for _, tt := range lfsTests { t.Run(tt, func(t *testing.T) { req, _ := http.NewRequest("POST", tt, nil) @@ -128,5 +129,27 @@ func Test_isGitRawOrLFSPath(t *testing.T) { assert.Equalf(t, setting.LFS.StartServer, got, "isGitOrLFSPath(%q) = %v, want %v", tt, got, setting.LFS.StartServer) }) } - setting.LFS.StartServer = origLFSStartServer +} + +func Test_isFeedRequest(t *testing.T) { + tests := []struct { + want bool + path string + }{ + {true, "/user.rss"}, + {true, "/user/repo.atom"}, + {false, "/user/repo"}, + {false, "/use/repo/file.rss"}, + + {true, "/org/repo/rss/branch/xxx"}, + {true, "/org/repo/atom/tag/xxx"}, + {false, "/org/repo/branch/main/rss/any"}, + {false, "/org/atom/any"}, + } + for _, tt := range tests { + t.Run(tt.path, func(t *testing.T) { + req, _ := http.NewRequest("GET", "http://localhost"+tt.path, nil) + assert.Equal(t, tt.want, newAuthPathDetector(req).isFeedRequest(req)) + }) + } } diff --git a/services/auth/basic.go b/services/auth/basic.go index 67987206a7..e22b9e1eb7 100644 --- a/services/auth/basic.go +++ b/services/auth/basic.go @@ -47,9 +47,10 @@ func (b *Basic) Name() string { // name/token on successful validation. // Returns nil if header is empty or validation fails. func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { - // Basic authentication should only fire on API, Download or on Git or LFSPaths + // Basic authentication should only fire on API, Feed, Download or on Git or LFSPaths + // Not all feed (rss/atom) clients feature the ability to add cookies or headers, so we need to allow basic auth for feeds detector := newAuthPathDetector(req) - if !detector.isAPIPath() && !detector.isContainerPath() && !detector.isAttachmentDownload() && !detector.isGitRawOrAttachOrLFSPath() { + if !detector.isAPIPath() && !detector.isFeedRequest(req) && !detector.isContainerPath() && !detector.isAttachmentDownload() && !detector.isGitRawOrAttachOrLFSPath() { return nil, nil } From 6ca91f555ab9778310ac46cbbe33849c59286793 Mon Sep 17 00:00:00 2001 From: TheFox0x7 Date: Mon, 27 Jan 2025 03:33:39 +0100 Subject: [PATCH 017/655] User facing messages for AGit errors (#33012) Adds user facing messages to errors when submitting agit pull request Tries to highlight the returned error more and fixes agit suggestion to create PR on first submission. Closes: https://github.com/go-gitea/gitea/issues/32965 --------- Co-authored-by: wxiaoguang --- cmd/serv.go | 5 ++++- routers/private/hook_proc_receive.go | 16 ++++++++++++---- services/agit/agit.go | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/cmd/serv.go b/cmd/serv.go index d2271b68d2..476fd9a2ea 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -104,7 +104,10 @@ func fail(ctx context.Context, userMessage, logMsgFmt string, args ...any) error // There appears to be a chance to cause a zombie process and failure to read the Exit status // if nothing is outputted on stdout. _, _ = fmt.Fprintln(os.Stdout, "") - _, _ = fmt.Fprintln(os.Stderr, "Gitea:", userMessage) + // add extra empty lines to separate our message from other git errors to get more attention + _, _ = fmt.Fprintln(os.Stderr, "error:") + _, _ = fmt.Fprintln(os.Stderr, "error:", userMessage) + _, _ = fmt.Fprintln(os.Stderr, "error:") if logMsgFmt != "" { logMsg := fmt.Sprintf(logMsgFmt, args...) diff --git a/routers/private/hook_proc_receive.go b/routers/private/hook_proc_receive.go index efb3f5831e..4076a57dba 100644 --- a/routers/private/hook_proc_receive.go +++ b/routers/private/hook_proc_receive.go @@ -4,9 +4,11 @@ package private import ( + "errors" "net/http" - repo_model "code.gitea.io/gitea/models/repo" + issues_model "code.gitea.io/gitea/models/issues" + user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" @@ -25,10 +27,16 @@ func HookProcReceive(ctx *gitea_context.PrivateContext) { results, err := agit.ProcReceive(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, opts) if err != nil { - if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { - ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) + if errors.Is(err, issues_model.ErrMustCollaborator) { + ctx.JSON(http.StatusUnauthorized, private.Response{ + Err: err.Error(), UserMsg: "You must be a collaborator to create pull request.", + }) + } else if errors.Is(err, user_model.ErrBlockedUser) { + ctx.JSON(http.StatusUnauthorized, private.Response{ + Err: err.Error(), UserMsg: "Cannot create pull request because you are blocked by the repository owner.", + }) } else { - log.Error(err.Error()) + log.Error("agit.ProcReceive failed: %v", err) ctx.JSON(http.StatusInternalServerError, private.Response{ Err: err.Error(), }) diff --git a/services/agit/agit.go b/services/agit/agit.go index 83b12dfcdb..897e825012 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -153,7 +153,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. OriginalRef: opts.RefFullNames[i], OldOID: objectFormat.EmptyObjectID().String(), NewOID: opts.NewCommitIDs[i], - IsCreatePR: true, + IsCreatePR: false, // AGit always creates a pull request so there is no point in prompting user to create one URL: fmt.Sprintf("%s/pulls/%d", repo.HTMLURL(), pr.Index), ShouldShowMessage: setting.Git.PullRequestPushMessage && repo.AllowsPulls(ctx), HeadBranch: headBranch, From dcd3014567f2b8be3fca01c20c2b3eabdc8f519e Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 27 Jan 2025 07:58:46 -0800 Subject: [PATCH 018/655] Add pubdate for repository rss and add some tests (#33411) Fix #33291 --- routers/web/feed/branch.go | 1 + routers/web/feed/file.go | 1 + tests/integration/feed_repo_test.go | 35 +++++++++++++++++++ ...pi_feed_user_test.go => feed_user_test.go} | 25 ++++++++++++- 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/integration/feed_repo_test.go rename tests/integration/{api_feed_user_test.go => feed_user_test.go} (53%) diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go index 6c4cc11ca0..d3dae9503e 100644 --- a/routers/web/feed/branch.go +++ b/routers/web/feed/branch.go @@ -43,6 +43,7 @@ func ShowBranchFeed(ctx *context.Context, repo *repo.Repository, formatType stri }, Description: commit.Message(), Content: commit.Message(), + Created: commit.Committer.When, }) } diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go index 518d995ccb..407e4fa2d5 100644 --- a/routers/web/feed/file.go +++ b/routers/web/feed/file.go @@ -55,6 +55,7 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string }, Description: commit.Message(), Content: commit.Message(), + Created: commit.Committer.When, }) } diff --git a/tests/integration/feed_repo_test.go b/tests/integration/feed_repo_test.go new file mode 100644 index 0000000000..132ed32ced --- /dev/null +++ b/tests/integration/feed_repo_test.go @@ -0,0 +1,35 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "encoding/xml" + "net/http" + "testing" + + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestFeedRepo(t *testing.T) { + t.Run("RSS", func(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + req := NewRequest(t, "GET", "/user2/repo1.rss") + resp := MakeRequest(t, req, http.StatusOK) + + data := resp.Body.String() + assert.Contains(t, data, ` Date: Mon, 27 Jan 2025 08:25:14 -0800 Subject: [PATCH 019/655] Fix system admin cannot fork or get private fork with API (#33401) Fix #33368 --- routers/api/v1/repo/fork.go | 16 ++++++++------ services/repository/fork.go | 8 ++++--- tests/integration/api_fork_test.go | 33 +++++++++++++++++++++++++++-- tests/integration/repo_fork_test.go | 3 ++- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 14a1a8d1c4..f96c432b92 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -132,13 +132,15 @@ func CreateFork(ctx *context.APIContext) { } return } - isMember, err := org.IsOrgMember(ctx, ctx.Doer.ID) - if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrgMember", err) - return - } else if !isMember { - ctx.Error(http.StatusForbidden, "isMemberNot", fmt.Sprintf("User is no Member of Organisation '%s'", org.Name)) - return + if !ctx.Doer.IsAdmin { + isMember, err := org.IsOrgMember(ctx, ctx.Doer.ID) + if err != nil { + ctx.Error(http.StatusInternalServerError, "IsOrgMember", err) + return + } else if !isMember { + ctx.Error(http.StatusForbidden, "isMemberNot", fmt.Sprintf("User is no Member of Organisation '%s'", org.Name)) + return + } } forker = org.AsUser() } diff --git a/services/repository/fork.go b/services/repository/fork.go index cff0b1a403..8d89c2b0b0 100644 --- a/services/repository/fork.go +++ b/services/repository/fork.go @@ -256,9 +256,11 @@ type findForksOptions struct { } func (opts findForksOptions) ToConds() builder.Cond { - return builder.Eq{"fork_id": opts.RepoID}.And( - repo_model.AccessibleRepositoryCondition(opts.Doer, unit.TypeInvalid), - ) + cond := builder.Eq{"fork_id": opts.RepoID} + if opts.Doer != nil && opts.Doer.IsAdmin { + return cond + } + return cond.And(repo_model.AccessibleRepositoryCondition(opts.Doer, unit.TypeInvalid)) } // FindForks returns all the forks of the repository diff --git a/tests/integration/api_fork_test.go b/tests/integration/api_fork_test.go index 580bb459e7..69f37f4574 100644 --- a/tests/integration/api_fork_test.go +++ b/tests/integration/api_fork_test.go @@ -10,6 +10,7 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" org_model "code.gitea.io/gitea/models/organization" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" @@ -81,8 +82,8 @@ func TestAPIForkListLimitedAndPrivateRepos(t *testing.T) { var forks []*api.Repository DecodeJSON(t, resp, &forks) - assert.Len(t, forks, 1) - assert.EqualValues(t, "1", resp.Header().Get("X-Total-Count")) + assert.Len(t, forks, 2) + assert.EqualValues(t, "2", resp.Header().Get("X-Total-Count")) assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam2, user1)) @@ -96,3 +97,31 @@ func TestAPIForkListLimitedAndPrivateRepos(t *testing.T) { assert.EqualValues(t, "2", resp.Header().Get("X-Total-Count")) }) } + +func TestGetPrivateReposForks(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user1Sess := loginUser(t, "user1") + repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) // private repository + privateOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 23}) + user1Token := getTokenForLoggedInUser(t, user1Sess, auth_model.AccessTokenScopeWriteRepository) + + forkedRepoName := "forked-repo" + // create fork from a private repository + req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+repo2.FullName()+"/forks", &api.CreateForkOption{ + Organization: &privateOrg.Name, + Name: &forkedRepoName, + }).AddTokenAuth(user1Token) + MakeRequest(t, req, http.StatusAccepted) + + // test get a private fork without clear permissions + req = NewRequest(t, "GET", "/api/v1/repos/"+repo2.FullName()+"/forks").AddTokenAuth(user1Token) + resp := MakeRequest(t, req, http.StatusOK) + + forks := []*api.Repository{} + DecodeJSON(t, resp, &forks) + assert.Len(t, forks, 1) + assert.EqualValues(t, "1", resp.Header().Get("X-Total-Count")) + assert.EqualValues(t, "forked-repo", forks[0].Name) + assert.EqualValues(t, privateOrg.Name, forks[0].Owner.UserName) +} diff --git a/tests/integration/repo_fork_test.go b/tests/integration/repo_fork_test.go index 267fd0d56e..cbe5e4bb3f 100644 --- a/tests/integration/repo_fork_test.go +++ b/tests/integration/repo_fork_test.go @@ -118,7 +118,8 @@ func TestForkListLimitedAndPrivateRepos(t *testing.T) { req := NewRequest(t, "GET", "/user2/repo1/forks") resp := user1Sess.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) - assert.EqualValues(t, 1, htmlDoc.Find(forkItemSelector).Length()) + // since user1 is an admin, he can get both of the forked repositories + assert.EqualValues(t, 2, htmlDoc.Find(forkItemSelector).Length()) assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam2, user1)) resp = user1Sess.MakeRequest(t, req, http.StatusOK) From 182e3896bf6c6b3aeb313d2227ff96e35fbf46bd Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 28 Jan 2025 01:09:20 +0800 Subject: [PATCH 020/655] Fix flex width (#33414) Fix #33409 --- web_src/css/repo/home-file-list.css | 1 + 1 file changed, 1 insertion(+) diff --git a/web_src/css/repo/home-file-list.css b/web_src/css/repo/home-file-list.css index 19ba1f2bcb..189b6406d4 100644 --- a/web_src/css/repo/home-file-list.css +++ b/web_src/css/repo/home-file-list.css @@ -65,6 +65,7 @@ } #repo-files-table .repo-file-last-commit { + min-width: 0; /* otherwise the flex axis is not limited and the text might overflow in Pale Moon */ background: var(--color-box-header); } From 8cd10f7f3b76c070ca1aadccd470e732fb833a2f Mon Sep 17 00:00:00 2001 From: silverwind Date: Mon, 27 Jan 2025 22:57:14 +0100 Subject: [PATCH 021/655] Updates for poetry 2.0 (#33415) - Remove removed [`no-setuptools`](https://github.com/python-poetry/poetry/pull/9331) option, it's the default now - Ran `make update-py` under poetry 2.0.1 which updated the lockfile Also see https://github.com/python-poetry/poetry/releases/tag/2.0.0 --- poetry.lock | 21 +++++++++++++++++++-- poetry.toml | 1 - 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8c01674966..ab5bcf05ac 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. [[package]] name = "click" @@ -6,6 +6,7 @@ version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -20,6 +21,7 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -31,6 +33,7 @@ version = "1.15.1" description = "CSS unobfuscator and beautifier." optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "cssbeautifier-1.15.1.tar.gz", hash = "sha256:9f7064362aedd559c55eeecf6b6bed65e05f33488dcbe39044f0403c26e1c006"}, ] @@ -46,6 +49,7 @@ version = "1.36.4" description = "HTML Template Linter and Formatter" optional = false python-versions = ">=3.9" +groups = ["dev"] files = [ {file = "djlint-1.36.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2dfb60883ceb92465201bfd392291a7597c6752baede6fbb6f1980cac8d6c5c"}, {file = "djlint-1.36.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4bc6a1320c0030244b530ac200642f883d3daa451a115920ef3d56d08b644292"}, @@ -90,6 +94,7 @@ version = "0.17.0" description = "EditorConfig File Locator and Interpreter for Python" optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "EditorConfig-0.17.0-py3-none-any.whl", hash = "sha256:fe491719c5f65959ec00b167d07740e7ffec9a3f362038c72b289330b9991dfc"}, {file = "editorconfig-0.17.0.tar.gz", hash = "sha256:8739052279699840065d3a9f5c125d7d5a98daeefe53b0e5274261d77cb49aa2"}, @@ -101,6 +106,7 @@ version = "1.15.1" description = "JavaScript unobfuscator and beautifier." optional = false python-versions = "*" +groups = ["dev"] files = [ {file = "jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24"}, ] @@ -115,6 +121,7 @@ version = "0.10.0" description = "A Python implementation of the JSON5 data format." optional = false python-versions = ">=3.8.0" +groups = ["dev"] files = [ {file = "json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa"}, {file = "json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559"}, @@ -129,6 +136,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -140,6 +148,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -202,6 +211,7 @@ version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, @@ -305,6 +315,7 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["dev"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -316,6 +327,8 @@ version = "2.2.1" description = "A lil' TOML parser" optional = false python-versions = ">=3.8" +groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -357,6 +370,7 @@ version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" +groups = ["dev"] files = [ {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, @@ -378,6 +392,8 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["dev"] +markers = "python_version < \"3.11\"" files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -389,6 +405,7 @@ version = "1.35.1" description = "A linter for YAML files." optional = false python-versions = ">=3.8" +groups = ["dev"] files = [ {file = "yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3"}, {file = "yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd"}, @@ -402,6 +419,6 @@ pyyaml = "*" dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] [metadata] -lock-version = "2.0" +lock-version = "2.1" python-versions = "^3.10" content-hash = "f2e8260efe6e25f77ef387daff9551e41d25027e4794b42bc7a851ed0dfafd85" diff --git a/poetry.toml b/poetry.toml index 0299355b5d..6eda9f8eff 100644 --- a/poetry.toml +++ b/poetry.toml @@ -1,4 +1,3 @@ [virtualenvs] in-project = true options.no-pip = true -options.no-setuptools = true From 121e4c962417c7f0a355552ed2414f3c2dd209f3 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Tue, 28 Jan 2025 00:31:19 +0000 Subject: [PATCH 022/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_ga-IE.ini | 2 +- options/locale/locale_pt-BR.ini | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index a7309ee648..805deb618d 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -1646,7 +1646,7 @@ issues.label.filter_sort.by_size=Méid is lú issues.label.filter_sort.reverse_by_size=Méid is mó issues.num_participants=%d Rannpháirtithe issues.attachment.open_tab=`Cliceáil chun "%s" a fheiceáil i gcluaisín nua` -issues.attachment.download=Cliceáil chun "%s" a íoslódáil +issues.attachment.download=`Cliceáil chun "%s" a íoslódáil` issues.subscribe=Liostáil issues.unsubscribe=Díliostáil issues.unpin=Díphoráil diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index d3ccc711b2..cc21c5abea 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -1135,9 +1135,9 @@ file_view_raw=Ver original file_permalink=Link permanente file_too_large=O arquivo é muito grande para ser mostrado. invisible_runes_header=`Este arquivo contém caracteres Unicode invisíveis` -invisible_runes_description=Este arquivo contém caracteres Unicode invisíveis que são indistinguíveis para humanos, mas que podem ser processados de forma diferente por um computador. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los +invisible_runes_description=`Este arquivo contém caracteres Unicode invisíveis que são indistinguíveis para humanos, mas que podem ser processados de forma diferente por um computador. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los` ambiguous_runes_header=`Este arquivo contém caracteres Unicode ambíguos` -ambiguous_runes_description=Este arquivo contém caracteres Unicode que podem ser confundidos com outros caracteres. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los +ambiguous_runes_description=`Este arquivo contém caracteres Unicode que podem ser confundidos com outros caracteres. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los` invisible_runes_line=`Esta linha tem caracteres unicode invisíveis` ambiguous_runes_line=`Esta linha tem caracteres unicode ambíguos` From 8f433132e1a08ebb85e216db7d788ab795baadf5 Mon Sep 17 00:00:00 2001 From: silverwind Date: Tue, 28 Jan 2025 03:34:01 +0100 Subject: [PATCH 023/655] Update stylelint config (#33419) - Inherit stylelint config from [`stylelint-config-recommended`](https://github.com/stylelint/stylelint-config-recommended), removed all stylelint core rule options that were either already in their config or disabled. - `no-descending-specificity` diverges from their config, seems to much work currently. - Tweaked a few rules. - Added [`stylelint-define-config`](https://github.com/stylelint-types/stylelint-define-config) so that typescript can validate the config. --- package-lock.json | 55 +++++++++++++++++--- package.json | 4 +- stylelint.config.js | 120 ++++---------------------------------------- 3 files changed, 63 insertions(+), 116 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2c4f79926d..e7dead1871 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,9 +103,11 @@ "markdownlint-cli": "0.43.0", "nolyfill": "1.0.43", "postcss-html": "1.8.0", - "stylelint": "16.13.2", + "stylelint": "16.14.1", + "stylelint-config-recommended": "15.0.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", "stylelint-declaration-strict-value": "1.10.7", + "stylelint-define-config": "16.14.0", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "3.3.2", "type-fest": "4.33.0", @@ -13143,9 +13145,9 @@ "license": "ISC" }, "node_modules/stylelint": { - "version": "16.13.2", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.13.2.tgz", - "integrity": "sha512-wDlgh0mRO9RtSa3TdidqHd0nOG8MmUyVKl+dxA6C1j8aZRzpNeEgdhFmU5y4sZx4Fc6r46p0fI7p1vR5O2DZqA==", + "version": "16.14.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.14.1.tgz", + "integrity": "sha512-oqCL7AC3786oTax35T/nuLL8p2C3k/8rHKAooezrPGRvUX0wX+qqs5kMWh5YYT4PHQgVDobHT4tw55WgpYG6Sw==", "dev": true, "funding": [ { @@ -13177,7 +13179,7 @@ "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", - "ignore": "^7.0.1", + "ignore": "^7.0.3", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", "known-css-properties": "^0.35.0", @@ -13186,7 +13188,7 @@ "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", - "postcss": "^8.4.49", + "postcss": "^8.5.1", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.0.0", @@ -13205,6 +13207,29 @@ "node": ">=18.12.0" } }, + "node_modules/stylelint-config-recommended": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-15.0.0.tgz", + "integrity": "sha512-9LejMFsat7L+NXttdHdTq94byn25TD+82bzGRiV1Pgasl99pWnwipXS5DguTpp3nP1XjvLXVnEJIuYBfsRjRkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "stylelint": "^16.13.0" + } + }, "node_modules/stylelint-declaration-block-no-ignored-properties": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/stylelint-declaration-block-no-ignored-properties/-/stylelint-declaration-block-no-ignored-properties-2.8.0.tgz", @@ -13231,6 +13256,24 @@ "stylelint": ">=7 <=16" } }, + "node_modules/stylelint-define-config": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/stylelint-define-config/-/stylelint-define-config-16.14.0.tgz", + "integrity": "sha512-5R7/Vv6awCkNaPcedo1GuUp+7YTFvDnexogO4l/C0i349pBDYbefN6XzsDGsGOhU++maQSh2fp3mWNO0F16IjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.1.3" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=9.0.0", + "pnpm": ">=8.6.0" + }, + "peerDependencies": { + "stylelint": ">=16.0.0" + } + }, "node_modules/stylelint-value-no-unknown-custom-properties": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/stylelint-value-no-unknown-custom-properties/-/stylelint-value-no-unknown-custom-properties-6.0.1.tgz", diff --git a/package.json b/package.json index 97f73b7973..2ee785da72 100644 --- a/package.json +++ b/package.json @@ -102,9 +102,11 @@ "markdownlint-cli": "0.43.0", "nolyfill": "1.0.43", "postcss-html": "1.8.0", - "stylelint": "16.13.2", + "stylelint": "16.14.1", + "stylelint-config-recommended": "15.0.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", "stylelint-declaration-strict-value": "1.10.7", + "stylelint-define-config": "16.14.0", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "3.3.2", "type-fest": "4.33.0", diff --git a/stylelint.config.js b/stylelint.config.js index 977c35d9d5..1153bf7308 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -1,3 +1,5 @@ +// @ts-check +import {defineConfig} from 'stylelint-define-config'; import {fileURLToPath} from 'node:url'; const cssVarFiles = [ @@ -6,8 +8,8 @@ const cssVarFiles = [ fileURLToPath(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url)), ]; -/** @type {import('stylelint').Config} */ -export default { +export default defineConfig({ + extends: 'stylelint-config-recommended', plugins: [ 'stylelint-declaration-strict-value', 'stylelint-declaration-block-no-ignored-properties', @@ -67,7 +69,7 @@ export default { '@stylistic/function-comma-space-after': null, '@stylistic/function-comma-space-before': null, '@stylistic/function-max-empty-lines': 0, - '@stylistic/function-parentheses-newline-inside': 'never-multi-line', + '@stylistic/function-parentheses-newline-inside': null, '@stylistic/function-parentheses-space-inside': null, '@stylistic/function-whitespace-after': null, '@stylistic/indentation': 2, @@ -114,134 +116,34 @@ export default { '@stylistic/value-list-comma-space-after': null, '@stylistic/value-list-comma-space-before': null, '@stylistic/value-list-max-empty-lines': 0, - 'alpha-value-notation': null, - 'annotation-no-unknown': true, - 'at-rule-allowed-list': null, - 'at-rule-disallowed-list': null, - 'at-rule-empty-line-before': null, 'at-rule-no-unknown': [true, {ignoreAtRules: ['tailwind']}], 'at-rule-no-vendor-prefix': true, - 'at-rule-property-required-list': null, - 'block-no-empty': true, - 'color-function-notation': null, - 'color-hex-alpha': null, - 'color-hex-length': null, - 'color-named': null, - 'color-no-hex': null, - 'color-no-invalid-hex': true, - 'comment-empty-line-before': null, - 'comment-no-empty': true, - 'comment-pattern': null, - 'comment-whitespace-inside': null, - 'comment-word-disallowed-list': null, 'csstools/value-no-unknown-custom-properties': [true, {importFrom: cssVarFiles}], - 'custom-media-pattern': null, - 'custom-property-empty-line-before': null, - 'custom-property-no-missing-var-function': true, - 'custom-property-pattern': null, - 'declaration-block-no-duplicate-custom-properties': true, 'declaration-block-no-duplicate-properties': [true, {ignore: ['consecutive-duplicates-with-different-values']}], - 'declaration-block-no-redundant-longhand-properties': [true, {ignoreShorthands: ['flex-flow', 'overflow']}], - 'declaration-block-no-shorthand-property-overrides': null, - 'declaration-block-single-line-max-declarations': null, - 'declaration-empty-line-before': null, - 'declaration-no-important': null, - 'declaration-property-max-values': null, - 'declaration-property-unit-allowed-list': null, + 'declaration-block-no-redundant-longhand-properties': [true, {ignoreShorthands: ['flex-flow', 'overflow', 'grid-template']}], + // @ts-expect-error - https://github.com/stylelint-types/stylelint-define-config/issues/1 'declaration-property-unit-disallowed-list': {'line-height': ['em']}, - 'declaration-property-value-allowed-list': null, + // @ts-expect-error - https://github.com/stylelint-types/stylelint-define-config/issues/1 'declaration-property-value-disallowed-list': {'word-break': ['break-word']}, - 'declaration-property-value-no-unknown': true, 'font-family-name-quotes': 'always-where-recommended', - 'font-family-no-duplicate-names': true, - 'font-family-no-missing-generic-family-keyword': true, - 'font-weight-notation': null, - 'function-allowed-list': null, - 'function-calc-no-unspaced-operator': true, - 'function-disallowed-list': null, - 'function-linear-gradient-no-nonstandard-direction': true, 'function-name-case': 'lower', - 'function-no-unknown': true, - 'function-url-no-scheme-relative': null, 'function-url-quotes': 'always', - 'function-url-scheme-allowed-list': null, - 'function-url-scheme-disallowed-list': null, - 'hue-degree-notation': null, 'import-notation': 'string', - 'keyframe-block-no-duplicate-selectors': true, - 'keyframe-declaration-no-important': true, - 'keyframe-selector-notation': null, - 'keyframes-name-pattern': null, - 'length-zero-no-unit': [true, {ignore: ['custom-properties']}, {ignoreFunctions: ['var']}], - 'max-nesting-depth': null, - 'media-feature-name-allowed-list': null, - 'media-feature-name-disallowed-list': null, - 'media-feature-name-no-unknown': true, + 'length-zero-no-unit': [true, {ignore: ['custom-properties'], ignoreFunctions: ['var']}], 'media-feature-name-no-vendor-prefix': true, - 'media-feature-name-unit-allowed-list': null, - 'media-feature-name-value-allowed-list': null, - 'media-feature-name-value-no-unknown': true, - 'media-feature-range-notation': null, - 'media-query-no-invalid': true, - 'named-grid-areas-no-invalid': true, 'no-descending-specificity': null, - 'no-duplicate-at-import-rules': true, - 'no-duplicate-selectors': true, - 'no-empty-source': true, - 'no-invalid-double-slash-comments': true, 'no-invalid-position-at-import-rule': [true, {ignoreAtRules: ['tailwind']}], - 'no-irregular-whitespace': true, 'no-unknown-animations': null, // disabled until stylelint supports multi-file linting 'no-unknown-custom-media': null, // disabled until stylelint supports multi-file linting 'no-unknown-custom-properties': null, // disabled until stylelint supports multi-file linting - 'number-max-precision': null, 'plugin/declaration-block-no-ignored-properties': true, - 'property-allowed-list': null, - 'property-disallowed-list': null, - 'property-no-unknown': true, - 'property-no-vendor-prefix': null, - 'rule-empty-line-before': null, - 'rule-selector-property-disallowed-list': null, - 'scale-unlimited/declaration-strict-value': [['/color$/', 'font-weight'], {ignoreValues: '/^(inherit|transparent|unset|initial|currentcolor|none)$/', ignoreFunctions: false, disableFix: true, expandShorthand: true}], - 'selector-anb-no-unmatchable': true, - 'selector-attribute-name-disallowed-list': null, - 'selector-attribute-operator-allowed-list': null, - 'selector-attribute-operator-disallowed-list': null, + 'scale-unlimited/declaration-strict-value': [['/color$/', 'font-weight'], {ignoreValues: '/^(inherit|transparent|unset|initial|currentcolor|none)$/', ignoreFunctions: true, disableFix: true, expandShorthand: true}], 'selector-attribute-quotes': 'always', - 'selector-class-pattern': null, - 'selector-combinator-allowed-list': null, - 'selector-combinator-disallowed-list': null, - 'selector-disallowed-list': null, - 'selector-id-pattern': null, - 'selector-max-attribute': null, - 'selector-max-class': null, - 'selector-max-combinators': null, - 'selector-max-compound-selectors': null, - 'selector-max-id': null, - 'selector-max-pseudo-class': null, - 'selector-max-specificity': null, - 'selector-max-type': null, - 'selector-max-universal': null, - 'selector-nested-pattern': null, - 'selector-no-qualifying-type': null, 'selector-no-vendor-prefix': true, - 'selector-not-notation': null, - 'selector-pseudo-class-allowed-list': null, - 'selector-pseudo-class-disallowed-list': null, - 'selector-pseudo-class-no-unknown': true, - 'selector-pseudo-element-allowed-list': null, 'selector-pseudo-element-colon-notation': 'double', - 'selector-pseudo-element-disallowed-list': null, - 'selector-pseudo-element-no-unknown': true, 'selector-type-case': 'lower', 'selector-type-no-unknown': [true, {ignore: ['custom-elements']}], 'shorthand-property-no-redundant-values': true, - 'string-no-newline': true, - 'time-min-milliseconds': null, - 'unit-allowed-list': null, - 'unit-disallowed-list': null, - 'unit-no-unknown': true, - 'value-keyword-case': null, 'value-no-vendor-prefix': [true, {ignoreValues: ['box', 'inline-box']}], }, -}; +}); From a9577e0808d8432f58a24901eb87ffc88bdc4182 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 28 Jan 2025 10:59:15 +0800 Subject: [PATCH 024/655] Fix `GetCommitBranchStart` bug (#33298) Fix #33265 Fix #33370 This PR also fixes some bugs in `TestGitGeneral`. --- modules/git/commit_test.go | 2 +- modules/git/repo_commit.go | 8 ++-- tests/integration/git_general_test.go | 69 +++++++++++++++++---------- 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/modules/git/commit_test.go b/modules/git/commit_test.go index 9560c2cd94..9a87dd32d9 100644 --- a/modules/git/commit_test.go +++ b/modules/git/commit_test.go @@ -357,5 +357,5 @@ func Test_GetCommitBranchStart(t *testing.T) { startCommitID, err := repo.GetCommitBranchStart(os.Environ(), "branch1", commit.ID.String()) assert.NoError(t, err) assert.NotEmpty(t, startCommitID) - assert.EqualValues(t, "9c9aef8dd84e02bc7ec12641deb4c930a7c30185", startCommitID) + assert.EqualValues(t, "95bb4d39648ee7e325106df01a621c530863a653", startCommitID) } diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index 647894bb21..02d8e163e4 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -519,6 +519,7 @@ func (repo *Repository) AddLastCommitCache(cacheKey, fullName, sha string) error return nil } +// GetCommitBranchStart returns the commit where the branch diverged func (repo *Repository) GetCommitBranchStart(env []string, branch, endCommitID string) (string, error) { cmd := NewCommand(repo.Ctx, "log", prettyLogFormat) cmd.AddDynamicArguments(endCommitID) @@ -533,7 +534,8 @@ func (repo *Repository) GetCommitBranchStart(env []string, branch, endCommitID s parts := bytes.Split(bytes.TrimSpace(stdout), []byte{'\n'}) - var startCommitID string + // check the commits one by one until we find a commit contained by another branch + // and we think this commit is the divergence point for _, commitID := range parts { branches, err := repo.getBranches(env, string(commitID), 2) if err != nil { @@ -541,11 +543,9 @@ func (repo *Repository) GetCommitBranchStart(env []string, branch, endCommitID s } for _, b := range branches { if b != branch { - return startCommitID, nil + return string(commitID), nil } } - - startCommitID = string(commitID) } return "", nil diff --git a/tests/integration/git_general_test.go b/tests/integration/git_general_test.go index 6dd29a438a..ab2a948fde 100644 --- a/tests/integration/git_general_test.go +++ b/tests/integration/git_general_test.go @@ -80,6 +80,7 @@ func testGitGeneral(t *testing.T, u *url.URL) { mediaTest(t, &httpContext, pushedFilesStandard[0], pushedFilesStandard[1], pushedFilesLFS[0], pushedFilesLFS[1]) t.Run("CreateAgitFlowPull", doCreateAgitFlowPull(dstPath, &httpContext, "test/head")) + t.Run("CreateProtectedBranch", doCreateProtectedBranch(&httpContext, dstPath)) t.Run("BranchProtectMerge", doBranchProtectPRMerge(&httpContext, dstPath)) t.Run("AutoMerge", doAutoPRMerge(&httpContext, dstPath)) t.Run("CreatePRAndSetManuallyMerged", doCreatePRAndSetManuallyMerged(httpContext, httpContext, dstPath, "master", "test-manually-merge")) @@ -121,6 +122,7 @@ func testGitGeneral(t *testing.T, u *url.URL) { mediaTest(t, &sshContext, pushedFilesStandard[0], pushedFilesStandard[1], pushedFilesLFS[0], pushedFilesLFS[1]) t.Run("CreateAgitFlowPull", doCreateAgitFlowPull(dstPath, &sshContext, "test/head2")) + t.Run("CreateProtectedBranch", doCreateProtectedBranch(&sshContext, dstPath)) t.Run("BranchProtectMerge", doBranchProtectPRMerge(&sshContext, dstPath)) t.Run("MergeFork", func(t *testing.T) { defer tests.PrintCurrentTest(t)() @@ -325,6 +327,34 @@ func generateCommitWithNewData(size int, repoPath, email, fullName, prefix strin return filepath.Base(tmpFile.Name()), err } +func doCreateProtectedBranch(baseCtx *APITestContext, dstPath string) func(t *testing.T) { + return func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeWriteRepository) + + t.Run("ProtectBranchWithFilePatterns", doProtectBranch(ctx, "release-*", baseCtx.Username, "", "", "config*")) + + // push a new branch without any new commits + t.Run("CreateProtectedBranch-NoChanges", doGitCreateBranch(dstPath, "release-v1.0")) + t.Run("PushProtectedBranch-NoChanges", doGitPushTestRepository(dstPath, "origin", "release-v1.0")) + t.Run("CheckoutMaster-NoChanges", doGitCheckoutBranch(dstPath, "master")) + + // push a new branch with a new unprotected file + t.Run("CreateProtectedBranch-UnprotectedFile", doGitCreateBranch(dstPath, "release-v2.0")) + _, err := generateCommitWithNewData(testFileSizeSmall, dstPath, "user2@example.com", "User Two", "abc.txt") + assert.NoError(t, err) + t.Run("PushProtectedBranch-UnprotectedFile", doGitPushTestRepository(dstPath, "origin", "release-v2.0")) + t.Run("CheckoutMaster-UnprotectedFile", doGitCheckoutBranch(dstPath, "master")) + + // push a new branch with a new protected file + t.Run("CreateProtectedBranch-ProtectedFile", doGitCreateBranch(dstPath, "release-v3.0")) + _, err = generateCommitWithNewData(testFileSizeSmall, dstPath, "user2@example.com", "User Two", "config") + assert.NoError(t, err) + t.Run("PushProtectedBranch-ProtectedFile", doGitPushTestRepositoryFail(dstPath, "origin", "release-v3.0")) + t.Run("CheckoutMaster-ProtectedFile", doGitCheckoutBranch(dstPath, "master")) + } +} + func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) { return func(t *testing.T) { defer tests.PrintCurrentTest(t)() @@ -334,27 +364,23 @@ func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *tes ctx := NewAPITestContext(t, baseCtx.Username, baseCtx.Reponame, auth_model.AccessTokenScopeWriteRepository) // Protect branch without any whitelisting - t.Run("ProtectBranchNoWhitelist", func(t *testing.T) { - doProtectBranch(ctx, "protected", "", "", "") - }) + t.Run("ProtectBranchNoWhitelist", doProtectBranch(ctx, "protected", "", "", "", "")) // Try to push without permissions, which should fail t.Run("TryPushWithoutPermissions", func(t *testing.T) { _, err := generateCommitWithNewData(testFileSizeSmall, dstPath, "user2@example.com", "User Two", "branch-data-file-") assert.NoError(t, err) - doGitPushTestRepositoryFail(dstPath, "origin", "protected") + doGitPushTestRepositoryFail(dstPath, "origin", "protected")(t) }) // Set up permissions for normal push but not force push - t.Run("SetupNormalPushPermissions", func(t *testing.T) { - doProtectBranch(ctx, "protected", baseCtx.Username, "", "") - }) + t.Run("SetupNormalPushPermissions", doProtectBranch(ctx, "protected", baseCtx.Username, "", "", "")) // Normal push should work t.Run("NormalPushWithPermissions", func(t *testing.T) { _, err := generateCommitWithNewData(testFileSizeSmall, dstPath, "user2@example.com", "User Two", "branch-data-file-") assert.NoError(t, err) - doGitPushTestRepository(dstPath, "origin", "protected") + doGitPushTestRepository(dstPath, "origin", "protected")(t) }) // Try to force push without force push permissions, which should fail @@ -364,30 +390,22 @@ func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *tes _, err := generateCommitWithNewData(testFileSizeSmall, dstPath, "user2@example.com", "User Two", "branch-data-file-new") assert.NoError(t, err) }) - doGitPushTestRepositoryFail(dstPath, "-f", "origin", "protected") + doGitPushTestRepositoryFail(dstPath, "-f", "origin", "protected")(t) }) // Set up permissions for force push but not normal push - t.Run("SetupForcePushPermissions", func(t *testing.T) { - doProtectBranch(ctx, "protected", "", baseCtx.Username, "") - }) + t.Run("SetupForcePushPermissions", doProtectBranch(ctx, "protected", "", baseCtx.Username, "", "")) // Try to force push without normal push permissions, which should fail - t.Run("ForcePushWithoutNormalPermissions", func(t *testing.T) { - doGitPushTestRepositoryFail(dstPath, "-f", "origin", "protected") - }) + t.Run("ForcePushWithoutNormalPermissions", doGitPushTestRepositoryFail(dstPath, "-f", "origin", "protected")) // Set up permissions for normal and force push (both are required to force push) - t.Run("SetupNormalAndForcePushPermissions", func(t *testing.T) { - doProtectBranch(ctx, "protected", baseCtx.Username, baseCtx.Username, "") - }) + t.Run("SetupNormalAndForcePushPermissions", doProtectBranch(ctx, "protected", baseCtx.Username, baseCtx.Username, "", "")) // Force push should now work - t.Run("ForcePushWithPermissions", func(t *testing.T) { - doGitPushTestRepository(dstPath, "-f", "origin", "protected") - }) + t.Run("ForcePushWithPermissions", doGitPushTestRepository(dstPath, "-f", "origin", "protected")) - t.Run("ProtectProtectedBranchNoWhitelist", doProtectBranch(ctx, "protected", "", "", "")) + t.Run("ProtectProtectedBranchNoWhitelist", doProtectBranch(ctx, "protected", "", "", "", "")) t.Run("PushToUnprotectedBranch", doGitPushTestRepository(dstPath, "origin", "protected:unprotected")) var pr api.PullRequest var err error @@ -409,14 +427,14 @@ func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *tes t.Run("MergePR", doAPIMergePullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)) t.Run("PullProtected", doGitPull(dstPath, "origin", "protected")) - t.Run("ProtectProtectedBranchUnprotectedFilePaths", doProtectBranch(ctx, "protected", "", "", "unprotected-file-*")) + t.Run("ProtectProtectedBranchUnprotectedFilePaths", doProtectBranch(ctx, "protected", "", "", "unprotected-file-*", "")) t.Run("GenerateCommit", func(t *testing.T) { _, err := generateCommitWithNewData(testFileSizeSmall, dstPath, "user2@example.com", "User Two", "unprotected-file-") assert.NoError(t, err) }) t.Run("PushUnprotectedFilesToProtectedBranch", doGitPushTestRepository(dstPath, "origin", "protected")) - t.Run("ProtectProtectedBranchWhitelist", doProtectBranch(ctx, "protected", baseCtx.Username, "", "")) + t.Run("ProtectProtectedBranchWhitelist", doProtectBranch(ctx, "protected", baseCtx.Username, "", "", "")) t.Run("CheckoutMaster", doGitCheckoutBranch(dstPath, "master")) t.Run("CreateBranchForced", doGitCreateBranch(dstPath, "toforce")) @@ -431,7 +449,7 @@ func doBranchProtectPRMerge(baseCtx *APITestContext, dstPath string) func(t *tes } } -func doProtectBranch(ctx APITestContext, branch, userToWhitelistPush, userToWhitelistForcePush, unprotectedFilePatterns string) func(t *testing.T) { +func doProtectBranch(ctx APITestContext, branch, userToWhitelistPush, userToWhitelistForcePush, unprotectedFilePatterns, protectedFilePatterns string) func(t *testing.T) { // We are going to just use the owner to set the protection. return func(t *testing.T) { csrf := GetUserCSRFToken(t, ctx.Session) @@ -440,6 +458,7 @@ func doProtectBranch(ctx APITestContext, branch, userToWhitelistPush, userToWhit "_csrf": csrf, "rule_name": branch, "unprotected_file_patterns": unprotectedFilePatterns, + "protected_file_patterns": protectedFilePatterns, } if userToWhitelistPush != "" { From 8c4f0f02ef7ab094cbd71c062e60ebaf71f65a24 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 29 Jan 2025 07:14:35 +0800 Subject: [PATCH 025/655] Refactor user package (#33423) and avoid global variables --- models/issues/reaction.go | 8 ++++- models/user/email_address.go | 5 +-- models/user/openid.go | 5 +-- models/user/user.go | 59 ++++++++++++++++++++++-------------- models/user/user_system.go | 31 ++++++++----------- routers/web/user/avatar.go | 3 +- 6 files changed, 59 insertions(+), 52 deletions(-) diff --git a/models/issues/reaction.go b/models/issues/reaction.go index 11b3c6be20..f24001fd23 100644 --- a/models/issues/reaction.go +++ b/models/issues/reaction.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "fmt" + "strings" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" @@ -321,6 +322,11 @@ func valuesUser(m map[int64]*user_model.User) []*user_model.User { return values } +// newMigrationOriginalUser creates and returns a fake user for external user +func newMigrationOriginalUser(name string) *user_model.User { + return &user_model.User{ID: 0, Name: name, LowerName: strings.ToLower(name)} +} + // LoadUsers loads reactions' all users func (list ReactionList) LoadUsers(ctx context.Context, repo *repo_model.Repository) ([]*user_model.User, error) { if len(list) == 0 { @@ -338,7 +344,7 @@ func (list ReactionList) LoadUsers(ctx context.Context, repo *repo_model.Reposit for _, reaction := range list { if reaction.OriginalAuthor != "" { - reaction.User = user_model.NewReplaceUser(fmt.Sprintf("%s(%s)", reaction.OriginalAuthor, repo.OriginalServiceType.Name())) + reaction.User = newMigrationOriginalUser(fmt.Sprintf("%s(%s)", reaction.OriginalAuthor, repo.OriginalServiceType.Name())) } else if user, ok := userMaps[reaction.UserID]; ok { reaction.User = user } else { diff --git a/models/user/email_address.go b/models/user/email_address.go index 74ba5f617a..7c9c6140ac 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -8,7 +8,6 @@ import ( "context" "fmt" "net/mail" - "regexp" "strings" "time" @@ -153,8 +152,6 @@ func UpdateEmailAddress(ctx context.Context, email *EmailAddress) error { return err } -var emailRegexp = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") - // ValidateEmail check if email is a valid & allowed address func ValidateEmail(email string) error { if err := validateEmailBasic(email); err != nil { @@ -514,7 +511,7 @@ func validateEmailBasic(email string) error { return ErrEmailInvalid{email} } - if !emailRegexp.MatchString(email) { + if !globalVars().emailRegexp.MatchString(email) { return ErrEmailCharIsNotSupported{email} } diff --git a/models/user/openid.go b/models/user/openid.go index ee4ecabae0..420c67ca18 100644 --- a/models/user/openid.go +++ b/models/user/openid.go @@ -11,9 +11,6 @@ import ( "code.gitea.io/gitea/modules/util" ) -// ErrOpenIDNotExist openid is not known -var ErrOpenIDNotExist = util.NewNotExistErrorf("OpenID is unknown") - // UserOpenID is the list of all OpenID identities of a user. // Since this is a middle table, name it OpenID is not suitable, so we ignore the lint here type UserOpenID struct { //revive:disable-line:exported @@ -99,7 +96,7 @@ func DeleteUserOpenID(ctx context.Context, openid *UserOpenID) (err error) { if err != nil { return err } else if deleted != 1 { - return ErrOpenIDNotExist + return util.NewNotExistErrorf("OpenID is unknown") } return nil } diff --git a/models/user/user.go b/models/user/user.go index f790392a9b..e93ad41ade 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -14,6 +14,7 @@ import ( "path/filepath" "regexp" "strings" + "sync" "time" "unicode" @@ -417,19 +418,9 @@ func (u *User) DisplayName() string { return u.Name } -var emailToReplacer = strings.NewReplacer( - "\n", "", - "\r", "", - "<", "", - ">", "", - ",", "", - ":", "", - ";", "", -) - // EmailTo returns a string suitable to be put into a e-mail `To:` header. func (u *User) EmailTo() string { - sanitizedDisplayName := emailToReplacer.Replace(u.DisplayName()) + sanitizedDisplayName := globalVars().emailToReplacer.Replace(u.DisplayName()) // should be an edge case but nice to have if sanitizedDisplayName == u.Email { @@ -526,28 +517,52 @@ func GetUserSalt() (string, error) { if err != nil { return "", err } - // Returns a 32 bytes long string. + // Returns a 32-byte long string. return hex.EncodeToString(rBytes), nil } -// Note: The set of characters here can safely expand without a breaking change, -// but characters removed from this set can cause user account linking to break -var ( - customCharsReplacement = strings.NewReplacer("Æ", "AE") - removeCharsRE = regexp.MustCompile("['`´]") - transformDiacritics = transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC) - replaceCharsHyphenRE = regexp.MustCompile(`[\s~+]`) -) +type globalVarsStruct struct { + customCharsReplacement *strings.Replacer + removeCharsRE *regexp.Regexp + transformDiacritics transform.Transformer + replaceCharsHyphenRE *regexp.Regexp + emailToReplacer *strings.Replacer + emailRegexp *regexp.Regexp +} + +var globalVars = sync.OnceValue(func() *globalVarsStruct { + return &globalVarsStruct{ + // Note: The set of characters here can safely expand without a breaking change, + // but characters removed from this set can cause user account linking to break + customCharsReplacement: strings.NewReplacer("Æ", "AE"), + + removeCharsRE: regexp.MustCompile("['`´]"), + transformDiacritics: transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC), + replaceCharsHyphenRE: regexp.MustCompile(`[\s~+]`), + + emailToReplacer: strings.NewReplacer( + "\n", "", + "\r", "", + "<", "", + ">", "", + ",", "", + ":", "", + ";", "", + ), + emailRegexp: regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"), + } +}) // NormalizeUserName only takes the name part if it is an email address, transforms it diacritics to ASCII characters. // It returns a string with the single-quotes removed, and any other non-supported username characters are replaced with a `-` character func NormalizeUserName(s string) (string, error) { + vars := globalVars() s, _, _ = strings.Cut(s, "@") - strDiacriticsRemoved, n, err := transform.String(transformDiacritics, customCharsReplacement.Replace(s)) + strDiacriticsRemoved, n, err := transform.String(vars.transformDiacritics, vars.customCharsReplacement.Replace(s)) if err != nil { return "", fmt.Errorf("failed to normalize the string of provided username %q at position %d", s, n) } - return replaceCharsHyphenRE.ReplaceAllLiteralString(removeCharsRE.ReplaceAllLiteralString(strDiacriticsRemoved, ""), "-"), nil + return vars.replaceCharsHyphenRE.ReplaceAllLiteralString(vars.removeCharsRE.ReplaceAllLiteralString(strDiacriticsRemoved, ""), "-"), nil } var ( diff --git a/models/user/user_system.go b/models/user/user_system.go index 612cdb2cae..6e7638377e 100644 --- a/models/user/user_system.go +++ b/models/user/user_system.go @@ -10,9 +10,8 @@ import ( ) const ( - GhostUserID = -1 - GhostUserName = "Ghost" - GhostUserLowerName = "ghost" + GhostUserID = -1 + GhostUserName = "Ghost" ) // NewGhostUser creates and returns a fake user for someone has deleted their account. @@ -20,10 +19,14 @@ func NewGhostUser() *User { return &User{ ID: GhostUserID, Name: GhostUserName, - LowerName: GhostUserLowerName, + LowerName: strings.ToLower(GhostUserName), } } +func IsGhostUserName(name string) bool { + return strings.EqualFold(name, GhostUserName) +} + // IsGhost check if user is fake user for a deleted account func (u *User) IsGhost() bool { if u == nil { @@ -32,20 +35,10 @@ func (u *User) IsGhost() bool { return u.ID == GhostUserID && u.Name == GhostUserName } -// NewReplaceUser creates and returns a fake user for external user -func NewReplaceUser(name string) *User { - return &User{ - ID: 0, - Name: name, - LowerName: strings.ToLower(name), - } -} - const ( - ActionsUserID = -2 - ActionsUserName = "gitea-actions" - ActionsFullName = "Gitea Actions" - ActionsEmail = "teabot@gitea.io" + ActionsUserID = -2 + ActionsUserName = "gitea-actions" + ActionsUserEmail = "teabot@gitea.io" ) // NewActionsUser creates and returns a fake user for running the actions. @@ -55,8 +48,8 @@ func NewActionsUser() *User { Name: ActionsUserName, LowerName: ActionsUserName, IsActive: true, - FullName: ActionsFullName, - Email: ActionsEmail, + FullName: "Gitea Actions", + Email: ActionsUserEmail, KeepEmailPrivate: true, LoginName: ActionsUserName, Type: UserTypeIndividual, diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go index f77bd602b3..f70b280377 100644 --- a/routers/web/user/avatar.go +++ b/routers/web/user/avatar.go @@ -4,7 +4,6 @@ package user import ( - "strings" "time" "code.gitea.io/gitea/models/avatars" @@ -27,7 +26,7 @@ func AvatarByUserName(ctx *context.Context) { size := int(ctx.PathParamInt64("size")) var user *user_model.User - if strings.ToLower(userName) != user_model.GhostUserLowerName { + if !user_model.IsGhostUserName(userName) { var err error if user, err = user_model.GetUserByName(ctx, userName); err != nil { if user_model.IsErrUserNotExist(err) { From a89c73530327784ce99e1e07c269ea8ff1861fdc Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 29 Jan 2025 00:31:19 +0000 Subject: [PATCH 026/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_fr-FR.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index ced3ed7bd1..a5558eebb0 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -1499,7 +1499,7 @@ issues.remove_labels=a supprimé les labels %s %s. issues.add_remove_labels=a ajouté le label %s et supprimé %s %s. issues.add_milestone_at=`a ajouté ça au jalon %s %s.` issues.add_project_at=`a ajouté ça au projet %s %s.` -issues.move_to_column_of_project=`a déplacé ça vers %s dans %s sur %s` +issues.move_to_column_of_project=`a déplacé ça vers %s dans %s %s.` issues.change_milestone_at=`a remplacé le jalon %s par %s %s.` issues.change_project_at=`a remplacé le projet %s par %s %s.` issues.remove_milestone_at=`a supprimé ça du jalon %s %s.` From 4ffc54f59a7723eb5aef21955129bdd329ee1d4f Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 30 Jan 2025 07:33:50 +0800 Subject: [PATCH 027/655] Refactor user & avatar (#33433) 1. better GetPossibleUserByID logic 2. fix some function name & comment typos 3. do not re-generate avatar if one exists --- models/user/avatar.go | 21 +++++++----- models/user/avatar_test.go | 40 ++++++++++++++++++++++ models/user/user.go | 51 +++++++++++++---------------- models/user/user_system.go | 16 ++++++++- models/user/user_system_test.go | 32 ++++++++++++++++++ models/user/user_test.go | 4 +-- modules/storage/storage.go | 4 +-- routers/web/user/avatar.go | 25 +++++--------- routers/web/user/home.go | 2 +- routers/web/web.go | 2 +- services/actions/notifier_helper.go | 2 +- services/mailer/mail_issue.go | 2 +- services/mailer/mail_release.go | 4 +-- 13 files changed, 139 insertions(+), 66 deletions(-) create mode 100644 models/user/user_system_test.go diff --git a/models/user/avatar.go b/models/user/avatar.go index 5453c78fc6..2a41b99129 100644 --- a/models/user/avatar.go +++ b/models/user/avatar.go @@ -38,27 +38,30 @@ func GenerateRandomAvatar(ctx context.Context, u *User) error { u.Avatar = avatars.HashEmail(seed) - // Don't share the images so that we can delete them easily - if err := storage.SaveFrom(storage.Avatars, u.CustomAvatarRelativePath(), func(w io.Writer) error { - if err := png.Encode(w, img); err != nil { - log.Error("Encode: %v", err) + _, err = storage.Avatars.Stat(u.CustomAvatarRelativePath()) + if err != nil { + // If unable to Stat the avatar file (usually it means non-existing), then try to save a new one + // Don't share the images so that we can delete them easily + if err := storage.SaveFrom(storage.Avatars, u.CustomAvatarRelativePath(), func(w io.Writer) error { + if err := png.Encode(w, img); err != nil { + log.Error("Encode: %v", err) + } + return nil + }); err != nil { + return fmt.Errorf("failed to save avatar %s: %w", u.CustomAvatarRelativePath(), err) } - return err - }); err != nil { - return fmt.Errorf("Failed to create dir %s: %w", u.CustomAvatarRelativePath(), err) } if _, err := db.GetEngine(ctx).ID(u.ID).Cols("avatar").Update(u); err != nil { return err } - log.Info("New random avatar created: %d", u.ID) return nil } // AvatarLinkWithSize returns a link to the user's avatar with size. size <= 0 means default size func (u *User) AvatarLinkWithSize(ctx context.Context, size int) string { - if u.IsGhost() { + if u.IsGhost() || u.IsGiteaActions() { return avatars.DefaultAvatarLink() } diff --git a/models/user/avatar_test.go b/models/user/avatar_test.go index 1078875ee1..a1cc01316f 100644 --- a/models/user/avatar_test.go +++ b/models/user/avatar_test.go @@ -4,13 +4,19 @@ package user import ( + "context" + "io" + "strings" "testing" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/test" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestUserAvatarLink(t *testing.T) { @@ -26,3 +32,37 @@ func TestUserAvatarLink(t *testing.T) { link = u.AvatarLink(db.DefaultContext) assert.Equal(t, "https://localhost/sub-path/avatars/avatar.png", link) } + +func TestUserAvatarGenerate(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + var err error + tmpDir := t.TempDir() + storage.Avatars, err = storage.NewLocalStorage(context.Background(), &setting.Storage{Path: tmpDir}) + require.NoError(t, err) + + u := unittest.AssertExistsAndLoadBean(t, &User{ID: 2}) + + // there was no avatar, generate a new one + assert.Empty(t, u.Avatar) + err = GenerateRandomAvatar(db.DefaultContext, u) + require.NoError(t, err) + assert.NotEmpty(t, u.Avatar) + + // make sure the generated one exists + oldAvatarPath := u.CustomAvatarRelativePath() + _, err = storage.Avatars.Stat(u.CustomAvatarRelativePath()) + require.NoError(t, err) + // and try to change its content + _, err = storage.Avatars.Save(u.CustomAvatarRelativePath(), strings.NewReader("abcd"), 4) + require.NoError(t, err) + + // try to generate again + err = GenerateRandomAvatar(db.DefaultContext, u) + require.NoError(t, err) + assert.Equal(t, oldAvatarPath, u.CustomAvatarRelativePath()) + f, err := storage.Avatars.Open(u.CustomAvatarRelativePath()) + require.NoError(t, err) + defer f.Close() + content, _ := io.ReadAll(f) + assert.Equal(t, "abcd", string(content)) +} diff --git a/models/user/user.go b/models/user/user.go index e93ad41ade..75ed7ece8b 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -528,6 +528,7 @@ type globalVarsStruct struct { replaceCharsHyphenRE *regexp.Regexp emailToReplacer *strings.Replacer emailRegexp *regexp.Regexp + systemUserNewFuncs map[int64]func() *User } var globalVars = sync.OnceValue(func() *globalVarsStruct { @@ -550,6 +551,11 @@ var globalVars = sync.OnceValue(func() *globalVarsStruct { ";", "", ), emailRegexp: regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"), + + systemUserNewFuncs: map[int64]func() *User{ + GhostUserID: NewGhostUser, + ActionsUserID: NewActionsUser, + }, } }) @@ -978,30 +984,28 @@ func GetUserByIDs(ctx context.Context, ids []int64) ([]*User, error) { return users, err } -// GetPossibleUserByID returns the user if id > 0 or return system usrs if id < 0 +// GetPossibleUserByID returns the user if id > 0 or returns system user if id < 0 func GetPossibleUserByID(ctx context.Context, id int64) (*User, error) { - switch id { - case GhostUserID: - return NewGhostUser(), nil - case ActionsUserID: - return NewActionsUser(), nil - case 0: + if id < 0 { + if newFunc, ok := globalVars().systemUserNewFuncs[id]; ok { + return newFunc(), nil + } + return nil, ErrUserNotExist{UID: id} + } else if id == 0 { return nil, ErrUserNotExist{} - default: - return GetUserByID(ctx, id) } + return GetUserByID(ctx, id) } -// GetPossibleUserByIDs returns the users if id > 0 or return system users if id < 0 +// GetPossibleUserByIDs returns the users if id > 0 or returns system users if id < 0 func GetPossibleUserByIDs(ctx context.Context, ids []int64) ([]*User, error) { uniqueIDs := container.SetOf(ids...) users := make([]*User, 0, len(ids)) _ = uniqueIDs.Remove(0) - if uniqueIDs.Remove(GhostUserID) { - users = append(users, NewGhostUser()) - } - if uniqueIDs.Remove(ActionsUserID) { - users = append(users, NewActionsUser()) + for systemUID, newFunc := range globalVars().systemUserNewFuncs { + if uniqueIDs.Remove(systemUID) { + users = append(users, newFunc()) + } } res, err := GetUserByIDs(ctx, uniqueIDs.Values()) if err != nil { @@ -1011,7 +1015,7 @@ func GetPossibleUserByIDs(ctx context.Context, ids []int64) ([]*User, error) { return users, nil } -// GetUserByNameCtx returns user by given name. +// GetUserByName returns user by given name. func GetUserByName(ctx context.Context, name string) (*User, error) { if len(name) == 0 { return nil, ErrUserNotExist{Name: name} @@ -1042,8 +1046,8 @@ func GetUserEmailsByNames(ctx context.Context, names []string) []string { return mails } -// GetMaileableUsersByIDs gets users from ids, but only if they can receive mails -func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([]*User, error) { +// GetMailableUsersByIDs gets users from ids, but only if they can receive mails +func GetMailableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([]*User, error) { if len(ids) == 0 { return nil, nil } @@ -1068,17 +1072,6 @@ func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([ Find(&ous) } -// GetUserNamesByIDs returns usernames for all resolved users from a list of Ids. -func GetUserNamesByIDs(ctx context.Context, ids []int64) ([]string, error) { - unames := make([]string, 0, len(ids)) - err := db.GetEngine(ctx).In("id", ids). - Table("user"). - Asc("name"). - Cols("name"). - Find(&unames) - return unames, err -} - // GetUserNameByID returns username for the id func GetUserNameByID(ctx context.Context, id int64) (string, error) { var name string diff --git a/models/user/user_system.go b/models/user/user_system.go index 6e7638377e..e54973dc8e 100644 --- a/models/user/user_system.go +++ b/models/user/user_system.go @@ -41,6 +41,10 @@ const ( ActionsUserEmail = "teabot@gitea.io" ) +func IsGiteaActionsUserName(name string) bool { + return strings.EqualFold(name, ActionsUserName) +} + // NewActionsUser creates and returns a fake user for running the actions. func NewActionsUser() *User { return &User{ @@ -58,6 +62,16 @@ func NewActionsUser() *User { } } -func (u *User) IsActions() bool { +func (u *User) IsGiteaActions() bool { return u != nil && u.ID == ActionsUserID } + +func GetSystemUserByName(name string) *User { + if IsGhostUserName(name) { + return NewGhostUser() + } + if IsGiteaActionsUserName(name) { + return NewActionsUser() + } + return nil +} diff --git a/models/user/user_system_test.go b/models/user/user_system_test.go new file mode 100644 index 0000000000..97768b509b --- /dev/null +++ b/models/user/user_system_test.go @@ -0,0 +1,32 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package user + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSystemUser(t *testing.T) { + u, err := GetPossibleUserByID(db.DefaultContext, -1) + require.NoError(t, err) + assert.Equal(t, "Ghost", u.Name) + assert.Equal(t, "ghost", u.LowerName) + assert.True(t, u.IsGhost()) + assert.True(t, IsGhostUserName("gHost")) + + u, err = GetPossibleUserByID(db.DefaultContext, -2) + require.NoError(t, err) + assert.Equal(t, "gitea-actions", u.Name) + assert.Equal(t, "gitea-actions", u.LowerName) + assert.True(t, u.IsGiteaActions()) + assert.True(t, IsGiteaActionsUserName("Gitea-actionS")) + + _, err = GetPossibleUserByID(db.DefaultContext, -3) + require.Error(t, err) +} diff --git a/models/user/user_test.go b/models/user/user_test.go index cad1a64d6e..51098417e6 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -333,14 +333,14 @@ func TestGetUserIDsByNames(t *testing.T) { func TestGetMaileableUsersByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - results, err := user_model.GetMaileableUsersByIDs(db.DefaultContext, []int64{1, 4}, false) + results, err := user_model.GetMailableUsersByIDs(db.DefaultContext, []int64{1, 4}, false) assert.NoError(t, err) assert.Len(t, results, 1) if len(results) > 1 { assert.Equal(t, 1, results[0].ID) } - results, err = user_model.GetMaileableUsersByIDs(db.DefaultContext, []int64{1, 4}, true) + results, err = user_model.GetMailableUsersByIDs(db.DefaultContext, []int64{1, 4}, true) assert.NoError(t, err) assert.Len(t, results, 2) if len(results) > 2 { diff --git a/modules/storage/storage.go b/modules/storage/storage.go index 750ecdfe0d..b0529941e7 100644 --- a/modules/storage/storage.go +++ b/modules/storage/storage.go @@ -93,7 +93,7 @@ func Clean(storage ObjectStorage) error { } // SaveFrom saves data to the ObjectStorage with path p from the callback -func SaveFrom(objStorage ObjectStorage, p string, callback func(w io.Writer) error) error { +func SaveFrom(objStorage ObjectStorage, path string, callback func(w io.Writer) error) error { pr, pw := io.Pipe() defer pr.Close() go func() { @@ -103,7 +103,7 @@ func SaveFrom(objStorage ObjectStorage, p string, callback func(w io.Writer) err } }() - _, err := objStorage.Save(p, pr, -1) + _, err := objStorage.Save(path, pr, -1) return err } diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go index f70b280377..81c00b3bd4 100644 --- a/routers/web/user/avatar.go +++ b/routers/web/user/avatar.go @@ -20,27 +20,18 @@ func cacheableRedirect(ctx *context.Context, location string) { ctx.Redirect(location) } -// AvatarByUserName redirect browser to user avatar of requested size -func AvatarByUserName(ctx *context.Context) { - userName := ctx.PathParam("username") - size := int(ctx.PathParamInt64("size")) - - var user *user_model.User - if !user_model.IsGhostUserName(userName) { +// AvatarByUsernameSize redirect browser to user avatar of requested size +func AvatarByUsernameSize(ctx *context.Context) { + username := ctx.PathParam("username") + user := user_model.GetSystemUserByName(username) + if user == nil { var err error - if user, err = user_model.GetUserByName(ctx, userName); err != nil { - if user_model.IsErrUserNotExist(err) { - ctx.NotFound("GetUserByName", err) - return - } - ctx.ServerError("Invalid user: "+userName, err) + if user, err = user_model.GetUserByName(ctx, username); err != nil { + ctx.NotFoundOrServerError("GetUserByName", user_model.IsErrUserNotExist, err) return } - } else { - user = user_model.NewGhostUser() } - - cacheableRedirect(ctx, user.AvatarLinkWithSize(ctx, size)) + cacheableRedirect(ctx, user.AvatarLinkWithSize(ctx, int(ctx.PathParamInt64("size")))) } // AvatarByEmailHash redirects the browser to the email avatar link diff --git a/routers/web/user/home.go b/routers/web/user/home.go index c4ed242f71..ff9334da6e 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -732,7 +732,7 @@ func UsernameSubRoute(ctx *context.Context) { switch { case strings.HasSuffix(username, ".png"): if reloadParam(".png") { - AvatarByUserName(ctx) + AvatarByUsernameSize(ctx) } case strings.HasSuffix(username, ".keys"): if reloadParam(".keys") { diff --git a/routers/web/web.go b/routers/web/web.go index 5330b0f3c1..fc01d81b50 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -681,7 +681,7 @@ func registerRoutes(m *web.Router) { m.Get("/activate", auth.Activate) m.Post("/activate", auth.ActivatePost) m.Any("/activate_email", auth.ActivateEmail) - m.Get("/avatar/{username}/{size}", user.AvatarByUserName) + m.Get("/avatar/{username}/{size}", user.AvatarByUsernameSize) m.Get("/recover_account", auth.ResetPasswd) m.Post("/recover_account", auth.ResetPasswdPost) m.Get("/forgot_password", auth.ForgotPasswd) diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 323c6a76e4..2d8885dc32 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -117,7 +117,7 @@ func (input *notifyInput) Notify(ctx context.Context) { func notify(ctx context.Context, input *notifyInput) error { shouldDetectSchedules := input.Event == webhook_module.HookEventPush && input.Ref.BranchName() == input.Repo.DefaultBranch - if input.Doer.IsActions() { + if input.Doer.IsGiteaActions() { // avoiding triggering cyclically, for example: // a comment of an issue will trigger the runner to add a new comment as reply, // and the new comment will trigger the runner again. diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go index fab3315be2..e269b1ca1e 100644 --- a/services/mailer/mail_issue.go +++ b/services/mailer/mail_issue.go @@ -109,7 +109,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo } visited.AddMultiple(ids...) - unfilteredUsers, err := user_model.GetMaileableUsersByIDs(ctx, unfiltered, false) + unfilteredUsers, err := user_model.GetMailableUsersByIDs(ctx, unfiltered, false) if err != nil { return err } diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go index 796d63d27a..31316b0053 100644 --- a/services/mailer/mail_release.go +++ b/services/mailer/mail_release.go @@ -35,9 +35,9 @@ func MailNewRelease(ctx context.Context, rel *repo_model.Release) { return } - recipients, err := user_model.GetMaileableUsersByIDs(ctx, watcherIDList, false) + recipients, err := user_model.GetMailableUsersByIDs(ctx, watcherIDList, false) if err != nil { - log.Error("user_model.GetMaileableUsersByIDs: %v", err) + log.Error("user_model.GetMailableUsersByIDs: %v", err) return } From dc7ddaee2aca7c3c1652a5b287c3047612c1c655 Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 30 Jan 2025 00:38:53 +0100 Subject: [PATCH 028/655] Update `@github/text-expander-element` to 2.9.0 (#33435) Update and use their newly exported types. Tested, works. The import path is a bit suboptimal, to be fixed once https://github.com/github/text-expander-element/pull/75 is merged and released. Co-authored-by: Giteabot --- package-lock.json | 8 ++++---- package.json | 2 +- web_src/js/features/comp/TextExpander.ts | 18 +++--------------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7dead1871..8afe2b533f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "@citation-js/plugin-software-formats": "0.6.1", "@github/markdown-toolbar-element": "2.2.3", "@github/relative-time-element": "4.4.5", - "@github/text-expander-element": "2.8.0", + "@github/text-expander-element": "2.9.0", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.14.0", "@silverwind/vue3-calendar-heatmap": "2.0.6", @@ -2850,9 +2850,9 @@ "license": "MIT" }, "node_modules/@github/text-expander-element": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.8.0.tgz", - "integrity": "sha512-kkS2rZ/CG8HGKblpLDQ8vcK/K7l/Jsvzi/N4ovwPAsFSOImcIbJh2MgCv9tzqE3wAm/qXlscvh3Ms4Hh1vtZvw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.9.0.tgz", + "integrity": "sha512-NjoFiQ/3955XyefrkmtUpZvrgDl0MGyncv2QJBrUZ1+oOFOu+UmCR/ybkcuTgNg0O6AGcl8rUEXStUfrRPUCVQ==", "license": "MIT", "dependencies": { "@github/combobox-nav": "^2.0.2", diff --git a/package.json b/package.json index 2ee785da72..997941f0b4 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "@citation-js/plugin-software-formats": "0.6.1", "@github/markdown-toolbar-element": "2.2.3", "@github/relative-time-element": "4.4.5", - "@github/text-expander-element": "2.8.0", + "@github/text-expander-element": "2.9.0", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.14.0", "@silverwind/vue3-calendar-heatmap": "2.0.6", diff --git a/web_src/js/features/comp/TextExpander.ts b/web_src/js/features/comp/TextExpander.ts index 1e6d46f977..87d2b3a7a4 100644 --- a/web_src/js/features/comp/TextExpander.ts +++ b/web_src/js/features/comp/TextExpander.ts @@ -6,21 +6,9 @@ import {createElementFromAttrs, createElementFromHTML} from '../../utils/dom.ts' import {getIssueColor, getIssueIcon} from '../issue.ts'; import {debounce} from 'perfect-debounce'; import type TextExpanderElement from '@github/text-expander-element'; +import type {TextExpanderChangeEvent, TextExpanderResult} from '@github/text-expander-element/dist/text-expander-element.d.ts'; -type TextExpanderProvideResult = { - matched: boolean, - fragment?: HTMLElement, -} - -type TextExpanderChangeEvent = Event & { - detail?: { - key: string, - text: string, - provide: (result: TextExpanderProvideResult | Promise) => void, - } -} - -async function fetchIssueSuggestions(key: string, text: string): Promise { +async function fetchIssueSuggestions(key: string, text: string): Promise { const issuePathInfo = parseIssueHref(window.location.href); if (!issuePathInfo.ownerName) { const repoOwnerPathInfo = parseRepoOwnerPathInfo(window.location.pathname); @@ -59,7 +47,7 @@ export function initTextExpander(expander: TextExpanderElement) { return keyStart > lineStart; }; - const debouncedIssueSuggestions = debounce(async (key: string, text: string): Promise => { + const debouncedIssueSuggestions = debounce(async (key: string, text: string): Promise => { // https://github.com/github/text-expander-element/issues/71 // Upstream bug: when using "multiword+promise", TextExpander will get wrong "key" position. // To reproduce, comment out the "shouldShowIssueSuggestions" check, use the "await sleep" below, From ac2d97cb610d53d512545a6d0195173a5a690919 Mon Sep 17 00:00:00 2001 From: Rowan Bohde Date: Wed, 29 Jan 2025 18:09:52 -0600 Subject: [PATCH 029/655] Link to tree views of submodules if possible (#33424) This is a follow-up to https://github.com/go-gitea/gitea/pull/33097. When linking a submodule at a commit in either the repo view, or a diff when adding a new submodule, link to the tree view of that submodules intead of the individual commit. This shows the user the full tree, instead of the diff of the commit. This makes the assumption that the tree for a given SHA is at `/tree/`. This URL format is supported by both Github & Gitlab, but not Gitea. To fix this, add a redirect from `//tree/` to `//src/`, so that Gitea can support this URL structure. --- modules/git/commit_submodule_file.go | 4 ++-- modules/git/commit_submodule_file_test.go | 4 ++-- routers/web/repo/view_home.go | 6 ++++++ routers/web/web.go | 7 +++++++ services/gitdiff/submodule_test.go | 2 +- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/modules/git/commit_submodule_file.go b/modules/git/commit_submodule_file.go index 2ac744fbf6..729401f752 100644 --- a/modules/git/commit_submodule_file.go +++ b/modules/git/commit_submodule_file.go @@ -46,9 +46,9 @@ func (sf *CommitSubmoduleFile) SubmoduleWebLink(ctx context.Context, optCommitID if len(optCommitID) == 2 { commitLink = sf.repoLink + "/compare/" + optCommitID[0] + "..." + optCommitID[1] } else if len(optCommitID) == 1 { - commitLink = sf.repoLink + "/commit/" + optCommitID[0] + commitLink = sf.repoLink + "/tree/" + optCommitID[0] } else { - commitLink = sf.repoLink + "/commit/" + sf.refID + commitLink = sf.repoLink + "/tree/" + sf.refID } return &SubmoduleWebLink{RepoWebLink: sf.repoLink, CommitWebLink: commitLink} } diff --git a/modules/git/commit_submodule_file_test.go b/modules/git/commit_submodule_file_test.go index 4b5b767612..98342aa9e9 100644 --- a/modules/git/commit_submodule_file_test.go +++ b/modules/git/commit_submodule_file_test.go @@ -15,11 +15,11 @@ func TestCommitSubmoduleLink(t *testing.T) { wl := sf.SubmoduleWebLink(context.Background()) assert.Equal(t, "https://github.com/user/repo", wl.RepoWebLink) - assert.Equal(t, "https://github.com/user/repo/commit/aaaa", wl.CommitWebLink) + assert.Equal(t, "https://github.com/user/repo/tree/aaaa", wl.CommitWebLink) wl = sf.SubmoduleWebLink(context.Background(), "1111") assert.Equal(t, "https://github.com/user/repo", wl.RepoWebLink) - assert.Equal(t, "https://github.com/user/repo/commit/1111", wl.CommitWebLink) + assert.Equal(t, "https://github.com/user/repo/tree/1111", wl.CommitWebLink) wl = sf.SubmoduleWebLink(context.Background(), "1111", "2222") assert.Equal(t, "https://github.com/user/repo", wl.RepoWebLink) diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index 456efb96f6..6c6e007b50 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -412,3 +412,9 @@ func Home(ctx *context.Context) { ctx.HTML(http.StatusOK, tplRepoHome) } + +// HomeRedirect redirects from /tree/* to /src/* in order to maintain a similar URL structure. +func HomeRedirect(ctx *context.Context) { + remainder := ctx.PathParam("*") + ctx.Redirect(ctx.Repo.RepoLink + "/src/" + util.PathEscapeSegments(remainder)) +} diff --git a/routers/web/web.go b/routers/web/web.go index fc01d81b50..096f1e6bbe 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1584,6 +1584,13 @@ func registerRoutes(m *web.Router) { m.Get("/*", context.RepoRefByType(""), repo.Home) // "/*" route is deprecated, and kept for backward compatibility }, repo.SetEditorconfigIfExists) + // Add a /tree/* path to redirect to the /src/* path, which + // will redirect to the canonical URL for that ref. This is + // included so that Gitea's repo URL structure matches what + // other forges provide, allowing clients to construct URLs + // that work across forges. + m.Get("/tree/*", repo.HomeRedirect) + m.Get("/forks", context.RepoRef(), repo.Forks) m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff) m.Post("/lastcommit/*", context.RepoRefByType(git.RefTypeCommit), repo.LastCommit) diff --git a/services/gitdiff/submodule_test.go b/services/gitdiff/submodule_test.go index 89f32c0e0c..f0eab5557c 100644 --- a/services/gitdiff/submodule_test.go +++ b/services/gitdiff/submodule_test.go @@ -230,7 +230,7 @@ func TestSubmoduleInfo(t *testing.T) { assert.EqualValues(t, "name", sdi.SubmoduleRepoLinkHTML(ctx)) sdi.SubmoduleFile = git.NewCommitSubmoduleFile("https://github.com/owner/repo", "1234") - assert.EqualValues(t, `1111`, sdi.CommitRefIDLinkHTML(ctx, "1111")) + assert.EqualValues(t, `1111`, sdi.CommitRefIDLinkHTML(ctx, "1111")) assert.EqualValues(t, `aaaa...bbbb`, sdi.CompareRefIDLinkHTML(ctx)) assert.EqualValues(t, `name`, sdi.SubmoduleRepoLinkHTML(ctx)) } From 256b94e9e923edc806fca38c90507c8c1b93c691 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 30 Jan 2025 09:24:57 +0800 Subject: [PATCH 030/655] Support choose email when creating a commit via web UI (#33432) Initial PR for #24469 --- models/user/email_address.go | 10 ++ models/user/user.go | 2 +- options/locale/locale_en-US.ini | 2 + routers/api/v1/repo/file.go | 32 +++---- routers/api/v1/repo/patch.go | 8 +- routers/web/repo/editor.go | 68 ++++++++----- services/forms/repo_form.go | 1 + services/packages/cargo/index.go | 10 +- services/repository/files/cherry_pick.go | 23 +++-- services/repository/files/file.go | 46 --------- services/repository/files/patch.go | 21 ++-- services/repository/files/temp_repo.go | 69 +++++++++++--- services/repository/files/update.go | 25 +++-- services/repository/files/upload.go | 13 ++- templates/repo/editor/commit_form.tmpl | 10 ++ tests/integration/actions_trigger_test.go | 72 +++++++------- tests/integration/editor_test.go | 106 +++++++++++++++++++++ tests/integration/pull_update_test.go | 16 ++-- tests/integration/repofiles_change_test.go | 4 +- 19 files changed, 356 insertions(+), 182 deletions(-) diff --git a/models/user/email_address.go b/models/user/email_address.go index 7c9c6140ac..2ba6a56450 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -542,3 +542,13 @@ func IsEmailDomainAllowed(email string) bool { return validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, email) } + +func GetActivatedEmailAddresses(ctx context.Context, uid int64) ([]string, error) { + emails := make([]string, 0, 2) + if err := db.GetEngine(ctx).Table("email_address").Select("email"). + Where("uid=? AND is_activated=?", uid, true).Asc("id"). + Find(&emails); err != nil { + return nil, err + } + return emails, nil +} diff --git a/models/user/user.go b/models/user/user.go index 75ed7ece8b..e13fb6ab3c 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -214,7 +214,7 @@ func (u *User) GetPlaceholderEmail() string { return fmt.Sprintf("%s@%s", u.LowerName, setting.Service.NoReplyAddress) } -// GetEmail returns an noreply email, if the user has set to keep his +// GetEmail returns a noreply email, if the user has set to keep his // email address private, otherwise the primary email address. func (u *User) GetEmail() string { if u.KeepEmailPrivate { diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 85d2c71ec7..68b7fa2f9f 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1345,6 +1345,8 @@ editor.new_branch_name_desc = New branch name… editor.cancel = Cancel editor.filename_cannot_be_empty = The filename cannot be empty. editor.filename_is_invalid = The filename is invalid: "%s". +editor.commit_email = Commit email +editor.invalid_commit_email = The email for the commit is invalid. editor.branch_does_not_exist = Branch "%s" does not exist in this repository. editor.branch_already_exists = Branch "%s" already exists in this repository. editor.directory_is_a_file = Directory name "%s" is already used as a filename in this repository. diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 3eefd2ae29..045db7a291 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -489,12 +489,12 @@ func ChangeFiles(ctx *context.APIContext) { OldBranch: apiOpts.BranchName, NewBranch: apiOpts.NewBranchName, Committer: &files_service.IdentityOptions{ - Name: apiOpts.Committer.Name, - Email: apiOpts.Committer.Email, + GitUserName: apiOpts.Committer.Name, + GitUserEmail: apiOpts.Committer.Email, }, Author: &files_service.IdentityOptions{ - Name: apiOpts.Author.Name, - Email: apiOpts.Author.Email, + GitUserName: apiOpts.Author.Name, + GitUserEmail: apiOpts.Author.Email, }, Dates: &files_service.CommitDateOptions{ Author: apiOpts.Dates.Author, @@ -586,12 +586,12 @@ func CreateFile(ctx *context.APIContext) { OldBranch: apiOpts.BranchName, NewBranch: apiOpts.NewBranchName, Committer: &files_service.IdentityOptions{ - Name: apiOpts.Committer.Name, - Email: apiOpts.Committer.Email, + GitUserName: apiOpts.Committer.Name, + GitUserEmail: apiOpts.Committer.Email, }, Author: &files_service.IdentityOptions{ - Name: apiOpts.Author.Name, - Email: apiOpts.Author.Email, + GitUserName: apiOpts.Author.Name, + GitUserEmail: apiOpts.Author.Email, }, Dates: &files_service.CommitDateOptions{ Author: apiOpts.Dates.Author, @@ -689,12 +689,12 @@ func UpdateFile(ctx *context.APIContext) { OldBranch: apiOpts.BranchName, NewBranch: apiOpts.NewBranchName, Committer: &files_service.IdentityOptions{ - Name: apiOpts.Committer.Name, - Email: apiOpts.Committer.Email, + GitUserName: apiOpts.Committer.Name, + GitUserEmail: apiOpts.Committer.Email, }, Author: &files_service.IdentityOptions{ - Name: apiOpts.Author.Name, - Email: apiOpts.Author.Email, + GitUserName: apiOpts.Author.Name, + GitUserEmail: apiOpts.Author.Email, }, Dates: &files_service.CommitDateOptions{ Author: apiOpts.Dates.Author, @@ -848,12 +848,12 @@ func DeleteFile(ctx *context.APIContext) { OldBranch: apiOpts.BranchName, NewBranch: apiOpts.NewBranchName, Committer: &files_service.IdentityOptions{ - Name: apiOpts.Committer.Name, - Email: apiOpts.Committer.Email, + GitUserName: apiOpts.Committer.Name, + GitUserEmail: apiOpts.Committer.Email, }, Author: &files_service.IdentityOptions{ - Name: apiOpts.Author.Name, - Email: apiOpts.Author.Email, + GitUserName: apiOpts.Author.Name, + GitUserEmail: apiOpts.Author.Email, }, Dates: &files_service.CommitDateOptions{ Author: apiOpts.Dates.Author, diff --git a/routers/api/v1/repo/patch.go b/routers/api/v1/repo/patch.go index 5e24dcf891..95d7631da7 100644 --- a/routers/api/v1/repo/patch.go +++ b/routers/api/v1/repo/patch.go @@ -58,12 +58,12 @@ func ApplyDiffPatch(ctx *context.APIContext) { OldBranch: apiOpts.BranchName, NewBranch: apiOpts.NewBranchName, Committer: &files.IdentityOptions{ - Name: apiOpts.Committer.Name, - Email: apiOpts.Committer.Email, + GitUserName: apiOpts.Committer.Name, + GitUserEmail: apiOpts.Committer.Email, }, Author: &files.IdentityOptions{ - Name: apiOpts.Author.Name, - Email: apiOpts.Author.Email, + GitUserName: apiOpts.Author.Name, + GitUserEmail: apiOpts.Author.Email, }, Dates: &files.CommitDateOptions{ Author: apiOpts.Dates.Author, diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 85f407ab8d..48e041fb1d 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -13,6 +13,7 @@ import ( git_model "code.gitea.io/gitea/models/git" 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/charset" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" @@ -102,10 +103,32 @@ func getParentTreeFields(treePath string) (treeNames, treePaths []string) { return treeNames, treePaths } -func editFile(ctx *context.Context, isNewFile bool) { - ctx.Data["PageIsViewCode"] = true +func getCandidateEmailAddresses(ctx *context.Context) []string { + emails, err := user_model.GetActivatedEmailAddresses(ctx, ctx.Doer.ID) + if err != nil { + log.Error("getCandidateEmailAddresses: GetActivatedEmailAddresses: %v", err) + } + + if ctx.Doer.KeepEmailPrivate { + emails = append([]string{ctx.Doer.GetPlaceholderEmail()}, emails...) + } + return emails +} + +func editFileCommon(ctx *context.Context, isNewFile bool) { ctx.Data["PageIsEdit"] = true ctx.Data["IsNewFile"] = isNewFile + ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() + ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",") + ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",") + ctx.Data["IsEditingFileOnly"] = ctx.FormString("return_uri") != "" + ctx.Data["ReturnURI"] = ctx.FormString("return_uri") + ctx.Data["CommitCandidateEmails"] = getCandidateEmailAddresses(ctx) + ctx.Data["CommitDefaultEmail"] = ctx.Doer.GetEmail() +} + +func editFile(ctx *context.Context, isNewFile bool) { + editFileCommon(ctx, isNewFile) canCommit := renderCommitRights(ctx) treePath := cleanUploadFileName(ctx.Repo.TreePath) @@ -174,28 +197,19 @@ func editFile(ctx *context.Context, isNewFile bool) { ctx.Data["FileContent"] = content } } else { - // Append filename from query, or empty string to allow user name the new file. + // Append filename from query, or empty string to allow username the new file. treeNames = append(treeNames, fileName) } ctx.Data["TreeNames"] = treeNames ctx.Data["TreePaths"] = treePaths - ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() ctx.Data["commit_summary"] = "" ctx.Data["commit_message"] = "" - if canCommit { - ctx.Data["commit_choice"] = frmCommitChoiceDirect - } else { - ctx.Data["commit_choice"] = frmCommitChoiceNewBranch - } + ctx.Data["commit_choice"] = util.Iif(canCommit, frmCommitChoiceDirect, frmCommitChoiceNewBranch) ctx.Data["new_branch_name"] = GetUniquePatchBranchName(ctx) ctx.Data["last_commit"] = ctx.Repo.CommitID - ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",") - ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",") - ctx.Data["EditorconfigJson"] = GetEditorConfig(ctx, treePath) - ctx.Data["IsEditingFileOnly"] = ctx.FormString("return_uri") != "" - ctx.Data["ReturnURI"] = ctx.FormString("return_uri") + ctx.Data["EditorconfigJson"] = GetEditorConfig(ctx, treePath) ctx.HTML(http.StatusOK, tplEditFile) } @@ -224,6 +238,9 @@ func NewFile(ctx *context.Context) { } func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile bool) { + editFileCommon(ctx, isNewFile) + ctx.Data["PageHasPosted"] = true + canCommit := renderCommitRights(ctx) treeNames, treePaths := getParentTreeFields(form.TreePath) branchName := ctx.Repo.BranchName @@ -231,21 +248,15 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b branchName = form.NewBranchName } - ctx.Data["PageIsEdit"] = true - ctx.Data["PageHasPosted"] = true - ctx.Data["IsNewFile"] = isNewFile ctx.Data["TreePath"] = form.TreePath ctx.Data["TreeNames"] = treeNames ctx.Data["TreePaths"] = treePaths - ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(ctx.Repo.BranchName) ctx.Data["FileContent"] = form.Content ctx.Data["commit_summary"] = form.CommitSummary ctx.Data["commit_message"] = form.CommitMessage ctx.Data["commit_choice"] = form.CommitChoice ctx.Data["new_branch_name"] = form.NewBranchName ctx.Data["last_commit"] = ctx.Repo.CommitID - ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",") - ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",") ctx.Data["EditorconfigJson"] = GetEditorConfig(ctx, form.TreePath) if ctx.HasError() { @@ -253,7 +264,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b return } - // Cannot commit to a an existing branch if user doesn't have rights + // Cannot commit to an existing branch if user doesn't have rights if branchName == ctx.Repo.BranchName && !canCommit { ctx.Data["Err_NewBranchName"] = true ctx.Data["commit_choice"] = frmCommitChoiceNewBranch @@ -276,6 +287,17 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b message += "\n\n" + form.CommitMessage } + gitCommitter := &files_service.IdentityOptions{} + if form.CommitEmail != "" { + if util.SliceContainsString(getCandidateEmailAddresses(ctx), form.CommitEmail, true) { + gitCommitter.GitUserEmail = form.CommitEmail + } else { + ctx.Data["Err_CommitEmail"] = true + ctx.RenderWithErr(ctx.Tr("repo.editor.invalid_commit_email"), tplEditFile, &form) + return + } + } + operation := "update" if isNewFile { operation = "create" @@ -294,7 +316,9 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b ContentReader: strings.NewReader(strings.ReplaceAll(form.Content, "\r", "")), }, }, - Signoff: form.Signoff, + Signoff: form.Signoff, + Author: gitCommitter, + Committer: gitCommitter, }); err != nil { // This is where we handle all the errors thrown by files_service.ChangeRepoFiles if git.IsErrNotExist(err) { diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 1a1c6585db..40e15f2d5c 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -720,6 +720,7 @@ type EditRepoFileForm struct { NewBranchName string `binding:"GitRefName;MaxSize(100)"` LastCommit string Signoff bool + CommitEmail string } // Validate validates the fields diff --git a/services/packages/cargo/index.go b/services/packages/cargo/index.go index e8a8313625..88a463e4c6 100644 --- a/services/packages/cargo/index.go +++ b/services/packages/cargo/index.go @@ -11,7 +11,6 @@ import ( "io" "path" "strconv" - "time" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" @@ -296,8 +295,13 @@ func alterRepositoryContent(ctx context.Context, doer *user_model.User, repo *re return err } - now := time.Now() - commitHash, err := t.CommitTreeWithDate(lastCommitID, doer, doer, treeHash, commitMessage, false, now, now) + commitOpts := &files_service.CommitTreeUserOptions{ + ParentCommitID: lastCommitID, + TreeHash: treeHash, + CommitMessage: commitMessage, + DoerUser: doer, + } + commitHash, err := t.CommitTree(commitOpts) if err != nil { return err } diff --git a/services/repository/files/cherry_pick.go b/services/repository/files/cherry_pick.go index 10545e9e03..3457283803 100644 --- a/services/repository/files/cherry_pick.go +++ b/services/repository/files/cherry_pick.go @@ -32,15 +32,13 @@ func (err ErrCommitIDDoesNotMatch) Error() string { return fmt.Sprintf("file CommitID does not match [given: %s, expected: %s]", err.GivenCommitID, err.CurrentCommitID) } -// CherryPick cherrypicks or reverts a commit to the given repository +// CherryPick cherry-picks or reverts a commit to the given repository func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, revert bool, opts *ApplyDiffPatchOptions) (*structs.FileResponse, error) { if err := opts.Validate(ctx, repo, doer); err != nil { return nil, err } message := strings.TrimSpace(opts.Message) - author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer) - t, err := NewTemporaryUploadRepository(ctx, repo) if err != nil { log.Error("NewTemporaryUploadRepository failed: %v", err) @@ -112,12 +110,21 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod } // Now commit the tree - var commitHash string - if opts.Dates != nil { - commitHash, err = t.CommitTreeWithDate("HEAD", author, committer, treeHash, message, opts.Signoff, opts.Dates.Author, opts.Dates.Committer) - } else { - commitHash, err = t.CommitTree("HEAD", author, committer, treeHash, message, opts.Signoff) + commitOpts := &CommitTreeUserOptions{ + ParentCommitID: "HEAD", + TreeHash: treeHash, + CommitMessage: message, + SignOff: opts.Signoff, + DoerUser: doer, + AuthorIdentity: opts.Author, + AuthorTime: nil, + CommitterIdentity: opts.Committer, + CommitterTime: nil, } + if opts.Dates != nil { + commitOpts.AuthorTime, commitOpts.CommitterTime = &opts.Dates.Author, &opts.Dates.Committer + } + commitHash, err := t.CommitTree(commitOpts) if err != nil { return nil, err } diff --git a/services/repository/files/file.go b/services/repository/files/file.go index d7ca8e79e5..2caa1b4946 100644 --- a/services/repository/files/file.go +++ b/services/repository/files/file.go @@ -11,7 +11,6 @@ import ( "time" repo_model "code.gitea.io/gitea/models/repo" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" @@ -111,51 +110,6 @@ func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*ap return fileCommit, nil } -// GetAuthorAndCommitterUsers Gets the author and committer user objects from the IdentityOptions -func GetAuthorAndCommitterUsers(author, committer *IdentityOptions, doer *user_model.User) (authorUser, committerUser *user_model.User) { - // Committer and author are optional. If they are not the doer (not same email address) - // then we use bogus User objects for them to store their FullName and Email. - // If only one of the two are provided, we set both of them to it. - // If neither are provided, both are the doer. - if committer != nil && committer.Email != "" { - if doer != nil && strings.EqualFold(doer.Email, committer.Email) { - committerUser = doer // the committer is the doer, so will use their user object - if committer.Name != "" { - committerUser.FullName = committer.Name - } - } else { - committerUser = &user_model.User{ - FullName: committer.Name, - Email: committer.Email, - } - } - } - if author != nil && author.Email != "" { - if doer != nil && strings.EqualFold(doer.Email, author.Email) { - authorUser = doer // the author is the doer, so will use their user object - if authorUser.Name != "" { - authorUser.FullName = author.Name - } - } else { - authorUser = &user_model.User{ - FullName: author.Name, - Email: author.Email, - } - } - } - if authorUser == nil { - if committerUser != nil { - authorUser = committerUser // No valid author was given so use the committer - } else if doer != nil { - authorUser = doer // No valid author was given and no valid committer so use the doer - } - } - if committerUser == nil { - committerUser = authorUser // No valid committer so use the author as the committer (was set to a valid user above) - } - return authorUser, committerUser -} - // ErrFilenameInvalid represents a "FilenameInvalid" kind of error. type ErrFilenameInvalid struct { Path string diff --git a/services/repository/files/patch.go b/services/repository/files/patch.go index 38c17b4073..78c275f01c 100644 --- a/services/repository/files/patch.go +++ b/services/repository/files/patch.go @@ -126,8 +126,6 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user message := strings.TrimSpace(opts.Message) - author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer) - t, err := NewTemporaryUploadRepository(ctx, repo) if err != nil { log.Error("NewTemporaryUploadRepository failed: %v", err) @@ -187,12 +185,21 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user } // Now commit the tree - var commitHash string - if opts.Dates != nil { - commitHash, err = t.CommitTreeWithDate("HEAD", author, committer, treeHash, message, opts.Signoff, opts.Dates.Author, opts.Dates.Committer) - } else { - commitHash, err = t.CommitTree("HEAD", author, committer, treeHash, message, opts.Signoff) + commitOpts := &CommitTreeUserOptions{ + ParentCommitID: "HEAD", + TreeHash: treeHash, + CommitMessage: message, + SignOff: opts.Signoff, + DoerUser: doer, + AuthorIdentity: opts.Author, + AuthorTime: nil, + CommitterIdentity: opts.Committer, + CommitterTime: nil, } + if opts.Dates != nil { + commitOpts.AuthorTime, commitOpts.CommitterTime = &opts.Dates.Author, &opts.Dates.Committer + } + commitHash, err := t.CommitTree(commitOpts) if err != nil { return nil, err } diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go index 138af991f9..cf1402397b 100644 --- a/services/repository/files/temp_repo.go +++ b/services/repository/files/temp_repo.go @@ -19,6 +19,7 @@ import ( "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" asymkey_service "code.gitea.io/gitea/services/asymkey" "code.gitea.io/gitea/services/gitdiff" ) @@ -225,15 +226,53 @@ func (t *TemporaryUploadRepository) GetLastCommitByRef(ref string) (string, erro return strings.TrimSpace(stdout), nil } -// CommitTree creates a commit from a given tree for the user with provided message -func (t *TemporaryUploadRepository) CommitTree(parent string, author, committer *user_model.User, treeHash, message string, signoff bool) (string, error) { - return t.CommitTreeWithDate(parent, author, committer, treeHash, message, signoff, time.Now(), time.Now()) +type CommitTreeUserOptions struct { + ParentCommitID string + TreeHash string + CommitMessage string + SignOff bool + + DoerUser *user_model.User + + AuthorIdentity *IdentityOptions // if nil, use doer + AuthorTime *time.Time // if nil, use now + CommitterIdentity *IdentityOptions + CommitterTime *time.Time } -// CommitTreeWithDate creates a commit from a given tree for the user with provided message -func (t *TemporaryUploadRepository) CommitTreeWithDate(parent string, author, committer *user_model.User, treeHash, message string, signoff bool, authorDate, committerDate time.Time) (string, error) { - authorSig := author.NewGitSig() - committerSig := committer.NewGitSig() +func makeGitUserSignature(doer *user_model.User, identity, other *IdentityOptions) *git.Signature { + gitSig := &git.Signature{} + if identity != nil { + gitSig.Name, gitSig.Email = identity.GitUserName, identity.GitUserEmail + } + if other != nil { + gitSig.Name = util.IfZero(gitSig.Name, other.GitUserName) + gitSig.Email = util.IfZero(gitSig.Email, other.GitUserEmail) + } + if gitSig.Name == "" { + gitSig.Name = doer.GitName() + } + if gitSig.Email == "" { + gitSig.Email = doer.GetEmail() + } + return gitSig +} + +// CommitTree creates a commit from a given tree for the user with provided message +func (t *TemporaryUploadRepository) CommitTree(opts *CommitTreeUserOptions) (string, error) { + authorSig := makeGitUserSignature(opts.DoerUser, opts.AuthorIdentity, opts.CommitterIdentity) + committerSig := makeGitUserSignature(opts.DoerUser, opts.CommitterIdentity, opts.AuthorIdentity) + + authorDate := opts.AuthorTime + committerDate := opts.CommitterTime + if authorDate == nil && committerDate == nil { + authorDate = util.ToPointer(time.Now()) + committerDate = authorDate + } else if authorDate == nil { + authorDate = committerDate + } else if committerDate == nil { + committerDate = authorDate + } // Because this may call hooks we should pass in the environment env := append(os.Environ(), @@ -244,21 +283,21 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(parent string, author, co ) messageBytes := new(bytes.Buffer) - _, _ = messageBytes.WriteString(message) + _, _ = messageBytes.WriteString(opts.CommitMessage) _, _ = messageBytes.WriteString("\n") - cmdCommitTree := git.NewCommand(t.ctx, "commit-tree").AddDynamicArguments(treeHash) - if parent != "" { - cmdCommitTree.AddOptionValues("-p", parent) + cmdCommitTree := git.NewCommand(t.ctx, "commit-tree").AddDynamicArguments(opts.TreeHash) + if opts.ParentCommitID != "" { + cmdCommitTree.AddOptionValues("-p", opts.ParentCommitID) } var sign bool var keyID string var signer *git.Signature - if parent != "" { - sign, keyID, signer, _ = asymkey_service.SignCRUDAction(t.ctx, t.repo.RepoPath(), author, t.basePath, parent) + if opts.ParentCommitID != "" { + sign, keyID, signer, _ = asymkey_service.SignCRUDAction(t.ctx, t.repo.RepoPath(), opts.DoerUser, t.basePath, opts.ParentCommitID) } else { - sign, keyID, signer, _ = asymkey_service.SignInitialCommit(t.ctx, t.repo.RepoPath(), author) + sign, keyID, signer, _ = asymkey_service.SignInitialCommit(t.ctx, t.repo.RepoPath(), opts.DoerUser) } if sign { cmdCommitTree.AddOptionFormat("-S%s", keyID) @@ -279,7 +318,7 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(parent string, author, co cmdCommitTree.AddArguments("--no-gpg-sign") } - if signoff { + if opts.SignOff { // Signed-off-by _, _ = messageBytes.WriteString("\n") _, _ = messageBytes.WriteString("Signed-off-by: ") diff --git a/services/repository/files/update.go b/services/repository/files/update.go index a2763105b0..a707ea8bb6 100644 --- a/services/repository/files/update.go +++ b/services/repository/files/update.go @@ -27,8 +27,8 @@ import ( // IdentityOptions for a person's identity like an author or committer type IdentityOptions struct { - Name string - Email string + GitUserName string // to match "git config user.name" + GitUserEmail string // to match "git config user.email" } // CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE @@ -160,8 +160,6 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use message := strings.TrimSpace(opts.Message) - author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer) - t, err := NewTemporaryUploadRepository(ctx, repo) if err != nil { log.Error("NewTemporaryUploadRepository failed: %v", err) @@ -262,12 +260,21 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use } // Now commit the tree - var commitHash string - if opts.Dates != nil { - commitHash, err = t.CommitTreeWithDate(opts.LastCommitID, author, committer, treeHash, message, opts.Signoff, opts.Dates.Author, opts.Dates.Committer) - } else { - commitHash, err = t.CommitTree(opts.LastCommitID, author, committer, treeHash, message, opts.Signoff) + commitOpts := &CommitTreeUserOptions{ + ParentCommitID: opts.LastCommitID, + TreeHash: treeHash, + CommitMessage: message, + SignOff: opts.Signoff, + DoerUser: doer, + AuthorIdentity: opts.Author, + AuthorTime: nil, + CommitterIdentity: opts.Committer, + CommitterTime: nil, } + if opts.Dates != nil { + commitOpts.AuthorTime, commitOpts.CommitterTime = &opts.Dates.Author, &opts.Dates.Committer + } + commitHash, err := t.CommitTree(commitOpts) if err != nil { return nil, err } diff --git a/services/repository/files/upload.go b/services/repository/files/upload.go index cbfaf49d13..af32bc4c85 100644 --- a/services/repository/files/upload.go +++ b/services/repository/files/upload.go @@ -128,12 +128,15 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use return err } - // make author and committer the doer - author := doer - committer := doer - // Now commit the tree - commitHash, err := t.CommitTree(opts.LastCommitID, author, committer, treeHash, opts.Message, opts.Signoff) + commitOpts := &CommitTreeUserOptions{ + ParentCommitID: opts.LastCommitID, + TreeHash: treeHash, + CommitMessage: opts.Message, + SignOff: opts.Signoff, + DoerUser: doer, + } + commitHash, err := t.CommitTree(commitOpts) if err != nil { return err } diff --git a/templates/repo/editor/commit_form.tmpl b/templates/repo/editor/commit_form.tmpl index c050324e93..8f46c47b96 100644 --- a/templates/repo/editor/commit_form.tmpl +++ b/templates/repo/editor/commit_form.tmpl @@ -66,6 +66,16 @@
{{end}}
+ {{if and .CommitCandidateEmails (gt (len .CommitCandidateEmails) 1)}} +
+ + +
+ {{end}}
{{$.CsrfTokenHtml}} -
-
From f24d73ab5fb8112f40e9f17c80c40822369ba55d Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 31 Jan 2025 04:12:14 +0800 Subject: [PATCH 034/655] Fix "redirect link" handling (#33440) `a%2fb` should not redirect to `a/b` --------- Co-authored-by: delvh --- routers/web/repo/branch.go | 6 ++-- routers/web/repo/view_home.go | 19 ++++++++--- routers/web/web.go | 8 +---- services/context/api.go | 2 +- services/context/repo.go | 37 ++++++++++++++------- tests/integration/links_test.go | 8 +++-- tests/integration/nonascii_branches_test.go | 30 ++++++++--------- 7 files changed, 65 insertions(+), 45 deletions(-) diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 8747526f72..6f8d4d9959 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -93,7 +93,7 @@ func Branches(ctx *context.Context) { // DeleteBranchPost responses for delete merged branch func DeleteBranchPost(ctx *context.Context) { - defer redirect(ctx) + defer jsonRedirectBranches(ctx) branchName := ctx.FormString("name") if err := repo_service.DeleteBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName, nil); err != nil { @@ -120,7 +120,7 @@ func DeleteBranchPost(ctx *context.Context) { // RestoreBranchPost responses for delete merged branch func RestoreBranchPost(ctx *context.Context) { - defer redirect(ctx) + defer jsonRedirectBranches(ctx) branchID := ctx.FormInt64("branch_id") branchName := ctx.FormString("name") @@ -170,7 +170,7 @@ func RestoreBranchPost(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.branch.restore_success", deletedBranch.Name)) } -func redirect(ctx *context.Context) { +func jsonRedirectBranches(ctx *context.Context) { ctx.JSONRedirect(ctx.Repo.RepoLink + "/branches?page=" + url.QueryEscape(ctx.FormString("page"))) } diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index 6c6e007b50..e7255cde0a 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -413,8 +413,19 @@ func Home(ctx *context.Context) { ctx.HTML(http.StatusOK, tplRepoHome) } -// HomeRedirect redirects from /tree/* to /src/* in order to maintain a similar URL structure. -func HomeRedirect(ctx *context.Context) { - remainder := ctx.PathParam("*") - ctx.Redirect(ctx.Repo.RepoLink + "/src/" + util.PathEscapeSegments(remainder)) +func RedirectRepoTreeToSrc(ctx *context.Context) { + // Redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*", + // then use the deprecated "/src/*" handler to guess the ref type and render a file list page. + // This is done intentionally so that Gitea's repo URL structure matches other forges (GitHub/GitLab) provide, + // allowing us to construct submodule URLs across forges easily. + // For example, when viewing a submodule, we can simply construct the link as: + // * "https://gitea/owner/repo/tree/{CommitID}" + // * "https://github/owner/repo/tree/{CommitID}" + // * "https://gitlab/owner/repo/tree/{CommitID}" + // Then no matter which forge the submodule is using, the link works. + redirect := ctx.Repo.RepoLink + "/src/" + ctx.PathParamRaw("*") + if ctx.Req.URL.RawQuery != "" { + redirect += "?" + ctx.Req.URL.RawQuery + } + ctx.Redirect(redirect) } diff --git a/routers/web/web.go b/routers/web/web.go index 096f1e6bbe..b02bbe037f 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1583,13 +1583,7 @@ func registerRoutes(m *web.Router) { m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.Home) m.Get("/*", context.RepoRefByType(""), repo.Home) // "/*" route is deprecated, and kept for backward compatibility }, repo.SetEditorconfigIfExists) - - // Add a /tree/* path to redirect to the /src/* path, which - // will redirect to the canonical URL for that ref. This is - // included so that Gitea's repo URL structure matches what - // other forges provide, allowing clients to construct URLs - // that work across forges. - m.Get("/tree/*", repo.HomeRedirect) + m.Get("/tree/*", repo.RedirectRepoTreeToSrc) // redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*" m.Get("/forks", context.RepoRef(), repo.Forks) m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff) diff --git a/services/context/api.go b/services/context/api.go index 3a3cbe670e..bdeff0af63 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -293,7 +293,7 @@ func RepoRefForAPI(next http.Handler) http.Handler { return } - refName, _ := getRefNameLegacy(ctx.Base, ctx.Repo, ctx.PathParam("*"), ctx.FormTrim("ref")) + refName, _, _ := getRefNameLegacy(ctx.Base, ctx.Repo, ctx.PathParam("*"), ctx.FormTrim("ref")) var err error if ctx.Repo.GitRepo.IsBranchExist(refName) { diff --git a/services/context/repo.go b/services/context/repo.go index b0cfd78cf5..1cb35b9b83 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -686,24 +686,24 @@ func getRefNameFromPath(repo *Repository, path string, isExist func(string) bool return "" } -func getRefNameLegacy(ctx *Base, repo *Repository, reqPath, extraRef string) (string, git.RefType) { +func getRefNameLegacy(ctx *Base, repo *Repository, reqPath, extraRef string) (refName string, refType git.RefType, fallbackDefaultBranch bool) { reqRefPath := path.Join(extraRef, reqPath) reqRefPathParts := strings.Split(reqRefPath, "/") if refName := getRefName(ctx, repo, reqRefPath, git.RefTypeBranch); refName != "" { - return refName, git.RefTypeBranch + return refName, git.RefTypeBranch, false } if refName := getRefName(ctx, repo, reqRefPath, git.RefTypeTag); refName != "" { - return refName, git.RefTypeTag + return refName, git.RefTypeTag, false } if git.IsStringLikelyCommitID(git.ObjectFormatFromName(repo.Repository.ObjectFormatName), reqRefPathParts[0]) { // FIXME: this logic is different from other types. Ideally, it should also try to GetCommit to check if it exists repo.TreePath = strings.Join(reqRefPathParts[1:], "/") - return reqRefPathParts[0], git.RefTypeCommit + return reqRefPathParts[0], git.RefTypeCommit, false } // FIXME: the old code falls back to default branch if "ref" doesn't exist, there could be an edge case: // "README?ref=no-such" would read the README file from the default branch, but the user might expect a 404 repo.TreePath = reqPath - return repo.Repository.DefaultBranch, git.RefTypeBranch + return repo.Repository.DefaultBranch, git.RefTypeBranch, true } func getRefName(ctx *Base, repo *Repository, path string, refType git.RefType) string { @@ -838,8 +838,9 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { } } else { // there is a path in request guessLegacyPath := refType == "" + fallbackDefaultBranch := false if guessLegacyPath { - refShortName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "") + refShortName, refType, fallbackDefaultBranch = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "") } else { refShortName = getRefName(ctx.Base, ctx.Repo, reqPath, refType) } @@ -897,12 +898,24 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { if guessLegacyPath { // redirect from old URL scheme to new URL scheme - prefix := strings.TrimPrefix(setting.AppSubURL+strings.ToLower(strings.TrimSuffix(ctx.Req.URL.Path, ctx.PathParam("*"))), strings.ToLower(ctx.Repo.RepoLink)) - redirect := path.Join( - ctx.Repo.RepoLink, - util.PathEscapeSegments(prefix), - ctx.Repo.RefTypeNameSubURL(), - util.PathEscapeSegments(ctx.Repo.TreePath)) + // * /user2/repo1/commits/master => /user2/repo1/commits/branch/master + // * /user2/repo1/src/master => /user2/repo1/src/branch/master + // * /user2/repo1/src/README.md => /user2/repo1/src/branch/master/README.md (fallback to default branch) + var redirect string + refSubPath := "src" + // remove the "/subpath/owner/repo/" prefix, the names are case-insensitive + remainingLowerPath, cut := strings.CutPrefix(setting.AppSubURL+strings.ToLower(ctx.Req.URL.Path), strings.ToLower(ctx.Repo.RepoLink)+"/") + if cut { + refSubPath, _, _ = strings.Cut(remainingLowerPath, "/") // it could be "src" or "commits" + } + if fallbackDefaultBranch { + redirect = fmt.Sprintf("%s/%s/%s/%s/%s", ctx.Repo.RepoLink, refSubPath, refType, util.PathEscapeSegments(refShortName), ctx.PathParamRaw("*")) + } else { + redirect = fmt.Sprintf("%s/%s/%s/%s", ctx.Repo.RepoLink, refSubPath, refType, ctx.PathParamRaw("*")) + } + if ctx.Req.URL.RawQuery != "" { + redirect += "?" + ctx.Req.URL.RawQuery + } ctx.Redirect(redirect) return } diff --git a/tests/integration/links_test.go b/tests/integration/links_test.go index b54f670c23..1bfb3b83d2 100644 --- a/tests/integration/links_test.go +++ b/tests/integration/links_test.go @@ -52,9 +52,11 @@ func TestRedirectsNoLogin(t *testing.T) { redirects := []struct{ from, to string }{ {"/user2/repo1/commits/master", "/user2/repo1/commits/branch/master"}, {"/user2/repo1/src/master", "/user2/repo1/src/branch/master"}, - {"/user2/repo1/src/master/file.txt", "/user2/repo1/src/branch/master/file.txt"}, - {"/user2/repo1/src/master/directory/file.txt", "/user2/repo1/src/branch/master/directory/file.txt"}, - {"/user/avatar/Ghost/-1", "/assets/img/avatar_default.png"}, + {"/user2/repo1/src/master/a%2fb.txt", "/user2/repo1/src/branch/master/a%2fb.txt"}, + {"/user2/repo1/src/master/directory/file.txt?a=1", "/user2/repo1/src/branch/master/directory/file.txt?a=1"}, + {"/user2/repo1/tree/a%2fb?a=1", "/user2/repo1/src/a%2fb?a=1"}, + {"/user/avatar/GhosT/-1", "/assets/img/avatar_default.png"}, + {"/user/avatar/Gitea-ActionS/0", "/assets/img/avatar_default.png"}, {"/api/v1/swagger", "/api/swagger"}, } for _, c := range redirects { diff --git a/tests/integration/nonascii_branches_test.go b/tests/integration/nonascii_branches_test.go index ae348d8173..cc71acf002 100644 --- a/tests/integration/nonascii_branches_test.go +++ b/tests/integration/nonascii_branches_test.go @@ -46,21 +46,21 @@ func TestNonAsciiBranches(t *testing.T) { { from: "master/badfile", to: "branch/master/badfile", - status: http.StatusNotFound, // it does not exists + status: http.StatusNotFound, // it does not exist }, { from: "ГлавнаяВетка", - to: "branch/%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F%D0%92%D0%B5%D1%82%D0%BA%D0%B0", + to: "branch/%d0%93%d0%bb%d0%b0%d0%b2%d0%bd%d0%b0%d1%8f%d0%92%d0%b5%d1%82%d0%ba%d0%b0", status: http.StatusOK, }, { from: "а/б/в", - to: "branch/%D0%B0/%D0%B1/%D0%B2", + to: "branch/%d0%b0/%d0%b1/%d0%b2", status: http.StatusOK, }, { from: "Grüßen/README.md", - to: "branch/Gr%C3%BC%C3%9Fen/README.md", + to: "branch/Gr%c3%bc%c3%9fen/README.md", status: http.StatusOK, }, { @@ -70,7 +70,7 @@ func TestNonAsciiBranches(t *testing.T) { }, { from: "Plus+Is+Not+Space/Файл.md", - to: "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md", + to: "branch/Plus+Is+Not+Space/%d0%a4%d0%b0%d0%b9%d0%bb.md", status: http.StatusOK, }, { @@ -80,29 +80,29 @@ func TestNonAsciiBranches(t *testing.T) { }, { from: "ブランチ", - to: "branch/%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81", + to: "branch/%e3%83%96%e3%83%a9%e3%83%b3%e3%83%81", status: http.StatusOK, }, // Tags { from: "Тэг", - to: "tag/%D0%A2%D1%8D%D0%B3", + to: "tag/%d0%a2%d1%8d%d0%b3", status: http.StatusOK, }, { from: "Ё/人", - to: "tag/%D0%81/%E4%BA%BA", + to: "tag/%d0%81/%e4%ba%ba", status: http.StatusOK, }, { from: "タグ", - to: "tag/%E3%82%BF%E3%82%B0", + to: "tag/%e3%82%bf%e3%82%b0", status: http.StatusOK, }, { from: "タグ/ファイル.md", - to: "tag/%E3%82%BF%E3%82%B0/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.md", + to: "tag/%e3%82%bf%e3%82%b0/%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab.md", status: http.StatusOK, }, @@ -114,12 +114,12 @@ func TestNonAsciiBranches(t *testing.T) { }, { from: "Файл.md", - to: "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md", + to: "branch/Plus+Is+Not+Space/%d0%a4%d0%b0%d0%b9%d0%bb.md", status: http.StatusOK, }, { from: "ファイル.md", - to: "branch/Plus+Is+Not+Space/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.md", + to: "branch/Plus+Is+Not+Space/%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab.md", status: http.StatusNotFound, // it's not on default branch }, @@ -131,7 +131,7 @@ func TestNonAsciiBranches(t *testing.T) { }, { from: "%E3%82%BF%E3%82%b0", - to: "tag/%E3%82%BF%E3%82%B0", + to: "tag/%E3%82%BF%E3%82%b0", status: http.StatusOK, }, { @@ -141,12 +141,12 @@ func TestNonAsciiBranches(t *testing.T) { }, { from: "%D0%81%2F%E4%BA%BA", - to: "tag/%D0%81/%E4%BA%BA", + to: "tag/%D0%81%2F%E4%BA%BA", status: http.StatusOK, }, { from: "Ё%2F%E4%BA%BA", - to: "tag/%D0%81/%E4%BA%BA", + to: "tag/%d0%81%2F%E4%BA%BA", status: http.StatusOK, }, { From b57d9f41d4936382a985b41b4a74df463abd983a Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 31 Jan 2025 06:54:50 +0800 Subject: [PATCH 035/655] Fix issue sidebar dropdown keyboard support (#33447) Just a quick fix, fix #33444 --- templates/repo/issue/sidebar/assignee_list.tmpl | 3 ++- templates/repo/issue/sidebar/label_list.tmpl | 3 ++- templates/repo/issue/sidebar/milestone_list.tmpl | 4 ++-- templates/repo/issue/sidebar/project_list.tmpl | 3 ++- web_src/js/features/repo-issue-sidebar.md | 5 ++++- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/templates/repo/issue/sidebar/assignee_list.tmpl b/templates/repo/issue/sidebar/assignee_list.tmpl index 4fe8043f34..f124c3f1ce 100644 --- a/templates/repo/issue/sidebar/assignee_list.tmpl +++ b/templates/repo/issue/sidebar/assignee_list.tmpl @@ -15,8 +15,9 @@ {{svg "octicon-search" 16}}
-
{{ctx.Locale.Tr "repo.issues.new.clear_assignees"}}
- {{ctx.Locale.Tr "repo.issues.new.clear_labels"}} -
-
{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}
{{end}} -
{{ctx.Locale.Tr "repo.issues.new.clear_projects"}}
- {{if and .PageIsPullFiles $.SignedUserID (not .IsArchived) (not .DiffNotAvailable)}} + {{if and .PageIsPullFiles $.SignedUserID (not .DiffNotAvailable)}}
{{end}} - {{if and .PageIsPullFiles $.SignedUserID (not .IsArchived)}} + {{if and .PageIsPullFiles $.SignedUserID}} {{template "repo/diff/new_review" .}} {{end}}
@@ -105,7 +105,7 @@ {{$isCsv := (call $.IsCsvFile $file)}} {{$showFileViewToggle := or $isImage (and (not $file.IsIncomplete) $isCsv)}} {{$isExpandable := or (gt $file.Addition 0) (gt $file.Deletion 0) $file.IsBin}} - {{$isReviewFile := and $.IsSigned $.PageIsPullFiles (not $.IsArchived) $.IsShowingAllCommits}} + {{$isReviewFile := and $.IsSigned $.PageIsPullFiles (not $.Repository.IsArchived) $.IsShowingAllCommits}}

diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl index ec52934a9d..2e8261e479 100644 --- a/templates/repo/diff/comments.tmpl +++ b/templates/repo/diff/comments.tmpl @@ -48,7 +48,9 @@
{{end}} {{end}} - {{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID)}} + {{if not $.root.Repository.IsArchived}} + {{template "repo/issue/view_content/add_reaction" dict "ActionURL" (printf "%s/comments/%d/reactions" $.root.RepoLink .ID)}} + {{end}} {{template "repo/issue/view_content/context_menu" dict "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}}

diff --git a/templates/repo/diff/new_review.tmpl b/templates/repo/diff/new_review.tmpl index 2febc6303a..3bb01a139a 100644 --- a/templates/repo/diff/new_review.tmpl +++ b/templates/repo/diff/new_review.tmpl @@ -1,56 +1,59 @@ -
- - {{if $.IsShowingAllCommits}} -
-
- - {{.CsrfTokenHtml}} - -
-
{{ctx.Locale.Tr "repo.diff.review.header"}}
- {{svg "octicon-x" 16}} -
-
- {{template "shared/combomarkdowneditor" (dict - "MarkdownPreviewInRepo" $.Repository - "MarkdownPreviewMode" "comment" - "TextareaName" "content" - "TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.review.placeholder") - "DropzoneParentContainer" "form" - )}} -
- {{if .IsAttachmentEnabled}} -
- {{template "repo/upload" .}} -
- {{end}} -
- {{$showSelfTooltip := (and $.IsSigned ($.Issue.IsPoster $.SignedUser.ID))}} - {{if not $.Issue.IsClosed}} - {{if $showSelfTooltip}} - - - - {{else}} - - {{end}} - {{end}} - - {{if not $.Issue.IsClosed}} - {{if $showSelfTooltip}} - - - - {{else}} - - {{end}} - {{end}} - -
-
- {{end}}
+{{if $.IsShowingAllCommits}} +
+
+
+ {{.CsrfTokenHtml}} + +
+
{{ctx.Locale.Tr "repo.diff.review.header"}}
+ {{svg "octicon-x" 16}} +
+
+ {{template "shared/combomarkdowneditor" (dict + "MarkdownPreviewInRepo" $.Repository + "MarkdownPreviewMode" "comment" + "TextareaName" "content" + "TextareaPlaceholder" (ctx.Locale.Tr "repo.diff.review.placeholder") + "DropzoneParentContainer" "form" + )}} +
+ {{if .IsAttachmentEnabled}} +
+ {{template "repo/upload" .}} +
+ {{end}} +
+ {{$showSelfTooltip := (and $.IsSigned ($.Issue.IsPoster $.SignedUser.ID))}} + {{if not $.Issue.IsClosed}} + {{if $showSelfTooltip}} + + + + {{else}} + + {{end}} + {{end}} + + {{if not $.Issue.IsClosed}} + {{if $showSelfTooltip}} + + + + {{else}} + + {{end}} + {{end}} +
+
+
+{{end}} diff --git a/web_src/js/features/repo-issue.ts b/web_src/js/features/repo-issue.ts index a0cb875a87..f5455393b2 100644 --- a/web_src/js/features/repo-issue.ts +++ b/web_src/js/features/repo-issue.ts @@ -421,13 +421,11 @@ export function initRepoPullRequestReview() { // The following part is only for diff views if (!$('.repository.pull.diff').length) return; - const $reviewBtn = $('.js-btn-review'); - const $panel = $reviewBtn.parent().find('.review-box-panel'); - const $closeBtn = $panel.find('.close'); - - if ($reviewBtn.length && $panel.length) { - const tippy = createTippy($reviewBtn[0], { - content: $panel[0], + const elReviewBtn = document.querySelector('.js-btn-review'); + const elReviewPanel = document.querySelector('.review-box-panel.tippy-target'); + if (elReviewBtn && elReviewPanel) { + const tippy = createTippy(elReviewBtn, { + content: elReviewPanel, theme: 'default', placement: 'bottom', trigger: 'click', @@ -435,11 +433,7 @@ export function initRepoPullRequestReview() { interactive: true, hideOnClick: true, }); - - $closeBtn.on('click', (e) => { - e.preventDefault(); - tippy.hide(); - }); + elReviewPanel.querySelector('.close').addEventListener('click', () => tippy.hide()); } addDelegatedEventListener(document, 'click', '.add-code-comment', async (el, e) => { From 5b83203f377994cc63baa3f445e26bf85b7e370d Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 1 Feb 2025 00:33:46 +0000 Subject: [PATCH 041/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_pt-PT.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 88308271a7..fa5ef9c3a4 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -1345,6 +1345,8 @@ editor.new_branch_name_desc=Nome do novo ramo… editor.cancel=Cancelar editor.filename_cannot_be_empty=O nome do ficheiro não pode estar em branco. editor.filename_is_invalid=O nome do ficheiro é inválido: "%s". +editor.commit_email=Email do cometimento +editor.invalid_commit_email=O email do comentimento é inválido. editor.branch_does_not_exist=O ramo "%s" não existe neste repositório. editor.branch_already_exists=O ramo "%s" já existe neste repositório. editor.directory_is_a_file=O nome da pasta "%s" já é usado como um nome de ficheiro neste repositório. From 040c830dec5c727a56d16df62b1673bce6fca645 Mon Sep 17 00:00:00 2001 From: Bruno Sofiato Date: Fri, 31 Jan 2025 21:59:49 -0300 Subject: [PATCH 042/655] Inclusion of rename organization api (#33303) This adds an endpoint (`/orgs/{org}/rename`) to rename organizations. I've modeled the endpoint using the rename user endpoint -- `/admin/users/{username}/rename` -- as base. It is the 1st time I wrote a new API endpoint (I've tried to follow the rename users endpoint code while writing it). So feel free to ping me if there is something wrong or missing. Resolves #32995 --------- Signed-off-by: Bruno Sofiato Co-authored-by: delvh Co-authored-by: wxiaoguang --- modules/structs/org.go | 9 ++ routers/api/v1/admin/user.go | 18 +-- routers/api/v1/api.go | 1 + routers/api/v1/org/org.go | 38 +++++ routers/api/v1/swagger/options.go | 3 + templates/swagger/v1_json.tmpl | 56 +++++++ tests/integration/api_org_test.go | 256 +++++++++++++++--------------- 7 files changed, 240 insertions(+), 141 deletions(-) diff --git a/modules/structs/org.go b/modules/structs/org.go index c0a545ac1c..f93b3b6493 100644 --- a/modules/structs/org.go +++ b/modules/structs/org.go @@ -57,3 +57,12 @@ type EditOrgOption struct { Visibility string `json:"visibility" binding:"In(,public,limited,private)"` RepoAdminChangeTeamAccess *bool `json:"repo_admin_change_team_access"` } + +// RenameOrgOption options when renaming an organization +type RenameOrgOption struct { + // New username for this org. This name cannot be in use yet by any other user. + // + // required: true + // unique: true + NewName string `json:"new_name" binding:"Required"` +} diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 21cb2f9ccd..53eee72631 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -477,26 +477,16 @@ func RenameUser(ctx *context.APIContext) { return } - oldName := ctx.ContextUser.Name newName := web.GetForm(ctx).(*api.RenameUserOption).NewName - // Check if user name has been changed + // Check if username has been changed if err := user_service.RenameUser(ctx, ctx.ContextUser, newName); err != nil { - switch { - case user_model.IsErrUserAlreadyExist(err): - ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("form.username_been_taken")) - case db.IsErrNameReserved(err): - ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_reserved", newName)) - case db.IsErrNamePatternNotAllowed(err): - ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_pattern_not_allowed", newName)) - case db.IsErrNameCharsNotAllowed(err): - ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_chars_not_allowed", newName)) - default: + if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) { + ctx.Error(http.StatusUnprocessableEntity, "", err) + } else { ctx.ServerError("ChangeUserName", err) } return } - - log.Trace("User name changed: %s -> %s", oldName, newName) ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index b1a42a85e6..438db4ae71 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1530,6 +1530,7 @@ func Routes() *web.Router { m.Combo("").Get(org.Get). Patch(reqToken(), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). Delete(reqToken(), reqOrgOwnership(), org.Delete) + m.Post("/rename", reqToken(), reqOrgOwnership(), bind(api.RenameOrgOption{}), org.Rename) m.Combo("/repos").Get(user.ListOrgRepos). Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) m.Group("/members", func() { diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index d65f922434..2fcba0bf1a 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -315,6 +315,44 @@ func Get(ctx *context.APIContext) { ctx.JSON(http.StatusOK, org) } +func Rename(ctx *context.APIContext) { + // swagger:operation POST /orgs/{org}/rename organization renameOrg + // --- + // summary: Rename an organization + // produces: + // - application/json + // parameters: + // - name: org + // in: path + // description: existing org name + // type: string + // required: true + // - name: body + // in: body + // required: true + // schema: + // "$ref": "#/definitions/RenameOrgOption" + // responses: + // "204": + // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + // "422": + // "$ref": "#/responses/validationError" + + form := web.GetForm(ctx).(*api.RenameOrgOption) + orgUser := ctx.Org.Organization.AsUser() + if err := user_service.RenameUser(ctx, orgUser, form.NewName); err != nil { + if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) { + ctx.Error(http.StatusUnprocessableEntity, "RenameOrg", err) + } else { + ctx.ServerError("RenameOrg", err) + } + return + } + ctx.Status(http.StatusNoContent) +} + // Edit change an organization's information func Edit(ctx *context.APIContext) { // swagger:operation PATCH /orgs/{org} organization orgEdit diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go index 125605d98f..353d6de89b 100644 --- a/routers/api/v1/swagger/options.go +++ b/routers/api/v1/swagger/options.go @@ -208,6 +208,9 @@ type swaggerParameterBodies struct { // in:body CreateVariableOption api.CreateVariableOption + // in:body + RenameOrgOption api.RenameOrgOption + // in:body UpdateVariableOption api.UpdateVariableOption } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 8082fc594a..c58b21062d 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -2991,6 +2991,46 @@ } } }, + "/orgs/{org}/rename": { + "post": { + "produces": [ + "application/json" + ], + "tags": [ + "organization" + ], + "summary": "Rename an organization", + "operationId": "renameOrg", + "parameters": [ + { + "type": "string", + "description": "existing org name", + "name": "org", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/RenameOrgOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, "/orgs/{org}/repos": { "get": { "produces": [ @@ -24207,6 +24247,22 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "RenameOrgOption": { + "description": "RenameOrgOption options when renaming an organization", + "type": "object", + "required": [ + "new_name" + ], + "properties": { + "new_name": { + "description": "New username for this org. This name cannot be in use yet by any other user.", + "type": "string", + "uniqueItems": true, + "x-go-name": "NewName" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "RenameUserOption": { "description": "RenameUserOption options when renaming a user", "type": "object", diff --git a/tests/integration/api_org_test.go b/tests/integration/api_org_test.go index fff121490c..d766b1e8be 100644 --- a/tests/integration/api_org_test.go +++ b/tests/integration/api_org_test.go @@ -6,7 +6,6 @@ package integration import ( "fmt" "net/http" - "net/url" "strings" "testing" @@ -19,46 +18,52 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" ) -func TestAPIOrgCreate(t *testing.T) { - onGiteaRun(t, func(*testing.T, *url.URL) { - token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) +func TestAPIOrgCreateRename(t *testing.T) { + defer tests.PrepareTestEnv(t)() + token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) - org := api.CreateOrgOption{ - UserName: "user1_org", - FullName: "User1's organization", - Description: "This organization created by user1", - Website: "https://try.gitea.io", - Location: "Shanghai", - Visibility: "limited", - } - req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &org). - AddTokenAuth(token) - resp := MakeRequest(t, req, http.StatusCreated) + org := api.CreateOrgOption{ + UserName: "user1_org", + FullName: "User1's organization", + Description: "This organization created by user1", + Website: "https://try.gitea.io", + Location: "Shanghai", + Visibility: "limited", + } + req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &org).AddTokenAuth(token) + resp := MakeRequest(t, req, http.StatusCreated) - var apiOrg api.Organization - DecodeJSON(t, resp, &apiOrg) + var apiOrg api.Organization + DecodeJSON(t, resp, &apiOrg) - assert.Equal(t, org.UserName, apiOrg.Name) - assert.Equal(t, org.FullName, apiOrg.FullName) - assert.Equal(t, org.Description, apiOrg.Description) - assert.Equal(t, org.Website, apiOrg.Website) - assert.Equal(t, org.Location, apiOrg.Location) - assert.Equal(t, org.Visibility, apiOrg.Visibility) + assert.Equal(t, org.UserName, apiOrg.Name) + assert.Equal(t, org.FullName, apiOrg.FullName) + assert.Equal(t, org.Description, apiOrg.Description) + assert.Equal(t, org.Website, apiOrg.Website) + assert.Equal(t, org.Location, apiOrg.Location) + assert.Equal(t, org.Visibility, apiOrg.Visibility) - unittest.AssertExistsAndLoadBean(t, &user_model.User{ - Name: org.UserName, - LowerName: strings.ToLower(org.UserName), - FullName: org.FullName, - }) + unittest.AssertExistsAndLoadBean(t, &user_model.User{ + Name: org.UserName, + LowerName: strings.ToLower(org.UserName), + FullName: org.FullName, + }) + // check org name + req = NewRequestf(t, "GET", "/api/v1/orgs/%s", org.UserName).AddTokenAuth(token) + resp = MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiOrg) + assert.EqualValues(t, org.UserName, apiOrg.Name) + + t.Run("CheckPermission", func(t *testing.T) { // Check owner team permission ownerTeam, _ := org_model.GetOwnerTeam(db.DefaultContext, apiOrg.ID) - for _, ut := range unit_model.AllRepoUnitTypes { up := perm.AccessModeOwner if ut == unit_model.TypeExternalTracker || ut == unit_model.TypeExternalWiki { @@ -71,25 +76,10 @@ func TestAPIOrgCreate(t *testing.T) { AccessMode: up, }) } + }) - req = NewRequestf(t, "GET", "/api/v1/orgs/%s", org.UserName). - AddTokenAuth(token) - resp = MakeRequest(t, req, http.StatusOK) - DecodeJSON(t, resp, &apiOrg) - assert.EqualValues(t, org.UserName, apiOrg.Name) - - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", org.UserName). - AddTokenAuth(token) - resp = MakeRequest(t, req, http.StatusOK) - - var repos []*api.Repository - DecodeJSON(t, resp, &repos) - for _, repo := range repos { - assert.False(t, repo.Private) - } - - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", org.UserName). - AddTokenAuth(token) + t.Run("CheckMembers", func(t *testing.T) { + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", org.UserName).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) // user1 on this org is public @@ -98,76 +88,89 @@ func TestAPIOrgCreate(t *testing.T) { assert.Len(t, users, 1) assert.EqualValues(t, "user1", users[0].UserName) }) + + t.Run("RenameOrg", func(t *testing.T) { + req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/user1_org/rename", &api.RenameOrgOption{ + NewName: "renamed_org", + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNoContent) + unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "renamed_org"}) + org.UserName = "renamed_org" // update the variable so the following tests could still use it + }) + + t.Run("ListRepos", func(t *testing.T) { + // FIXME: this test is wrong, there is no repository at all, so the for-loop is empty + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", org.UserName).AddTokenAuth(token) + resp = MakeRequest(t, req, http.StatusOK) + var repos []*api.Repository + DecodeJSON(t, resp, &repos) + for _, repo := range repos { + assert.False(t, repo.Private) + } + }) } func TestAPIOrgEdit(t *testing.T) { - onGiteaRun(t, func(*testing.T, *url.URL) { - session := loginUser(t, "user1") + defer tests.PrepareTestEnv(t)() + session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) - org := api.EditOrgOption{ - FullName: "Org3 organization new full name", - Description: "A new description", - Website: "https://try.gitea.io/new", - Location: "Beijing", - Visibility: "private", - } - req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). - AddTokenAuth(token) - resp := MakeRequest(t, req, http.StatusOK) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + org := api.EditOrgOption{ + FullName: "Org3 organization new full name", + Description: "A new description", + Website: "https://try.gitea.io/new", + Location: "Beijing", + Visibility: "private", + } + req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). + AddTokenAuth(token) + resp := MakeRequest(t, req, http.StatusOK) - var apiOrg api.Organization - DecodeJSON(t, resp, &apiOrg) + var apiOrg api.Organization + DecodeJSON(t, resp, &apiOrg) - assert.Equal(t, "org3", apiOrg.Name) - assert.Equal(t, org.FullName, apiOrg.FullName) - assert.Equal(t, org.Description, apiOrg.Description) - assert.Equal(t, org.Website, apiOrg.Website) - assert.Equal(t, org.Location, apiOrg.Location) - assert.Equal(t, org.Visibility, apiOrg.Visibility) - }) + assert.Equal(t, "org3", apiOrg.Name) + assert.Equal(t, org.FullName, apiOrg.FullName) + assert.Equal(t, org.Description, apiOrg.Description) + assert.Equal(t, org.Website, apiOrg.Website) + assert.Equal(t, org.Location, apiOrg.Location) + assert.Equal(t, org.Visibility, apiOrg.Visibility) } func TestAPIOrgEditBadVisibility(t *testing.T) { - onGiteaRun(t, func(*testing.T, *url.URL) { - session := loginUser(t, "user1") + defer tests.PrepareTestEnv(t)() + session := loginUser(t, "user1") - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) - org := api.EditOrgOption{ - FullName: "Org3 organization new full name", - Description: "A new description", - Website: "https://try.gitea.io/new", - Location: "Beijing", - Visibility: "badvisibility", - } - req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). - AddTokenAuth(token) - MakeRequest(t, req, http.StatusUnprocessableEntity) - }) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + org := api.EditOrgOption{ + FullName: "Org3 organization new full name", + Description: "A new description", + Website: "https://try.gitea.io/new", + Location: "Beijing", + Visibility: "badvisibility", + } + req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). + AddTokenAuth(token) + MakeRequest(t, req, http.StatusUnprocessableEntity) } func TestAPIOrgDeny(t *testing.T) { - onGiteaRun(t, func(*testing.T, *url.URL) { - setting.Service.RequireSignInView = true - defer func() { - setting.Service.RequireSignInView = false - }() + defer tests.PrepareTestEnv(t)() + defer test.MockVariableValue(&setting.Service.RequireSignInView, true)() - orgName := "user1_org" - req := NewRequestf(t, "GET", "/api/v1/orgs/%s", orgName) - MakeRequest(t, req, http.StatusNotFound) + orgName := "user1_org" + req := NewRequestf(t, "GET", "/api/v1/orgs/%s", orgName) + MakeRequest(t, req, http.StatusNotFound) - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", orgName) - MakeRequest(t, req, http.StatusNotFound) + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", orgName) + MakeRequest(t, req, http.StatusNotFound) - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", orgName) - MakeRequest(t, req, http.StatusNotFound) - }) + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", orgName) + MakeRequest(t, req, http.StatusNotFound) } func TestAPIGetAll(t *testing.T) { defer tests.PrepareTestEnv(t)() - token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrganization) // accessing with a token will return all orgs @@ -192,37 +195,36 @@ func TestAPIGetAll(t *testing.T) { } func TestAPIOrgSearchEmptyTeam(t *testing.T) { - onGiteaRun(t, func(*testing.T, *url.URL) { - token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) - orgName := "org_with_empty_team" + defer tests.PrepareTestEnv(t)() + token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) + orgName := "org_with_empty_team" - // create org - req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &api.CreateOrgOption{ - UserName: orgName, - }).AddTokenAuth(token) - MakeRequest(t, req, http.StatusCreated) + // create org + req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &api.CreateOrgOption{ + UserName: orgName, + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusCreated) - // create team with no member - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", orgName), &api.CreateTeamOption{ - Name: "Empty", - IncludesAllRepositories: true, - Permission: "read", - Units: []string{"repo.code", "repo.issues", "repo.ext_issues", "repo.wiki", "repo.pulls"}, - }).AddTokenAuth(token) - MakeRequest(t, req, http.StatusCreated) + // create team with no member + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", orgName), &api.CreateTeamOption{ + Name: "Empty", + IncludesAllRepositories: true, + Permission: "read", + Units: []string{"repo.code", "repo.issues", "repo.ext_issues", "repo.wiki", "repo.pulls"}, + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusCreated) - // case-insensitive search for teams that have no members - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/orgs/%s/teams/search?q=%s", orgName, "empty")). - AddTokenAuth(token) - resp := MakeRequest(t, req, http.StatusOK) - data := struct { - Ok bool - Data []*api.Team - }{} - DecodeJSON(t, resp, &data) - assert.True(t, data.Ok) - if assert.Len(t, data.Data, 1) { - assert.EqualValues(t, "Empty", data.Data[0].Name) - } - }) + // case-insensitive search for teams that have no members + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/orgs/%s/teams/search?q=%s", orgName, "empty")). + AddTokenAuth(token) + resp := MakeRequest(t, req, http.StatusOK) + data := struct { + Ok bool + Data []*api.Team + }{} + DecodeJSON(t, resp, &data) + assert.True(t, data.Ok) + if assert.Len(t, data.Data, 1) { + assert.EqualValues(t, "Empty", data.Data[0].Name) + } } From 47bf8363102b95a240fc6a571d608567ff6b212a Mon Sep 17 00:00:00 2001 From: Typed SIGTERM Date: Sat, 1 Feb 2025 22:08:32 +0800 Subject: [PATCH 043/655] Update feishu icon (#33470) --- public/assets/img/feishu.png | Bin 1982 -> 0 bytes public/assets/img/svg/gitea-feishu.svg | 1 + templates/shared/webhook/icon.tmpl | 2 +- web_src/svg/gitea-feishu.svg | 1 + 4 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 public/assets/img/feishu.png create mode 100644 public/assets/img/svg/gitea-feishu.svg create mode 100644 web_src/svg/gitea-feishu.svg diff --git a/public/assets/img/feishu.png b/public/assets/img/feishu.png deleted file mode 100644 index 2c3ab744136a1be5d928be6780489da5ecf19b4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1982 zcmY*ZdoNb*Kb7AieNr!nQzLU?QM+JXd!eTqShRpQGPsUGAI%FN3VeqSj`acO$3dzz>cdQS14^3WrZ>#&6ZRC*5oMbH zq7?-fPQ%c*_YCAN94P9Pf0W^$`)AT>XUp28v;mYO<-?XBix|-H@4ANw zx++1?`Aa2675E5%QMWVTBCBjRV`<{7r8jZ42Mh=hyQYggC)gpy z$TJ^#7NTQR{tXEyymWTg{c*d=eqdCarYXMH1A`52<3kXEM@hK;(}U3U9=ghHBy_-=sbS@j4q#L~`!eaCuh5G3Si;+XpSdv#+so^=9quWo zqjH9P$6Y)yckE83{MiKmR@rE!9i$B(Kd)g;DdvQ2zoxk$uZzID^>}EUlslV zGJ=p4B!F2>)3T@lrXA>|#LBJH8n}p+|;L1=_Jno8t(+C{p zKt?OnRd2>uY*1LgE$EQrVVI+&JkNA?MqhiW+QPXq>Et9+UECJ&*JkZi%a*AAp*(L^ zDw&)Ri^g~y_TT`smqBlBtf?w4c>etHqtt7m!B+zV&mTW}*xA|9!NJbXeD^NG)-9V2 z4GmVWQp~HXtIW!#a10ZR1cDJBclal}ub08->S}LmZvOu5Yh4|UR{N=@x~i(Ovf};Q z!q=}}7QD!zQnNEN($gQ@zn_?x5EB!9n?xc7UA}ZN;QTp%UmtHTFHetCe;+&QcG$(m z&eqaw_io}Y!cNnzn+)|gXlt+4S{89&P+P z;f;wUO+U2N{5}}DnC*n zt{(l;IuoCpdUfoz(N~sBBfSFVZi`()dBtFy$b1lDJQTjHY_SDP*{a4vL@V^GR64x7 z@@hg43r{Zb=|2unjqSOoie;_;dd1Q2`JNpyjOVc;aPfK=ZRudka zw0~0Z%8X@hU{Zg8XHH7`VDK^RM5(~WIGK*phCP%o@+F`0u5{CQ1@%{{H+9s#A9bA7z+c$fW~IJX)}d^x$j(_! zAZFuE_DiWF{f2&e<#Ltguwa`<61wHn2(wK>)8>?<~dHRQ1uqIw;#6}4uoj;3mU-$M*(ey!DdCu}_3I>YPtfMDlw4cy9LyKgaP$&oj@ zw8Z=-N0lSiizywNCPd%IWs&*5DlJ@VFufIdCZ}UMzASR1<(ig}%iibVUNPCNs#|;~ z=TGk&i{8vjayr=ZYTy>vhbiDwh?|b2 zsNX9htLajV$PQW-F##^BIqmN(65kib-IeULSj1j9c$&0e++bjDrt7@Q$)|eNe$=@^ zFCRtcEFk5u>gP% \ No newline at end of file diff --git a/templates/shared/webhook/icon.tmpl b/templates/shared/webhook/icon.tmpl index 0f80787c57..245ed16505 100644 --- a/templates/shared/webhook/icon.tmpl +++ b/templates/shared/webhook/icon.tmpl @@ -17,7 +17,7 @@ {{else if eq .HookType "msteams"}} {{else if eq .HookType "feishu"}} - + {{svg "gitea-feishu" $size "img"}} {{else if eq .HookType "matrix"}} {{svg "gitea-matrix" $size "img"}} {{else if eq .HookType "wechatwork"}} diff --git a/web_src/svg/gitea-feishu.svg b/web_src/svg/gitea-feishu.svg new file mode 100644 index 0000000000..57941978d1 --- /dev/null +++ b/web_src/svg/gitea-feishu.svg @@ -0,0 +1 @@ + From 9cd88ef8c79005716de0f4ebc5bda2ee1e193333 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sun, 2 Feb 2025 00:33:31 +0000 Subject: [PATCH 044/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_fr-FR.ini | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index a5558eebb0..bf179a5931 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -1345,6 +1345,8 @@ editor.new_branch_name_desc=Nouveau nom de la branche… editor.cancel=Annuler editor.filename_cannot_be_empty=Le nom de fichier ne peut être vide. editor.filename_is_invalid=Le nom du fichier est invalide : "%s". +editor.commit_email=Courriel de la révision +editor.invalid_commit_email=Le courriel pour la révision n’est pas valide. editor.branch_does_not_exist=La branche "%s" n'existe pas dans ce dépôt. editor.branch_already_exists=La branche "%s" existe déjà dans ce dépôt. editor.directory_is_a_file=Le nom de dossier "%s" est déjà utilisé comme nom de fichier dans ce dépôt. @@ -1562,12 +1564,12 @@ issues.action_assignee=Assigné à issues.action_assignee_no_select=Pas d'assignataire issues.action_check=Cocher/Décocher issues.action_check_all=Cocher/Décocher tous les éléments -issues.opened_by=créé %[1]s par %[3]s -pulls.merged_by=par %[3]s fusionné %[1]s. -pulls.merged_by_fake=par %[2]s fusionné %[1]s. -issues.closed_by=de %[3]s, clôt %[1]s -issues.opened_by_fake=%[1]s ouvert par %[2]s -issues.closed_by_fake=de %[2]s, clôt %[1]s +issues.opened_by=ouvert(e) par %[3]s %[1]s +pulls.merged_by=par %[3]s a été fusionnée %[1]s +pulls.merged_by_fake=par %[2]s a été fusionnée %[1]s +issues.closed_by=par %[3]s a été fermé(e) %[1]s +issues.opened_by_fake=ouvert(e) par %[2]s %[1]s +issues.closed_by_fake=par %[2]s a été fermé(e) %[1]s issues.previous=Précédent issues.next=Suivant issues.open_title=Ouvert @@ -1735,8 +1737,8 @@ issues.dependency.added_dependency=`a créé une dépendance %s.` issues.dependency.removed_dependency=`a supprimé une dépendance %s.` issues.dependency.pr_closing_blockedby=La fermeture de cette demande d’ajout est bloquée par les tickets suivants issues.dependency.issue_closing_blockedby=La fermeture de ce ticket est bloquée par les tickets suivants -issues.dependency.issue_close_blocks=Cette demande d'ajout empêche la clôture des tickets suivants -issues.dependency.pr_close_blocks=Cette demande d'ajout empêche la clôture des tickets suivants +issues.dependency.issue_close_blocks=Ce ticket empêche la clôture des tickets suivants +issues.dependency.pr_close_blocks=Cette demande d’ajout empêche la clôture des tickets suivants issues.dependency.issue_close_blocked=Vous devez fermer tous les tickets qui bloquent ce ticket avant de pouvoir le fermer. issues.dependency.issue_batch_close_blocked=Impossible de fermer tous les tickets que vous avez choisis, car le ticket #%d a toujours des dépendances ouvertes. issues.dependency.pr_close_blocked=Vous devez fermer tous les tickets qui bloquent cette demande d'ajout avant de pouvoir la fusionner. From fcfe1fb0fcca15a4c8b5bcc30a9b5f4907074699 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sun, 2 Feb 2025 04:39:01 +0100 Subject: [PATCH 045/655] actions view: move loading of task attributes etc... into own func (#31494) just a smal refactor to make the function length smaler ... and code more reusable in the future --- routers/web/repo/actions/view.go | 162 +++++++++++++++++-------------- 1 file changed, 88 insertions(+), 74 deletions(-) diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index e5d83960b8..e9321d0a8a 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -281,86 +281,100 @@ func ViewPost(ctx *context_module.Context) { resp.State.CurrentJob.Steps = make([]*ViewJobStep, 0) // marshal to '[]' instead fo 'null' in json resp.Logs.StepsLog = make([]*ViewStepLog, 0) // marshal to '[]' instead fo 'null' in json if task != nil { - steps := actions.FullSteps(task) - - for _, v := range steps { - resp.State.CurrentJob.Steps = append(resp.State.CurrentJob.Steps, &ViewJobStep{ - Summary: v.Name, - Duration: v.Duration().String(), - Status: v.Status.String(), - }) - } - - for _, cursor := range req.LogCursors { - if !cursor.Expanded { - continue - } - - step := steps[cursor.Step] - - // if task log is expired, return a consistent log line - if task.LogExpired { - if cursor.Cursor == 0 { - resp.Logs.StepsLog = append(resp.Logs.StepsLog, &ViewStepLog{ - Step: cursor.Step, - Cursor: 1, - Lines: []*ViewStepLogLine{ - { - Index: 1, - Message: ctx.Locale.TrString("actions.runs.expire_log_message"), - // Timestamp doesn't mean anything when the log is expired. - // Set it to the task's updated time since it's probably the time when the log has expired. - Timestamp: float64(task.Updated.AsTime().UnixNano()) / float64(time.Second), - }, - }, - Started: int64(step.Started), - }) - } - continue - } - - logLines := make([]*ViewStepLogLine, 0) // marshal to '[]' instead fo 'null' in json - - index := step.LogIndex + cursor.Cursor - validCursor := cursor.Cursor >= 0 && - // !(cursor.Cursor < step.LogLength) when the frontend tries to fetch next line before it's ready. - // So return the same cursor and empty lines to let the frontend retry. - cursor.Cursor < step.LogLength && - // !(index < task.LogIndexes[index]) when task data is older than step data. - // It can be fixed by making sure write/read tasks and steps in the same transaction, - // but it's easier to just treat it as fetching the next line before it's ready. - index < int64(len(task.LogIndexes)) - - if validCursor { - length := step.LogLength - cursor.Cursor - offset := task.LogIndexes[index] - logRows, err := actions.ReadLogs(ctx, task.LogInStorage, task.LogFilename, offset, length) - if err != nil { - ctx.ServerError("actions.ReadLogs", err) - return - } - - for i, row := range logRows { - logLines = append(logLines, &ViewStepLogLine{ - Index: cursor.Cursor + int64(i) + 1, // start at 1 - Message: row.Content, - Timestamp: float64(row.Time.AsTime().UnixNano()) / float64(time.Second), - }) - } - } - - resp.Logs.StepsLog = append(resp.Logs.StepsLog, &ViewStepLog{ - Step: cursor.Step, - Cursor: cursor.Cursor + int64(len(logLines)), - Lines: logLines, - Started: int64(step.Started), - }) + steps, logs, err := convertToViewModel(ctx, req.LogCursors, task) + if err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return } + resp.State.CurrentJob.Steps = append(resp.State.CurrentJob.Steps, steps...) + resp.Logs.StepsLog = append(resp.Logs.StepsLog, logs...) } ctx.JSON(http.StatusOK, resp) } +func convertToViewModel(ctx *context_module.Context, cursors []LogCursor, task *actions_model.ActionTask) ([]*ViewJobStep, []*ViewStepLog, error) { + var viewJobs []*ViewJobStep + var logs []*ViewStepLog + + steps := actions.FullSteps(task) + + for _, v := range steps { + viewJobs = append(viewJobs, &ViewJobStep{ + Summary: v.Name, + Duration: v.Duration().String(), + Status: v.Status.String(), + }) + } + + for _, cursor := range cursors { + if !cursor.Expanded { + continue + } + + step := steps[cursor.Step] + + // if task log is expired, return a consistent log line + if task.LogExpired { + if cursor.Cursor == 0 { + logs = append(logs, &ViewStepLog{ + Step: cursor.Step, + Cursor: 1, + Lines: []*ViewStepLogLine{ + { + Index: 1, + Message: ctx.Locale.TrString("actions.runs.expire_log_message"), + // Timestamp doesn't mean anything when the log is expired. + // Set it to the task's updated time since it's probably the time when the log has expired. + Timestamp: float64(task.Updated.AsTime().UnixNano()) / float64(time.Second), + }, + }, + Started: int64(step.Started), + }) + } + continue + } + + logLines := make([]*ViewStepLogLine, 0) // marshal to '[]' instead fo 'null' in json + + index := step.LogIndex + cursor.Cursor + validCursor := cursor.Cursor >= 0 && + // !(cursor.Cursor < step.LogLength) when the frontend tries to fetch next line before it's ready. + // So return the same cursor and empty lines to let the frontend retry. + cursor.Cursor < step.LogLength && + // !(index < task.LogIndexes[index]) when task data is older than step data. + // It can be fixed by making sure write/read tasks and steps in the same transaction, + // but it's easier to just treat it as fetching the next line before it's ready. + index < int64(len(task.LogIndexes)) + + if validCursor { + length := step.LogLength - cursor.Cursor + offset := task.LogIndexes[index] + logRows, err := actions.ReadLogs(ctx, task.LogInStorage, task.LogFilename, offset, length) + if err != nil { + return nil, nil, fmt.Errorf("actions.ReadLogs: %w", err) + } + + for i, row := range logRows { + logLines = append(logLines, &ViewStepLogLine{ + Index: cursor.Cursor + int64(i) + 1, // start at 1 + Message: row.Content, + Timestamp: float64(row.Time.AsTime().UnixNano()) / float64(time.Second), + }) + } + } + + logs = append(logs, &ViewStepLog{ + Step: cursor.Step, + Cursor: cursor.Cursor + int64(len(logLines)), + Lines: logLines, + Started: int64(step.Started), + }) + } + + return viewJobs, logs, nil +} + // Rerun will rerun jobs in the given run // If jobIndexStr is a blank string, it means rerun all jobs func Rerun(ctx *context_module.Context) { From aec0b7ec3409b815bedd42e79782b896e276ff26 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 1 Feb 2025 22:40:39 -0800 Subject: [PATCH 046/655] Update .changelog file to add performance label group (#33472) --- .changelog.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.changelog.yml b/.changelog.yml index bfdee0c0ca..a7df8779de 100644 --- a/.changelog.yml +++ b/.changelog.yml @@ -22,20 +22,25 @@ groups: name: FEATURES labels: - type/feature - - - name: API - labels: - - modifies/api - name: ENHANCEMENTS labels: - type/enhancement - - type/refactoring - - topic/ui + - + name: PERFORMANCE + labels: + - performance/memory + - performance/speed + - performance/bigrepo + - performance/cpu - name: BUGFIXES labels: - type/bug + - + name: API + labels: + - modifies/api - name: TESTING labels: From 869f8fdbe4b0626a5f8ca3aabf84755cf9ddb5a5 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 2 Feb 2025 22:48:19 +0800 Subject: [PATCH 047/655] Skip deletion error for action artifacts (#33476) --- services/actions/cleanup.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/services/actions/cleanup.go b/services/actions/cleanup.go index 1223ebcab6..ee1d167713 100644 --- a/services/actions/cleanup.go +++ b/services/actions/cleanup.go @@ -52,9 +52,9 @@ func cleanExpiredArtifacts(taskCtx context.Context) error { } if err := storage.ActionsArtifacts.Delete(artifact.StoragePath); err != nil { log.Error("Cannot delete artifact %d: %v", artifact.ID, err) - continue + // go on } - log.Info("Artifact %d set expired", artifact.ID) + log.Info("Artifact %d is deleted (due to expiration)", artifact.ID) } return nil } @@ -76,9 +76,9 @@ func cleanNeedDeleteArtifacts(taskCtx context.Context) error { } if err := storage.ActionsArtifacts.Delete(artifact.StoragePath); err != nil { log.Error("Cannot delete artifact %d: %v", artifact.ID, err) - continue + // go on } - log.Info("Artifact %d set deleted", artifact.ID) + log.Info("Artifact %d is deleted (due to pending deletion)", artifact.ID) } if len(artifacts) < deleteArtifactBatchSize { log.Debug("No more artifacts pending deletion") @@ -103,8 +103,7 @@ func CleanupLogs(ctx context.Context) error { for _, task := range tasks { if err := actions_module.RemoveLogs(ctx, task.LogInStorage, task.LogFilename); err != nil { log.Error("Failed to remove log %s (in storage %v) of task %v: %v", task.LogFilename, task.LogInStorage, task.ID, err) - // do not return error here, continue to next task - continue + // do not return error here, go on } task.LogIndexes = nil // clear log indexes since it's a heavy field task.LogExpired = true From 34692a20b12e1d8fe094a474fb3a00d7f02a2b45 Mon Sep 17 00:00:00 2001 From: K Kovacs Date: Sun, 2 Feb 2025 18:51:12 +0100 Subject: [PATCH 048/655] Worktime tracking for the organization level (#19808) Dear Gitea team, first of all, thanks for the great work you're doing with this project. I'm planning to introduce Gitea at a client site, and noticed that while there is time recording, there are no project-manager-friendly reports to actually make use of that data, as were also mentioned by others in #4870 #8684 and #13531. Since I had a little time last weekend, I had put together something that I hope to be a useful contribution to this great project (while of course useful for me too). This PR adds a new "Worktime" tab to the Organisation level. There is a date range selector (by default set to the current month), and there are three possible views: - by repository, - by milestone, and - by team member. Happy to receive any feedback! There are several possible future improvements of course (predefined date ranges, charts, a member time sheet, matrix of repos/members, etc) but I hope that even in this relatively simple state this would be useful to lots of people. Screen Shot 2022-05-25 at 22 12 58 Keep up the good work! Kristof --------- Co-authored-by: user Co-authored-by: wxiaoguang --- models/organization/org_worktime.go | 103 ++++++ modules/templates/helper.go | 2 +- modules/util/sec_to_time.go | 10 +- modules/util/sec_to_time_test.go | 3 + options/locale/locale_en-US.ini | 11 + routers/web/org/worktime.go | 74 +++++ routers/web/web.go | 2 + services/context/org.go | 2 + templates/org/menu.tmpl | 5 + templates/org/worktime.tmpl | 40 +++ templates/org/worktime/table_members.tmpl | 16 + templates/org/worktime/table_milestones.tmpl | 28 ++ templates/org/worktime/table_repos.tmpl | 16 + templates/repo/issue/filters.tmpl | 2 +- templates/repo/issue/list.tmpl | 2 +- templates/repo/issue/milestone_issues.tmpl | 2 +- templates/repo/issue/milestones.tmpl | 2 +- .../issue/sidebar/stopwatch_timetracker.tmpl | 4 +- .../repo/issue/view_content/comments.tmpl | 6 +- templates/shared/issuelist.tmpl | 2 +- templates/user/dashboard/milestones.tmpl | 2 +- tests/integration/org_worktime_test.go | 293 ++++++++++++++++++ 22 files changed, 612 insertions(+), 15 deletions(-) create mode 100644 models/organization/org_worktime.go create mode 100644 routers/web/org/worktime.go create mode 100644 templates/org/worktime.tmpl create mode 100644 templates/org/worktime/table_members.tmpl create mode 100644 templates/org/worktime/table_milestones.tmpl create mode 100644 templates/org/worktime/table_repos.tmpl create mode 100644 tests/integration/org_worktime_test.go diff --git a/models/organization/org_worktime.go b/models/organization/org_worktime.go new file mode 100644 index 0000000000..7b57182a8a --- /dev/null +++ b/models/organization/org_worktime.go @@ -0,0 +1,103 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package organization + +import ( + "sort" + + "code.gitea.io/gitea/models/db" + + "xorm.io/builder" +) + +type WorktimeSumByRepos struct { + RepoName string + SumTime int64 +} + +func GetWorktimeByRepos(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByRepos, err error) { + err = db.GetEngine(db.DefaultContext). + Select("repository.name AS repo_name, SUM(tracked_time.time) AS sum_time"). + Table("tracked_time"). + Join("INNER", "issue", "tracked_time.issue_id = issue.id"). + Join("INNER", "repository", "issue.repo_id = repository.id"). + Where(builder.Eq{"repository.owner_id": org.ID}). + And(builder.Eq{"tracked_time.deleted": false}). + And(builder.Gte{"tracked_time.created_unix": unitFrom}). + And(builder.Lte{"tracked_time.created_unix": unixTo}). + GroupBy("repository.name"). + OrderBy("repository.name"). + Find(&results) + return results, err +} + +type WorktimeSumByMilestones struct { + RepoName string + MilestoneName string + MilestoneID int64 + MilestoneDeadline int64 + SumTime int64 + HideRepoName bool +} + +func GetWorktimeByMilestones(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByMilestones, err error) { + err = db.GetEngine(db.DefaultContext). + Select("repository.name AS repo_name, milestone.name AS milestone_name, milestone.id AS milestone_id, milestone.deadline_unix as milestone_deadline, SUM(tracked_time.time) AS sum_time"). + Table("tracked_time"). + Join("INNER", "issue", "tracked_time.issue_id = issue.id"). + Join("INNER", "repository", "issue.repo_id = repository.id"). + Join("LEFT", "milestone", "issue.milestone_id = milestone.id"). + Where(builder.Eq{"repository.owner_id": org.ID}). + And(builder.Eq{"tracked_time.deleted": false}). + And(builder.Gte{"tracked_time.created_unix": unitFrom}). + And(builder.Lte{"tracked_time.created_unix": unixTo}). + GroupBy("repository.name, milestone.name, milestone.deadline_unix, milestone.id"). + OrderBy("repository.name, milestone.deadline_unix, milestone.id"). + Find(&results) + + // TODO: pgsql: NULL values are sorted last in default ascending order, so we need to sort them manually again. + sort.Slice(results, func(i, j int) bool { + if results[i].RepoName != results[j].RepoName { + return results[i].RepoName < results[j].RepoName + } + if results[i].MilestoneDeadline != results[j].MilestoneDeadline { + return results[i].MilestoneDeadline < results[j].MilestoneDeadline + } + return results[i].MilestoneID < results[j].MilestoneID + }) + + // Show only the first RepoName, for nicer output. + prevRepoName := "" + for i := 0; i < len(results); i++ { + res := &results[i] + res.MilestoneDeadline = 0 // clear the deadline because we do not really need it + if prevRepoName == res.RepoName { + res.HideRepoName = true + } + prevRepoName = res.RepoName + } + return results, err +} + +type WorktimeSumByMembers struct { + UserName string + SumTime int64 +} + +func GetWorktimeByMembers(org *Organization, unitFrom, unixTo int64) (results []WorktimeSumByMembers, err error) { + err = db.GetEngine(db.DefaultContext). + Select("`user`.name AS user_name, SUM(tracked_time.time) AS sum_time"). + Table("tracked_time"). + Join("INNER", "issue", "tracked_time.issue_id = issue.id"). + Join("INNER", "repository", "issue.repo_id = repository.id"). + Join("INNER", "`user`", "tracked_time.user_id = `user`.id"). + Where(builder.Eq{"repository.owner_id": org.ID}). + And(builder.Eq{"tracked_time.deleted": false}). + And(builder.Gte{"tracked_time.created_unix": unitFrom}). + And(builder.Lte{"tracked_time.created_unix": unixTo}). + GroupBy("`user`.name"). + OrderBy("sum_time DESC"). + Find(&results) + return results, err +} diff --git a/modules/templates/helper.go b/modules/templates/helper.go index a2cc166de9..c0b0ddc97d 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -69,7 +69,7 @@ func NewFuncMap() template.FuncMap { // time / number / format "FileSize": base.FileSize, "CountFmt": countFmt, - "Sec2Time": util.SecToHours, + "Sec2Hour": util.SecToHours, "TimeEstimateString": timeEstimateString, diff --git a/modules/util/sec_to_time.go b/modules/util/sec_to_time.go index 73667d723e..646f33c82a 100644 --- a/modules/util/sec_to_time.go +++ b/modules/util/sec_to_time.go @@ -11,16 +11,20 @@ import ( // SecToHours converts an amount of seconds to a human-readable hours string. // This is stable for planning and managing timesheets. // Here it only supports hours and minutes, because a work day could contain 6 or 7 or 8 hours. +// If the duration is less than 1 minute, it will be shown as seconds. func SecToHours(durationVal any) string { - duration, _ := ToInt64(durationVal) - hours := duration / 3600 - minutes := (duration / 60) % 60 + seconds, _ := ToInt64(durationVal) + hours := seconds / 3600 + minutes := (seconds / 60) % 60 formattedTime := "" formattedTime = formatTime(hours, "hour", formattedTime) formattedTime = formatTime(minutes, "minute", formattedTime) // The formatTime() function always appends a space at the end. This will be trimmed + if formattedTime == "" && seconds > 0 { + formattedTime = formatTime(seconds, "second", "") + } return strings.TrimRight(formattedTime, " ") } diff --git a/modules/util/sec_to_time_test.go b/modules/util/sec_to_time_test.go index 71a8801d4f..b67926bbcf 100644 --- a/modules/util/sec_to_time_test.go +++ b/modules/util/sec_to_time_test.go @@ -22,4 +22,7 @@ func TestSecToHours(t *testing.T) { assert.Equal(t, "156 hours 30 minutes", SecToHours(6*day+12*hour+30*minute+18*second)) assert.Equal(t, "98 hours 16 minutes", SecToHours(4*day+2*hour+16*minute+58*second)) assert.Equal(t, "672 hours", SecToHours(4*7*day)) + assert.Equal(t, "1 second", SecToHours(1)) + assert.Equal(t, "2 seconds", SecToHours(2)) + assert.Equal(t, "", SecToHours(nil)) // old behavior, empty means no output } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 68b7fa2f9f..886628e4ff 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -54,6 +54,7 @@ webauthn_reload = Reload repository = Repository organization = Organization mirror = Mirror +issue_milestone = Milestone new_repo = New Repository new_migrate = New Migration new_mirror = New Mirror @@ -1253,6 +1254,7 @@ labels = Labels org_labels_desc = Organization level labels that can be used with all repositories under this organization org_labels_desc_manage = manage +milestone = Milestone milestones = Milestones commits = Commits commit = Commit @@ -2876,6 +2878,15 @@ view_as_role = View as: %s view_as_public_hint = You are viewing the README as a public user. view_as_member_hint = You are viewing the README as a member of this organization. +worktime = Worktime +worktime.date_range_start = Start date +worktime.date_range_end = End date +worktime.query = Query +worktime.time = Time +worktime.by_repositories = By repositories +worktime.by_milestones = By milestones +worktime.by_members = By members + [admin] maintenance = Maintenance dashboard = Dashboard diff --git a/routers/web/org/worktime.go b/routers/web/org/worktime.go new file mode 100644 index 0000000000..2336984825 --- /dev/null +++ b/routers/web/org/worktime.go @@ -0,0 +1,74 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package org + +import ( + "net/http" + "time" + + "code.gitea.io/gitea/models/organization" + "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/services/context" +) + +const tplByRepos templates.TplName = "org/worktime" + +// parseOrgTimes contains functionality that is required in all these functions, +// like parsing the date from the request, setting default dates, etc. +func parseOrgTimes(ctx *context.Context) (unixFrom, unixTo int64) { + rangeFrom := ctx.FormString("from") + rangeTo := ctx.FormString("to") + if rangeFrom == "" { + rangeFrom = time.Now().Format("2006-01") + "-01" // defaults to start of current month + } + if rangeTo == "" { + rangeTo = time.Now().Format("2006-01-02") // defaults to today + } + + ctx.Data["RangeFrom"] = rangeFrom + ctx.Data["RangeTo"] = rangeTo + + timeFrom, err := time.Parse("2006-01-02", rangeFrom) + if err != nil { + ctx.ServerError("time.Parse", err) + } + timeTo, err := time.Parse("2006-01-02", rangeTo) + if err != nil { + ctx.ServerError("time.Parse", err) + } + unixFrom = timeFrom.Unix() + unixTo = timeTo.Add(1440*time.Minute - 1*time.Second).Unix() // humans expect that we include the ending day too + return unixFrom, unixTo +} + +func Worktime(ctx *context.Context) { + ctx.Data["PageIsOrgTimes"] = true + + unixFrom, unixTo := parseOrgTimes(ctx) + if ctx.Written() { + return + } + + worktimeBy := ctx.FormString("by") + ctx.Data["WorktimeBy"] = worktimeBy + + var worktimeSumResult any + var err error + if worktimeBy == "milestones" { + worktimeSumResult, err = organization.GetWorktimeByMilestones(ctx.Org.Organization, unixFrom, unixTo) + ctx.Data["WorktimeByMilestones"] = true + } else if worktimeBy == "members" { + worktimeSumResult, err = organization.GetWorktimeByMembers(ctx.Org.Organization, unixFrom, unixTo) + ctx.Data["WorktimeByMembers"] = true + } else /* by repos */ { + worktimeSumResult, err = organization.GetWorktimeByRepos(ctx.Org.Organization, unixFrom, unixTo) + ctx.Data["WorktimeByRepos"] = true + } + if err != nil { + ctx.ServerError("GetWorktime", err) + return + } + ctx.Data["WorktimeSumResult"] = worktimeSumResult + ctx.HTML(http.StatusOK, tplByRepos) +} diff --git a/routers/web/web.go b/routers/web/web.go index bbf257a493..daba9887e8 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -913,6 +913,8 @@ func registerRoutes(m *web.Router) { m.Post("/teams/{team}/edit", web.Bind(forms.CreateTeamForm{}), org.EditTeamPost) m.Post("/teams/{team}/delete", org.DeleteTeam) + m.Get("/worktime", context.OrgAssignment(false, true), org.Worktime) + m.Group("/settings", func() { m.Combo("").Get(org.Settings). Post(web.Bind(forms.UpdateOrgSettingForm{}), org.SettingsPost) diff --git a/services/context/org.go b/services/context/org.go index be87cef7a3..f4597a4ce1 100644 --- a/services/context/org.go +++ b/services/context/org.go @@ -63,6 +63,7 @@ func GetOrganizationByParams(ctx *Context) { } // HandleOrgAssignment handles organization assignment +// args: requireMember, requireOwner, requireTeamMember, requireTeamAdmin func HandleOrgAssignment(ctx *Context, args ...bool) { var ( requireMember bool @@ -269,6 +270,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { } // OrgAssignment returns a middleware to handle organization assignment +// args: requireMember, requireOwner, requireTeamMember, requireTeamAdmin func OrgAssignment(args ...bool) func(ctx *Context) { return func(ctx *Context) { HandleOrgAssignment(ctx, args...) diff --git a/templates/org/menu.tmpl b/templates/org/menu.tmpl index 4a8aee68a7..2d3af2d559 100644 --- a/templates/org/menu.tmpl +++ b/templates/org/menu.tmpl @@ -45,6 +45,11 @@ {{end}} {{if .IsOrganizationOwner}} + + {{svg "octicon-clock"}} {{ctx.Locale.Tr "org.worktime"}} + + {{end}} + {{if .IsOrganizationOwner}} {{svg "octicon-tools"}} {{ctx.Locale.Tr "repo.settings"}} diff --git a/templates/org/worktime.tmpl b/templates/org/worktime.tmpl new file mode 100644 index 0000000000..5d99998129 --- /dev/null +++ b/templates/org/worktime.tmpl @@ -0,0 +1,40 @@ +{{template "base/head" .}} +
+ {{template "org/header" .}} +
+
+
+
+ +
+ + +
+
+ + +
+ +
+
+
+ + {{if .WorktimeByRepos}} + {{template "org/worktime/table_repos" dict "Org" .Org "WorktimeSumResult" .WorktimeSumResult}} + {{else if .WorktimeByMilestones}} + {{template "org/worktime/table_milestones" dict "Org" .Org "WorktimeSumResult" .WorktimeSumResult}} + {{else if .WorktimeByMembers}} + {{template "org/worktime/table_members" dict "Org" .Org "WorktimeSumResult" .WorktimeSumResult}} + {{end}} +
+
+
+
+{{template "base/footer" .}} diff --git a/templates/org/worktime/table_members.tmpl b/templates/org/worktime/table_members.tmpl new file mode 100644 index 0000000000..a59d1941d8 --- /dev/null +++ b/templates/org/worktime/table_members.tmpl @@ -0,0 +1,16 @@ + + + + + + + + + {{range $.WorktimeSumResult}} + + + + + {{end}} + +
{{ctx.Locale.Tr "org.members.member"}}{{ctx.Locale.Tr "org.worktime.time"}}
{{svg "octicon-person"}} {{.UserName}}{{svg "octicon-clock"}} {{.SumTime | Sec2Hour}}
diff --git a/templates/org/worktime/table_milestones.tmpl b/templates/org/worktime/table_milestones.tmpl new file mode 100644 index 0000000000..6ef9289e56 --- /dev/null +++ b/templates/org/worktime/table_milestones.tmpl @@ -0,0 +1,28 @@ + + + + + + + + + + {{range $.WorktimeSumResult}} + + + + + + {{end}} + +
{{ctx.Locale.Tr "repository"}}{{ctx.Locale.Tr "repo.milestone"}}{{ctx.Locale.Tr "org.worktime.time"}}
+ {{if not .HideRepoName}} + {{svg "octicon-repo"}} {{.RepoName}} + {{end}} + + {{if .MilestoneName}} + {{svg "octicon-milestone"}} {{.MilestoneName}} + {{else}} + - + {{end}} + {{svg "octicon-clock"}} {{.SumTime | Sec2Hour}}
diff --git a/templates/org/worktime/table_repos.tmpl b/templates/org/worktime/table_repos.tmpl new file mode 100644 index 0000000000..eaa085df0c --- /dev/null +++ b/templates/org/worktime/table_repos.tmpl @@ -0,0 +1,16 @@ + + + + + + + + + {{range $.WorktimeSumResult}} + + + + + {{end}} + +
{{ctx.Locale.Tr "repository"}}{{ctx.Locale.Tr "org.worktime.time"}}
{{svg "octicon-repo"}} {{.RepoName}}{{svg "octicon-clock"}} {{.SumTime | Sec2Hour}}
diff --git a/templates/repo/issue/filters.tmpl b/templates/repo/issue/filters.tmpl index 06e7c1aa6c..409ec876e6 100644 --- a/templates/repo/issue/filters.tmpl +++ b/templates/repo/issue/filters.tmpl @@ -9,7 +9,7 @@ {{end}} diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl index 01b610b39d..53d0eca171 100644 --- a/templates/repo/issue/list.tmpl +++ b/templates/repo/issue/list.tmpl @@ -40,7 +40,7 @@ {{end}} diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl index 4fc6057117..abb4e3290d 100644 --- a/templates/repo/issue/milestone_issues.tmpl +++ b/templates/repo/issue/milestone_issues.tmpl @@ -50,7 +50,7 @@ {{if .TotalTrackedTime}}
{{svg "octicon-clock"}} - {{.TotalTrackedTime | Sec2Time}} + {{.TotalTrackedTime | Sec2Hour}}
{{end}}
diff --git a/templates/repo/issue/milestones.tmpl b/templates/repo/issue/milestones.tmpl index 9515acfb8e..e7dfe08ee0 100644 --- a/templates/repo/issue/milestones.tmpl +++ b/templates/repo/issue/milestones.tmpl @@ -41,7 +41,7 @@ {{if .TotalTrackedTime}}
{{svg "octicon-clock"}} - {{.TotalTrackedTime|Sec2Time}} + {{.TotalTrackedTime|Sec2Hour}}
{{end}} {{if .UpdatedUnix}} diff --git a/templates/repo/issue/sidebar/stopwatch_timetracker.tmpl b/templates/repo/issue/sidebar/stopwatch_timetracker.tmpl index f107dc5ef5..d5ac6827ba 100644 --- a/templates/repo/issue/sidebar/stopwatch_timetracker.tmpl +++ b/templates/repo/issue/sidebar/stopwatch_timetracker.tmpl @@ -72,7 +72,7 @@ {{end}} {{if .WorkingUsers}}
- {{ctx.Locale.Tr "repo.issues.time_spent_from_all_authors" ($.Issue.TotalTrackedTime | Sec2Time)}} + {{ctx.Locale.Tr "repo.issues.time_spent_from_all_authors" ($.Issue.TotalTrackedTime | Sec2Hour)}}
{{range $user, $trackedtime := .WorkingUsers}}
@@ -82,7 +82,7 @@
{{template "shared/user/authorlink" $user}}
- {{$trackedtime|Sec2Time}} + {{$trackedtime|Sec2Hour}}
diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index c1ad64a118..f2f3d1c9cc 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -252,7 +252,7 @@ {{template "shared/user/authorlink" .Poster}} {{$timeStr := .RenderedContent}} {{/* compatibility with time comments made before v1.21 */}} - {{if not $timeStr}}{{$timeStr = .Content|Sec2Time}}{{end}} + {{if not $timeStr}}{{$timeStr = .Content|Sec2Hour}}{{end}} {{ctx.Locale.Tr "repo.issues.stop_tracking_history" $timeStr $createdStr}} {{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}} @@ -264,7 +264,7 @@ {{template "shared/user/authorlink" .Poster}} {{$timeStr := .RenderedContent}} {{/* compatibility with time comments made before v1.21 */}} - {{if not $timeStr}}{{$timeStr = .Content|Sec2Time}}{{end}} + {{if not $timeStr}}{{$timeStr = .Content|Sec2Hour}}{{end}} {{ctx.Locale.Tr "repo.issues.add_time_history" $timeStr $createdStr}} {{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}} @@ -506,7 +506,7 @@ {{/* compatibility with time comments made before v1.21 */}} {{.RenderedContent}} {{else}} - - {{.Content|Sec2Time}} + - {{.Content|Sec2Hour}} {{end}}
diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl index e8015b40ea..fe7f2fd8bf 100644 --- a/templates/shared/issuelist.tmpl +++ b/templates/shared/issuelist.tmpl @@ -28,7 +28,7 @@ {{if .TotalTrackedTime}}
{{svg "octicon-clock" 16}} - {{.TotalTrackedTime | Sec2Time}} + {{.TotalTrackedTime | Sec2Hour}}
{{end}}
diff --git a/templates/user/dashboard/milestones.tmpl b/templates/user/dashboard/milestones.tmpl index c0059d3cd4..7c1a69a6f5 100644 --- a/templates/user/dashboard/milestones.tmpl +++ b/templates/user/dashboard/milestones.tmpl @@ -100,7 +100,7 @@ {{if .TotalTrackedTime}}
{{svg "octicon-clock"}} - {{.TotalTrackedTime|Sec2Time}} + {{.TotalTrackedTime|Sec2Hour}}
{{end}} {{if .UpdatedUnix}} diff --git a/tests/integration/org_worktime_test.go b/tests/integration/org_worktime_test.go new file mode 100644 index 0000000000..fb5216be8d --- /dev/null +++ b/tests/integration/org_worktime_test.go @@ -0,0 +1,293 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration_test + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/organization" + "code.gitea.io/gitea/models/unittest" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestTimesByRepos tests TimesByRepos functionality +func testTimesByRepos(t *testing.T) { + kases := []struct { + name string + unixfrom int64 + unixto int64 + orgname int64 + expected []organization.WorktimeSumByRepos + }{ + { + name: "Full sum for org 1", + unixfrom: 0, + unixto: 9223372036854775807, + orgname: 1, + expected: []organization.WorktimeSumByRepos(nil), + }, + { + name: "Full sum for org 2", + unixfrom: 0, + unixto: 9223372036854775807, + orgname: 2, + expected: []organization.WorktimeSumByRepos{ + { + RepoName: "repo1", + SumTime: 4083, + }, + { + RepoName: "repo2", + SumTime: 75, + }, + }, + }, + { + name: "Simple time bound", + unixfrom: 946684801, + unixto: 946684802, + orgname: 2, + expected: []organization.WorktimeSumByRepos{ + { + RepoName: "repo1", + SumTime: 3662, + }, + }, + }, + { + name: "Both times inclusive", + unixfrom: 946684801, + unixto: 946684801, + orgname: 2, + expected: []organization.WorktimeSumByRepos{ + { + RepoName: "repo1", + SumTime: 3661, + }, + }, + }, + { + name: "Should ignore deleted", + unixfrom: 947688814, + unixto: 947688815, + orgname: 2, + expected: []organization.WorktimeSumByRepos{ + { + RepoName: "repo2", + SumTime: 71, + }, + }, + }, + } + + // Run test kases + for _, kase := range kases { + t.Run(kase.name, func(t *testing.T) { + org, err := organization.GetOrgByID(db.DefaultContext, kase.orgname) + assert.NoError(t, err) + results, err := organization.GetWorktimeByRepos(org, kase.unixfrom, kase.unixto) + assert.NoError(t, err) + assert.Equal(t, kase.expected, results) + }) + } +} + +// TestTimesByMilestones tests TimesByMilestones functionality +func testTimesByMilestones(t *testing.T) { + kases := []struct { + name string + unixfrom int64 + unixto int64 + orgname int64 + expected []organization.WorktimeSumByMilestones + }{ + { + name: "Full sum for org 1", + unixfrom: 0, + unixto: 9223372036854775807, + orgname: 1, + expected: []organization.WorktimeSumByMilestones(nil), + }, + { + name: "Full sum for org 2", + unixfrom: 0, + unixto: 9223372036854775807, + orgname: 2, + expected: []organization.WorktimeSumByMilestones{ + { + RepoName: "repo1", + MilestoneName: "", + MilestoneID: 0, + SumTime: 401, + HideRepoName: false, + }, + { + RepoName: "repo1", + MilestoneName: "milestone1", + MilestoneID: 1, + SumTime: 3682, + HideRepoName: true, + }, + { + RepoName: "repo2", + MilestoneName: "", + MilestoneID: 0, + SumTime: 75, + HideRepoName: false, + }, + }, + }, + { + name: "Simple time bound", + unixfrom: 946684801, + unixto: 946684802, + orgname: 2, + expected: []organization.WorktimeSumByMilestones{ + { + RepoName: "repo1", + MilestoneName: "milestone1", + MilestoneID: 1, + SumTime: 3662, + HideRepoName: false, + }, + }, + }, + { + name: "Both times inclusive", + unixfrom: 946684801, + unixto: 946684801, + orgname: 2, + expected: []organization.WorktimeSumByMilestones{ + { + RepoName: "repo1", + MilestoneName: "milestone1", + MilestoneID: 1, + SumTime: 3661, + HideRepoName: false, + }, + }, + }, + { + name: "Should ignore deleted", + unixfrom: 947688814, + unixto: 947688815, + orgname: 2, + expected: []organization.WorktimeSumByMilestones{ + { + RepoName: "repo2", + MilestoneName: "", + MilestoneID: 0, + SumTime: 71, + HideRepoName: false, + }, + }, + }, + } + + // Run test kases + for _, kase := range kases { + t.Run(kase.name, func(t *testing.T) { + org, err := organization.GetOrgByID(db.DefaultContext, kase.orgname) + require.NoError(t, err) + results, err := organization.GetWorktimeByMilestones(org, kase.unixfrom, kase.unixto) + if assert.NoError(t, err) { + assert.Equal(t, kase.expected, results) + } + }) + } +} + +// TestTimesByMembers tests TimesByMembers functionality +func testTimesByMembers(t *testing.T) { + kases := []struct { + name string + unixfrom int64 + unixto int64 + orgname int64 + expected []organization.WorktimeSumByMembers + }{ + { + name: "Full sum for org 1", + unixfrom: 0, + unixto: 9223372036854775807, + orgname: 1, + expected: []organization.WorktimeSumByMembers(nil), + }, + { + // Test case: Sum of times forever in org no. 2 + name: "Full sum for org 2", + unixfrom: 0, + unixto: 9223372036854775807, + orgname: 2, + expected: []organization.WorktimeSumByMembers{ + { + UserName: "user2", + SumTime: 3666, + }, + { + UserName: "user1", + SumTime: 491, + }, + }, + }, + { + name: "Simple time bound", + unixfrom: 946684801, + unixto: 946684802, + orgname: 2, + expected: []organization.WorktimeSumByMembers{ + { + UserName: "user2", + SumTime: 3662, + }, + }, + }, + { + name: "Both times inclusive", + unixfrom: 946684801, + unixto: 946684801, + orgname: 2, + expected: []organization.WorktimeSumByMembers{ + { + UserName: "user2", + SumTime: 3661, + }, + }, + }, + { + name: "Should ignore deleted", + unixfrom: 947688814, + unixto: 947688815, + orgname: 2, + expected: []organization.WorktimeSumByMembers{ + { + UserName: "user1", + SumTime: 71, + }, + }, + }, + } + + // Run test kases + for _, kase := range kases { + t.Run(kase.name, func(t *testing.T) { + org, err := organization.GetOrgByID(db.DefaultContext, kase.orgname) + assert.NoError(t, err) + results, err := organization.GetWorktimeByMembers(org, kase.unixfrom, kase.unixto) + assert.NoError(t, err) + assert.Equal(t, kase.expected, results) + }) + } +} + +func TestOrgWorktime(t *testing.T) { + // we need to run these tests in integration test because there are complex SQL queries + assert.NoError(t, unittest.PrepareTestDatabase()) + t.Run("ByRepos", testTimesByRepos) + t.Run("ByMilestones", testTimesByMilestones) + t.Run("ByMembers", testTimesByMembers) +} From 5dddcc1773b9245a7bcd1f71a83a0681ea541538 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 3 Feb 2025 02:16:56 +0800 Subject: [PATCH 049/655] chore: fix some trivial problems and TODOs (#33473) 1. Fix incorrect `MentionCount` (actually it seems to be deadcode, affects nothing) 2. Remove fallback sha1 support for time limit token 3. Use route middleware `reqRepoActionsWriter` for `ArtifactsDeleteView` 4. Use clearer message "Failed to authenticate user" instead of "Verify" when auth fails 5. `tests/integration/benchmarks_test.go` is not quite right, actually it is never used, so delete it. 6. Remove or update TODO comments --- models/issues/issue_stats.go | 2 +- models/system/notice_test.go | 2 - modules/base/tool.go | 9 +--- modules/base/tool_test.go | 11 ++--- modules/markup/html.go | 2 +- modules/web/middleware/binding.go | 2 +- routers/web/repo/actions/view.go | 5 -- routers/web/web.go | 4 +- services/mailer/mail_test.go | 16 +++---- tests/integration/benchmarks_test.go | 69 ---------------------------- 10 files changed, 18 insertions(+), 104 deletions(-) delete mode 100644 tests/integration/benchmarks_test.go diff --git a/models/issues/issue_stats.go b/models/issues/issue_stats.go index 9ef9347a16..50409fbbd8 100644 --- a/models/issues/issue_stats.go +++ b/models/issues/issue_stats.go @@ -107,7 +107,7 @@ func GetIssueStats(ctx context.Context, opts *IssuesOptions) (*IssueStats, error accum.YourRepositoriesCount += stats.YourRepositoriesCount accum.AssignCount += stats.AssignCount accum.CreateCount += stats.CreateCount - accum.OpenCount += stats.MentionCount + accum.MentionCount += stats.MentionCount accum.ReviewRequestedCount += stats.ReviewRequestedCount accum.ReviewedCount += stats.ReviewedCount i = chunk diff --git a/models/system/notice_test.go b/models/system/notice_test.go index 599b2fb65c..9fc9e6cce1 100644 --- a/models/system/notice_test.go +++ b/models/system/notice_test.go @@ -45,8 +45,6 @@ func TestCreateRepositoryNotice(t *testing.T) { unittest.AssertExistsAndLoadBean(t, noticeBean) } -// TODO TestRemoveAllWithNotice - func TestCountNotices(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) assert.Equal(t, int64(3), system.CountNotices(db.DefaultContext)) diff --git a/modules/base/tool.go b/modules/base/tool.go index 1d16186bc5..b6ed8cbf9a 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -18,7 +18,6 @@ import ( "time" "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" @@ -64,10 +63,7 @@ func VerifyTimeLimitCode(now time.Time, data string, minutes int, code string) b // check code retCode := CreateTimeLimitCode(data, aliveTime, startTimeStr, nil) if subtle.ConstantTimeCompare([]byte(retCode), []byte(code)) != 1 { - retCode = CreateTimeLimitCode(data, aliveTime, startTimeStr, sha1.New()) // TODO: this is only for the support of legacy codes, remove this in/after 1.23 - if subtle.ConstantTimeCompare([]byte(retCode), []byte(code)) != 1 { - return false - } + return false } // check time is expired or not: startTime <= now && now < startTime + minutes @@ -144,13 +140,12 @@ func Int64sToStrings(ints []int64) []string { return strs } -// EntryIcon returns the octicon class for displaying files/directories +// EntryIcon returns the octicon name for displaying files/directories func EntryIcon(entry *git.TreeEntry) string { switch { case entry.IsLink(): te, err := entry.FollowLink() if err != nil { - log.Debug(err.Error()) return "file-symlink-file" } if te.IsDir() { diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go index c821a55c19..7cebedb073 100644 --- a/modules/base/tool_test.go +++ b/modules/base/tool_test.go @@ -86,13 +86,10 @@ JWT_SECRET = %s verifyDataCode := func(c string) bool { return VerifyTimeLimitCode(now, "data", 2, c) } - code1 := CreateTimeLimitCode("data", 2, now, sha1.New()) - code2 := CreateTimeLimitCode("data", 2, now, nil) - assert.True(t, verifyDataCode(code1)) - assert.True(t, verifyDataCode(code2)) + code := CreateTimeLimitCode("data", 2, now, nil) + assert.True(t, verifyDataCode(code)) initGeneralSecret("000_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko") - assert.False(t, verifyDataCode(code1)) - assert.False(t, verifyDataCode(code2)) + assert.False(t, verifyDataCode(code)) }) } @@ -137,5 +134,3 @@ func TestInt64sToStrings(t *testing.T) { Int64sToStrings([]int64{1, 4, 16, 64, 256}), ) } - -// TODO: Test EntryIcon diff --git a/modules/markup/html.go b/modules/markup/html.go index bb12febf27..3aaf669c63 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -47,7 +47,7 @@ var globalVars = sync.OnceValue(func() *globalVarsType { // NOTE: All below regex matching do not perform any extra validation. // Thus a link is produced even if the linked entity does not exist. // While fast, this is also incorrect and lead to false positives. - // TODO: fix invalid linking issue + // TODO: fix invalid linking issue (update: stale TODO, what issues? maybe no TODO anymore) // valid chars in encoded path and parameter: [-+~_%.a-zA-Z0-9/] diff --git a/modules/web/middleware/binding.go b/modules/web/middleware/binding.go index 43e1bbc70e..03e188f509 100644 --- a/modules/web/middleware/binding.go +++ b/modules/web/middleware/binding.go @@ -78,7 +78,7 @@ func GetInclude(field reflect.StructField) string { return getRuleBody(field, "Include(") } -// Validate validate TODO: +// Validate validate func Validate(errs binding.Errors, data map[string]any, f Form, l translation.Locale) binding.Errors { if errs.Len() == 0 { return errs diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index e9321d0a8a..fc346b83b4 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -628,11 +628,6 @@ func getRunJobs(ctx *context_module.Context, runIndex, jobIndex int64) (*actions } func ArtifactsDeleteView(ctx *context_module.Context) { - if !ctx.Repo.CanWrite(unit.TypeActions) { - ctx.Error(http.StatusForbidden, "no permission") - return - } - runIndex := getRunIndex(ctx) artifactName := ctx.PathParam("artifact_name") diff --git a/routers/web/web.go b/routers/web/web.go index daba9887e8..f772f6dbb9 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -118,7 +118,7 @@ func webAuth(authMethod auth_service.Method) func(*context.Context) { ar, err := common.AuthShared(ctx.Base, ctx.Session, authMethod) if err != nil { log.Error("Failed to verify user: %v", err) - ctx.Error(http.StatusUnauthorized, "Verify") + ctx.Error(http.StatusUnauthorized, "Failed to authenticate user") return } ctx.Doer = ar.Doer @@ -1430,7 +1430,7 @@ func registerRoutes(m *web.Router) { m.Post("/cancel", reqRepoActionsWriter, actions.Cancel) m.Post("/approve", reqRepoActionsWriter, actions.Approve) m.Get("/artifacts/{artifact_name}", actions.ArtifactsDownloadView) - m.Delete("/artifacts/{artifact_name}", actions.ArtifactsDeleteView) + m.Delete("/artifacts/{artifact_name}", reqRepoActionsWriter, actions.ArtifactsDeleteView) m.Post("/rerun", reqRepoActionsWriter, actions.Rerun) }) m.Group("/workflows/{workflow_name}", func() { diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go index 36cef486c9..8298ac4a34 100644 --- a/services/mailer/mail_test.go +++ b/services/mailer/mail_test.go @@ -85,7 +85,7 @@ func TestComposeIssueCommentMessage(t *testing.T) { recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}} msgs, err := composeIssueCommentMessages(&mailCommentContext{ - Context: context.TODO(), // TODO: use a correct context + Context: context.TODO(), Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue, Content: fmt.Sprintf("test @%s %s#%d body", doer.Name, issue.Repo.FullName(), issue.Index), Comment: comment, @@ -131,7 +131,7 @@ func TestComposeIssueMessage(t *testing.T) { recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}} msgs, err := composeIssueCommentMessages(&mailCommentContext{ - Context: context.TODO(), // TODO: use a correct context + Context: context.TODO(), Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue, Content: "test body", }, "en-US", recipients, false, "issue create") @@ -178,14 +178,14 @@ func TestTemplateSelection(t *testing.T) { } msg := testComposeIssueCommentMessage(t, &mailCommentContext{ - Context: context.TODO(), // TODO: use a correct context + Context: context.TODO(), Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue, Content: "test body", }, recipients, false, "TestTemplateSelection") expect(t, msg, "issue/new/subject", "issue/new/body") msg = testComposeIssueCommentMessage(t, &mailCommentContext{ - Context: context.TODO(), // TODO: use a correct context + Context: context.TODO(), Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue, Content: "test body", Comment: comment, }, recipients, false, "TestTemplateSelection") @@ -194,14 +194,14 @@ func TestTemplateSelection(t *testing.T) { pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer}) comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull}) msg = testComposeIssueCommentMessage(t, &mailCommentContext{ - Context: context.TODO(), // TODO: use a correct context + Context: context.TODO(), Issue: pull, Doer: doer, ActionType: activities_model.ActionCommentPull, Content: "test body", Comment: comment, }, recipients, false, "TestTemplateSelection") expect(t, msg, "pull/comment/subject", "pull/comment/body") msg = testComposeIssueCommentMessage(t, &mailCommentContext{ - Context: context.TODO(), // TODO: use a correct context + Context: context.TODO(), Issue: issue, Doer: doer, ActionType: activities_model.ActionCloseIssue, Content: "test body", Comment: comment, }, recipients, false, "TestTemplateSelection") @@ -220,7 +220,7 @@ func TestTemplateServices(t *testing.T) { recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}} msg := testComposeIssueCommentMessage(t, &mailCommentContext{ - Context: context.TODO(), // TODO: use a correct context + Context: context.TODO(), Issue: issue, Doer: doer, ActionType: actionType, Content: "test body", Comment: comment, }, recipients, fromMention, "TestTemplateServices") @@ -263,7 +263,7 @@ func testComposeIssueCommentMessage(t *testing.T, ctx *mailCommentContext, recip func TestGenerateAdditionalHeaders(t *testing.T) { doer, _, issue, _ := prepareMailerTest(t) - ctx := &mailCommentContext{Context: context.TODO() /* TODO: use a correct context */, Issue: issue, Doer: doer} + ctx := &mailCommentContext{Context: context.TODO(), Issue: issue, Doer: doer} recipient := &user_model.User{Name: "test", Email: "test@gitea.com"} headers := generateAdditionalHeaders(ctx, "dummy-reason", recipient) diff --git a/tests/integration/benchmarks_test.go b/tests/integration/benchmarks_test.go deleted file mode 100644 index 62da761d2d..0000000000 --- a/tests/integration/benchmarks_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2017 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package integration - -import ( - "math/rand/v2" - "net/http" - "net/url" - "testing" - - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unittest" - api "code.gitea.io/gitea/modules/structs" -) - -// StringWithCharset random string (from https://www.calhoun.io/creating-random-strings-in-go/) -func StringWithCharset(length int, charset string) string { - b := make([]byte, length) - for i := range b { - b[i] = charset[rand.IntN(len(charset))] - } - return string(b) -} - -func BenchmarkRepoBranchCommit(b *testing.B) { - onGiteaRun(b, func(b *testing.B, u *url.URL) { - samples := []int64{1, 2, 3} - b.ResetTimer() - - for _, repoID := range samples { - b.StopTimer() - repo := unittest.AssertExistsAndLoadBean(b, &repo_model.Repository{ID: repoID}) - b.StartTimer() - b.Run(repo.Name, func(b *testing.B) { - session := loginUser(b, "user2") - b.ResetTimer() - b.Run("CreateBranch", func(b *testing.B) { - b.StopTimer() - branchName := StringWithCharset(5+rand.IntN(10), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") - b.StartTimer() - for i := 0; i < b.N; i++ { - b.Run("new_"+branchName, func(b *testing.B) { - b.Skip("benchmark broken") // TODO fix - testAPICreateBranch(b, session, repo.OwnerName, repo.Name, repo.DefaultBranch, "new_"+branchName, http.StatusCreated) - }) - } - }) - b.Run("GetBranches", func(b *testing.B) { - req := NewRequestf(b, "GET", "/api/v1/repos/%s/branches", repo.FullName()) - session.MakeRequest(b, req, http.StatusOK) - }) - b.Run("AccessCommits", func(b *testing.B) { - var branches []*api.Branch - req := NewRequestf(b, "GET", "/api/v1/repos/%s/branches", repo.FullName()) - resp := session.MakeRequest(b, req, http.StatusOK) - DecodeJSON(b, resp, &branches) - b.ResetTimer() // We measure from here - if len(branches) != 0 { - for i := 0; i < b.N; i++ { - req := NewRequestf(b, "GET", "/api/v1/repos/%s/commits?sha=%s", repo.FullName(), branches[i%len(branches)].Name) - session.MakeRequest(b, req, http.StatusOK) - } - } - }) - }) - } - }) -} From 50873c192559e05e88c8edbdd50ed336ef0a6c11 Mon Sep 17 00:00:00 2001 From: Typed SIGTERM Date: Mon, 3 Feb 2025 02:42:30 +0800 Subject: [PATCH 050/655] Correct bot label `vertical-align` (#33477) --- templates/shared/user/authorlink.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/shared/user/authorlink.tmpl b/templates/shared/user/authorlink.tmpl index d57a635b4b..abe1ab1ce2 100644 --- a/templates/shared/user/authorlink.tmpl +++ b/templates/shared/user/authorlink.tmpl @@ -1 +1 @@ -{{.GetDisplayName}}{{if .IsBot}}bot{{end}} +{{.GetDisplayName}}{{if .IsBot}}bot{{end}} From ed84f3737a31c46de537b688f877753a92d0ab5c Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 3 Feb 2025 00:32:15 +0000 Subject: [PATCH 051/655] [skip ci] Updated licenses and gitignores --- options/gitignore/Flutter | 119 ++++++++++++++++++ options/gitignore/Nix | 3 + options/gitignore/NotesAndCoreConfiguration | 16 +++ .../gitignore/NotesAndExtendedConfiguration | 38 ++++++ options/gitignore/NotesOnly | 4 + 5 files changed, 180 insertions(+) create mode 100644 options/gitignore/Flutter create mode 100644 options/gitignore/NotesAndCoreConfiguration create mode 100644 options/gitignore/NotesAndExtendedConfiguration create mode 100644 options/gitignore/NotesOnly diff --git a/options/gitignore/Flutter b/options/gitignore/Flutter new file mode 100644 index 0000000000..39b8814aec --- /dev/null +++ b/options/gitignore/Flutter @@ -0,0 +1,119 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.buildlog/ +.history + + + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +**/generated_plugin_registrant.dart +.packages +.pub-preload-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake + +# Coverage +coverage/ + +# Symbols +app.*.symbols + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock \ No newline at end of file diff --git a/options/gitignore/Nix b/options/gitignore/Nix index 1fd04ef1f6..912e6700f4 100644 --- a/options/gitignore/Nix +++ b/options/gitignore/Nix @@ -1,3 +1,6 @@ # Ignore build outputs from performing a nix-build or `nix build` command result result-* + +# Ignore automatically generated direnv output +.direnv diff --git a/options/gitignore/NotesAndCoreConfiguration b/options/gitignore/NotesAndCoreConfiguration new file mode 100644 index 0000000000..4eff01dae1 --- /dev/null +++ b/options/gitignore/NotesAndCoreConfiguration @@ -0,0 +1,16 @@ +# Excludes Obsidian workspace cache and plugins. All notes and core obsidian +# configuration files are tracked by Git. + +# The current application UI state (DOM layout, recently-opened files, etc.) is +# stored in these files (separate for desktop and mobile) so you can resume +# your session seamlessly after a restart. If you want to track UI state, use +# the Workspaces core plugin instead of relying on these files. +.obsidian/workspace.json +.obsidian/workspace-mobile.json + +# Obsidian plugins are stored under .obsidian/plugins/$plugin_name. They +# contain metadata (manifest.json), application code (main.js), stylesheets +# (styles.css), and user-configuration data (data.json). +# We want to exclude all plugin-related files, so we can exclude everything +# under this directory. +.obsidian/plugins/**/* diff --git a/options/gitignore/NotesAndExtendedConfiguration b/options/gitignore/NotesAndExtendedConfiguration new file mode 100644 index 0000000000..3e0804f299 --- /dev/null +++ b/options/gitignore/NotesAndExtendedConfiguration @@ -0,0 +1,38 @@ +# Excludes Obsidian workspace cache and plugin code, but retains plugin +# configuration. All notes and user-controlled configuration files are tracked +# by Git. +# +# !!! WARNING !!! +# +# Community plugins may store sensitive secrets in their data.json files. By +# including these files, those secrets may be tracked in your Git repository. +# +# To ignore configurations for specific plugins, add a line like this after the +# contents of this file (order is important): +# .obsidian/plugins/{{plugin_name}}/data.json +# +# Alternatively, ensure that you are treating your entire Git repository as +# sensitive data, since it may contain secrets, or may have contained them in +# past commits. Understand your threat profile, and make the decision +# appropriate for yourself. If in doubt, err on the side of not including +# plugin configuration. Use one of the alternative gitignore files instead: +# * NotesOnly.gitignore +# * NotesAndCoreConfiguration.gitignore + +# The current application UI state (DOM layout, recently-opened files, etc.) is +# stored in these files (separate for desktop and mobile) so you can resume +# your session seamlessly after a restart. If you want to track UI state, use +# the Workspaces core plugin instead of relying on these files. +.obsidian/workspace.json +.obsidian/workspace-mobile.json + +# Obsidian plugins are stored under .obsidian/plugins/$plugin_name. They +# contain metadata (manifest.json), application code (main.js), stylesheets +# (styles.css), and user-configuration data (data.json). +# We only want to track data.json, so we: +# 1. exclude everything under the plugins directory recursively, +# 2. unignore the plugin directories themselves, which then allows us to +# 3. unignore the data.json files +.obsidian/plugins/**/* +!.obsidian/plugins/*/ +!.obsidian/plugins/*/data.json diff --git a/options/gitignore/NotesOnly b/options/gitignore/NotesOnly new file mode 100644 index 0000000000..2b3b76ee0e --- /dev/null +++ b/options/gitignore/NotesOnly @@ -0,0 +1,4 @@ +# Excludes all Obsidian-related configuration. All notes are tracked by Git. + +# All Obsidian configuration and runtime state is stored here +.obsidian/**/* From 3ebfc77e8304face48e9043b90dd94a815fc66f1 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 3 Feb 2025 12:52:20 -0800 Subject: [PATCH 052/655] Disable cron task to update license (#33486) Help #33467 The file can be changed or removed after that issue is resolved. --- .github/workflows/cron-licenses.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cron-licenses.yml b/.github/workflows/cron-licenses.yml index cd8386ecc5..7e57f48aa9 100644 --- a/.github/workflows/cron-licenses.yml +++ b/.github/workflows/cron-licenses.yml @@ -1,8 +1,8 @@ name: cron-licenses on: - schedule: - - cron: "7 0 * * 1" # every Monday at 00:07 UTC + #schedule: + # - cron: "7 0 * * 1" # every Monday at 00:07 UTC workflow_dispatch: jobs: From 3c46cd6aae4ed4a01d0471767563c5d882fc5b45 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Tue, 4 Feb 2025 00:31:03 +0000 Subject: [PATCH 053/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_cs-CZ.ini | 3 +++ options/locale/locale_de-DE.ini | 3 +++ options/locale/locale_el-GR.ini | 3 +++ options/locale/locale_es-ES.ini | 3 +++ options/locale/locale_fa-IR.ini | 1 + options/locale/locale_fi-FI.ini | 3 +++ options/locale/locale_fr-FR.ini | 5 ++++- options/locale/locale_ga-IE.ini | 5 +++++ options/locale/locale_hu-HU.ini | 1 + options/locale/locale_id-ID.ini | 1 + options/locale/locale_is-IS.ini | 3 +++ options/locale/locale_it-IT.ini | 3 +++ options/locale/locale_ja-JP.ini | 3 +++ options/locale/locale_ko-KR.ini | 1 + options/locale/locale_lv-LV.ini | 3 +++ options/locale/locale_nl-NL.ini | 3 +++ options/locale/locale_pl-PL.ini | 1 + options/locale/locale_pt-BR.ini | 3 +++ options/locale/locale_pt-PT.ini | 3 +++ options/locale/locale_ru-RU.ini | 3 +++ options/locale/locale_si-LK.ini | 1 + options/locale/locale_sk-SK.ini | 3 +++ options/locale/locale_sv-SE.ini | 1 + options/locale/locale_tr-TR.ini | 7 +++++-- options/locale/locale_uk-UA.ini | 3 +++ options/locale/locale_zh-CN.ini | 3 +++ options/locale/locale_zh-HK.ini | 1 + options/locale/locale_zh-TW.ini | 3 +++ 28 files changed, 73 insertions(+), 3 deletions(-) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 91605a1f31..8d43077f50 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -54,6 +54,7 @@ webauthn_reload=Znovu načíst repository=Repozitář organization=Organizace mirror=Zrcadlo +issue_milestone=Milník new_repo=Nový repozitář new_migrate=Nová migrace new_mirror=Nové zrcadlo @@ -1253,6 +1254,7 @@ labels=Štítky org_labels_desc=Štítky na úrovni organizace, které mohou být použity se všemi repozitáři v rámci této organizace org_labels_desc_manage=spravovat +milestone=Milník milestones=Milníky commits=Commity commit=Commit @@ -2873,6 +2875,7 @@ view_as_role=Zobrazit jako: %s view_as_public_hint=Prohlížíte README jako veřejný uživatel. view_as_member_hint=Prohlížíte README jako člen této organizace. + [admin] maintenance=Údržba dashboard=Přehled diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 29ef51bfc4..32f3a4bbcc 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -54,6 +54,7 @@ webauthn_reload=Neu laden repository=Repository organization=Organisation mirror=Mirror +issue_milestone=Meilenstein new_repo=Neues Repository new_migrate=Neue Migration new_mirror=Neuer Mirror @@ -1247,6 +1248,7 @@ labels=Label org_labels_desc=Labels der Organisationsebene, die mit allen Repositories in dieser Organisation verwendet werden können org_labels_desc_manage=verwalten +milestone=Meilenstein milestones=Meilensteine commits=Commits commit=Commit @@ -2854,6 +2856,7 @@ teams.invite.by=Von %s eingeladen teams.invite.description=Bitte klicke auf die folgende Schaltfläche, um dem Team beizutreten. + [admin] maintenance=Wartung dashboard=Dashboard diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index e989819c5e..cab6320016 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -53,6 +53,7 @@ webauthn_reload=Ανανέωση repository=Αποθετήριο organization=Οργανισμός mirror=Αντίγραφο +issue_milestone=Ορόσημο new_repo=Νέο Αποθετήριο new_migrate=Νέα Μεταφορά new_mirror=Νέο Είδωλο @@ -1119,6 +1120,7 @@ labels=Σήματα org_labels_desc=Τα σήματα στο επίπεδο οργανισμού, που μπορούν να χρησιμοποιηθούν με όλα τα αποθετήρια κάτω από αυτόν τον οργανισμό org_labels_desc_manage=διαχείριση +milestone=Ορόσημο milestones=Ορόσημα commits=Υποβολές commit=Υποβολή @@ -2590,6 +2592,7 @@ teams.invite.by=Προσκλήθηκε από %s teams.invite.description=Παρακαλώ κάντε κλικ στον παρακάτω σύνδεσμο για συμμετοχή στην ομάδα. + [admin] dashboard=Πίνακας Ελέγχου identity_access=Ταυτότητα & Πρόσβαση diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 049fb9196d..359f490356 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -52,6 +52,7 @@ webauthn_reload=Recargar repository=Repositorio organization=Organización mirror=Réplica +issue_milestone=Hito new_repo=Nuevo repositorio new_migrate=Nueva migración new_mirror=Nueva réplica @@ -1109,6 +1110,7 @@ labels=Etiquetas org_labels_desc=Etiquetas de nivel de la organización que pueden ser utilizadas con todos los repositorios bajo esta organización org_labels_desc_manage=gestionar +milestone=Hito milestones=Hitos commits=Commits commit=Commit @@ -2571,6 +2573,7 @@ teams.invite.by=Invitado por %s teams.invite.description=Por favor, haga clic en el botón de abajo para unirse al equipo. + [admin] dashboard=Panel de control identity_access=Identidad y acceso diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 4d90cf9876..a84fcd9bd7 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -1993,6 +1993,7 @@ teams.all_repositories_write_permission_desc=این تیم دسترسی teams.all_repositories_admin_permission_desc=این تیم دسترسی مدیر به مخازن همه را می بخشد: اعضا می توانند مخازن را بخواند، همکار و مخزن اضافه کنند. + [admin] dashboard=پیشخوان users=حساب کاربران diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index b5fa5c8afc..1c78f049f9 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -49,6 +49,7 @@ webauthn_reload=Päivitä repository=Repo organization=Organisaatio mirror=Peili +issue_milestone=Merkkipaalu new_repo=Uusi repo new_migrate=Uusi migraatio new_mirror=Uusi peilaus @@ -720,6 +721,7 @@ projects=Projektit packages=Paketit labels=Tunnisteet +milestone=Merkkipaalu milestones=Merkkipaalut commits=Commitit commit=Commit @@ -1361,6 +1363,7 @@ teams.members.none=Ei jäseniä tässä tiimissä. teams.all_repositories=Kaikki repot + [admin] dashboard=Kojelauta users=Käyttäjätilit diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index bf179a5931..45cf43956a 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -54,6 +54,7 @@ webauthn_reload=Recharger repository=Dépôt organization=Organisation mirror=Miroir +issue_milestone=Jalon new_repo=Nouveau dépôt new_migrate=Nouvelle migration new_mirror=Nouveau miroir @@ -1172,7 +1173,7 @@ migrate_items_releases=Publications migrate_repo=Migrer le dépôt migrate.clone_address=Migrer/Cloner depuis une URL migrate.clone_address_desc=L'URL HTTP(S) ou Git "clone" d'un dépôt existant -migrate.github_token_desc=Vous pouvez mettre un ou plusieurs jetons séparés par des virgules ici pour rendre la migration plus rapide en raison de la limite de débit de l'API GitHub. ATTENTION : Abuser de cette fonctionnalité peut enfreindre la politique du fournisseur de services et entraîner un blocage de compte. +migrate.github_token_desc=Vous pouvez mettre un ou plusieurs jetons séparés par des virgules ici pour rendre la migration plus rapide et contourner la limite de débit de l’API GitHub. ATTENTION : Abuser de cette fonctionnalité peut enfreindre la politique du fournisseur de service et entraîner un blocage de votre compte. migrate.clone_local_path=ou un chemin serveur local migrate.permission_denied=Vous n'êtes pas autorisé à importer des dépôts locaux. migrate.permission_denied_blocked=Vous ne pouvez pas importer depuis des hôtes interdits, veuillez demander à l'administrateur de vérifier les paramètres ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS. @@ -1253,6 +1254,7 @@ labels=Labels org_labels_desc=Les labels d'une organisation peuvent être utilisés avec tous les dépôts de cette organisation. org_labels_desc_manage=gérer +milestone=Jalon milestones=Jalons commits=Révisions commit=Révision @@ -2875,6 +2877,7 @@ view_as_role=Voir en tant que %s view_as_public_hint=Vous visualisez le README en tant qu’utilisateur public. view_as_member_hint=Vous visualisez le README en tant que membre de cette organisation. + [admin] maintenance=Maintenance dashboard=Tableau de bord diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index 805deb618d..84ec5c10ee 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -54,6 +54,7 @@ webauthn_reload=Athlódáil repository=Stór organization=Eagraíocht mirror=Scáthán +issue_milestone=Cloch Mhíle new_repo=Stór Nua new_migrate=Imirce Nua new_mirror=Scáthán Nua @@ -1253,6 +1254,7 @@ labels=Lipéid org_labels_desc=Lipéid ar leibhéal eagraíochta is féidir a úsáid le gach stóras faoin eagraíocht seo org_labels_desc_manage=bainistigh +milestone=Cloch Mhíle milestones=Clocha míle commits=Tiomáintí commit=Tiomantas @@ -1345,6 +1347,8 @@ editor.new_branch_name_desc=Ainm brainse nua… editor.cancel=Cealaigh editor.filename_cannot_be_empty=Ní féidir ainm an chomhaid a bheith folamh. editor.filename_is_invalid=Tá ainm an chomhaid neamhbhailí: "%s". +editor.commit_email=Tiomantas ríomhphost +editor.invalid_commit_email=Tá an ríomhphost don ghealltanas neamhbhailí. editor.branch_does_not_exist=Níl brainse "%s" ann sa stóras seo. editor.branch_already_exists=Tá brainse "%s" ann cheana féin sa stóras seo. editor.directory_is_a_file=Úsáidtear ainm eolaire "%s" cheana féin mar ainm comhaid sa stóras seo. @@ -2873,6 +2877,7 @@ view_as_role=Féach mar: %s view_as_public_hint=Tá tú ag féachaint ar an README mar úsáideoir poiblí. view_as_member_hint=Tá tú ag féachaint ar an README mar bhall den eagraíocht seo. + [admin] maintenance=Cothabháil dashboard=Deais diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index f0935a2916..579a030567 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -1229,6 +1229,7 @@ teams.specific_repositories=Meghatározott tárolók teams.all_repositories=Minden tároló + [admin] dashboard=Műszerfal users=Felhasználói fiókok diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index 391691ebf5..1fb1efbd16 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -1084,6 +1084,7 @@ teams.delete_team_success=Tim sudah di hapus. teams.repositories=Tim repositori + [admin] dashboard=Dasbor organizations=Organisasi diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index 1eab4d58be..c8bcf9819e 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -49,6 +49,7 @@ webauthn_reload=Endurhlaða repository=Hugbúnaðarsafn organization=Stofnun mirror=Speglun +issue_milestone=Tímamót new_repo=Nýtt Hugbúnaðarsafn new_migrate=Nýr Flutningur new_mirror=Ný Speglun @@ -652,6 +653,7 @@ projects=Verkefni packages=Pakkar labels=Skýringar +milestone=Tímamót milestones=Tímamót commits=Framlög commit=Framlag @@ -1137,6 +1139,7 @@ teams.update_settings=Uppfæra Stillingar teams.all_repositories=Öll hugbúnaðarsöfn + [admin] repositories=Hugbúnaðarsöfn config=Stilling diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index 17f0aa83d2..f37598eec3 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -50,6 +50,7 @@ webauthn_reload=Ricarica repository=Repository organization=Organizzazione mirror=Mirror +issue_milestone=Traguardo new_repo=Nuovo Repository new_migrate=Nuova Migrazione new_mirror=Nuovo Mirror @@ -942,6 +943,7 @@ labels=Etichette org_labels_desc=Etichette a livello di organizzazione che possono essere utilizzate con tutti i repository sotto questa organizzazione org_labels_desc_manage=gestisci +milestone=Traguardo milestones=Traguardi commits=Commit commit=Commit @@ -2154,6 +2156,7 @@ teams.all_repositories_write_permission_desc=Questo team concede permess teams.all_repositories_admin_permission_desc=Questo team concede a Amministratore l'accesso a tutte le repository: i membri possono leggere, pushare e aggiungere collaboratori alle repository. + [admin] dashboard=Pannello di Controllo users=Account utenti diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 925d0249b7..df0c2b9524 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -54,6 +54,7 @@ webauthn_reload=リロード repository=リポジトリ organization=組織 mirror=ミラー +issue_milestone=マイルストーン new_repo=新しいリポジトリ new_migrate=新しい移行 new_mirror=新しいミラー @@ -1253,6 +1254,7 @@ labels=ラベル org_labels_desc=組織で定義されているラベル (組織のすべてのリポジトリで使用可能なもの) org_labels_desc_manage=編集 +milestone=マイルストーン milestones=マイルストーン commits=コミット commit=コミット @@ -2873,6 +2875,7 @@ view_as_role=表示: %s view_as_public_hint=READMEを公開ユーザーとして見ています。 view_as_member_hint=READMEをこの組織のメンバーとして見ています。 + [admin] maintenance=メンテナンス dashboard=ダッシュボード diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index 5485a53c81..05a6d21335 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -1191,6 +1191,7 @@ teams.add_duplicate_users=사용자가 이미 팀 멤버입니다. teams.members.none=이 팀에 멤버가 없습니다. + [admin] dashboard=대시보드 users=사용자 계정 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index cc2dcd1180..6fc6e53800 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -54,6 +54,7 @@ webauthn_reload=Pārlādēt repository=Repozitorijs organization=Organizācija mirror=Spogulis +issue_milestone=Atskaites punktus new_repo=Jauns repozitorijs new_migrate=Jauna migrācija new_mirror=Jauns spogulis @@ -1125,6 +1126,7 @@ labels=Iezīmes org_labels_desc=Organizācijas līmeņa iezīmes var tikt izmantotas visiem repozitorijiem šajā organizācijā org_labels_desc_manage=pārvaldīt +milestone=Atskaites punktus milestones=Atskaites punkti commits=Revīzijas commit=Revīzija @@ -2593,6 +2595,7 @@ teams.invite.by=Uzaicināja %s teams.invite.description=Nospiediet pogu zemāk, lai pievienotos komandai. + [admin] dashboard=Infopanelis self_check=Pašpārbaude diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index 8a6dabbceb..9f61d34bc0 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -50,6 +50,7 @@ webauthn_reload=Vernieuwen repository=Repository organization=Organisatie mirror=Kopie +issue_milestone=Mijlpaal new_repo=Nieuwe repository new_migrate=Nieuwe migratie new_mirror=Nieuwe kopie @@ -940,6 +941,7 @@ labels=Labels org_labels_desc=Organisatielabel dat gebruikt kan worden met alle repositories onder deze organisatie org_labels_desc_manage=beheren +milestone=Mijlpaal milestones=Mijlpalen commits=Commits commit=Commit @@ -2055,6 +2057,7 @@ teams.all_repositories_helper=Team heeft toegang tot alle repositories. Door dit teams.all_repositories_read_permission_desc=Dit team heeft Lees toegang tot alle repositories: leden kunnen repositories bekijken en klonen. + [admin] dashboard=Overzicht users=Gebruikersacount diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 4dfae86bb6..958310a085 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -1934,6 +1934,7 @@ teams.all_repositories_write_permission_desc=Ten zespół nadaje uprawnienie Administratora do wszystkich repozytoriów: jego członkowie mogą odczytywać, przesyłać oraz dodawać innych współtwórców do repozytoriów. + [admin] dashboard=Pulpit users=Konta użytkownika diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index cc21c5abea..9df7e5e956 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -52,6 +52,7 @@ webauthn_reload=Recarregar repository=Repositório organization=Organização mirror=Espelhamento +issue_milestone=Marco new_repo=Novo repositório new_migrate=Nova migração new_mirror=Novo espelhamento @@ -1119,6 +1120,7 @@ labels=Etiquetas org_labels_desc=Rótulos de nível de organização que podem ser usados em todos os repositórios sob esta organização org_labels_desc_manage=gerenciar +milestone=Marco milestones=Marcos commits=Commits commit=Commit @@ -2551,6 +2553,7 @@ teams.invite.by=Convidado por %s teams.invite.description=Por favor, clique no botão abaixo para se juntar à equipe. + [admin] dashboard=Painel identity_access=Identidade e acesso diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index fa5ef9c3a4..c482949dd1 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -54,6 +54,7 @@ webauthn_reload=Recarregar repository=Repositório organization=Organização mirror=Réplica +issue_milestone=Etapa new_repo=Novo repositório new_migrate=Nova migração new_mirror=Nova réplica @@ -1253,6 +1254,7 @@ labels=Rótulos org_labels_desc=Rótulos ao nível da organização que podem ser usados em todos os repositórios desta organização org_labels_desc_manage=gerir +milestone=Etapa milestones=Etapas commits=Cometimentos commit=Cometimento @@ -2875,6 +2877,7 @@ view_as_role=Ver como: %s view_as_public_hint=Está a ver o README como um utilizador público. view_as_member_hint=Está a ver o README como um membro desta organização. + [admin] maintenance=Manutenção dashboard=Painel de controlo diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index d3b673bd18..f2b4e28405 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -52,6 +52,7 @@ webauthn_reload=Обновить repository=Репозиторий organization=Организация mirror=Зеркало +issue_milestone=Этап new_repo=Новый репозиторий new_migrate=Новая миграция new_mirror=Новое зеркало @@ -1100,6 +1101,7 @@ labels=Метки org_labels_desc=Метки уровня организации, которые можно использовать с всеми репозиториями в этой организации org_labels_desc_manage=управлять +milestone=Этап milestones=Этапы commits=коммитов commit=коммит @@ -2540,6 +2542,7 @@ teams.invite.by=Приглашен(а) %s teams.invite.description=Нажмите на кнопку ниже, чтобы присоединиться к команде. + [admin] dashboard=Панель identity_access=Идентификация и доступ diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 167ecaf24a..2a0b9394d5 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -1955,6 +1955,7 @@ teams.all_repositories_write_permission_desc=මෙම කණ්ඩායම ප teams.all_repositories_admin_permission_desc=මෙම කණ්ඩායම ප්රදානය කරයි පරිපාලක වෙත ප්රවේශය සියලු ගබඩාවන්ට: සාමාජිකයින්ට කියවීමට, තල්ලු කිරීමට සහ ගබඩාවන්ට සහයෝගීකයින් එකතු කිරීමට. + [admin] dashboard=උපකරණ පුවරුව users=පරිශීලක ගිණුම් diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini index cd2f915755..e323c2befa 100644 --- a/options/locale/locale_sk-SK.ini +++ b/options/locale/locale_sk-SK.ini @@ -53,6 +53,7 @@ webauthn_reload=Znovu načítať repository=Repozitár organization=Organizácia mirror=Zrkadlo +issue_milestone=Míľnik new_repo=Nový repozitár new_migrate=Nová migrácia new_mirror=Nové zrkadlo @@ -967,6 +968,7 @@ labels=Štítky org_labels_desc=Štítky na úrovni organizácie, ktoré možno použiť so všetkými repozitármi v rámci tejto organizácie org_labels_desc_manage=spravovať +milestone=Míľnik milestones=Míľniky commits=Commitov release=Vydanie @@ -1236,6 +1238,7 @@ teams.all_repositories_write_permission_desc=Tomuto tímu je pridelený prístup teams.all_repositories_admin_permission_desc=Tomuto tímu je pridelený Admin prístup ku všetkým repozitárom: členovia môžu prezerať, nahrávať do repozitárov a pridávať do nich spolupracovníkov. + [admin] repositories=Repozitáre hooks=Webhooky diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index 0315ebe9a1..d43cf655ae 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -1592,6 +1592,7 @@ teams.all_repositories_write_permission_desc=Detta team beviljar SkrivAdmin-rättigheter till alla utvecklingskataloger: medlemmar kan läsa från, pusha till och lägga till kollaboratörer för utvecklingskatalogerna. + [admin] dashboard=Instrumentpanel users=Användarkonto diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 6d14f512ff..39f5bd5978 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -54,6 +54,7 @@ webauthn_reload=Yeniden yükle repository=Depo organization=Organizasyon mirror=Yansı +issue_milestone=Dönüm noktası new_repo=Yeni Depo new_migrate=Yeni Göç new_mirror=Yeni Yansı @@ -78,7 +79,7 @@ forks=Çatallar activities=Etkinlikler pull_requests=Değişiklik İstekleri issues=Konular -milestones=Kilometre Taşları +milestones=Dönüm noktaları ok=Tamam cancel=İptal @@ -1128,7 +1129,7 @@ migrate_options_lfs_endpoint.description.local=Yerel bir sunucu yolu da destekle migrate_options_lfs_endpoint.placeholder=Boş bırakılırsa, uç nokta klon URL'sinden türetilecektir migrate_items=Göç Öğeleri migrate_items_wiki=Wiki -migrate_items_milestones=Kilometre Taşları +migrate_items_milestones=Dönüm noktaları migrate_items_labels=Etiketler migrate_items_issues=Konular migrate_items_pullrequests=Değişiklik İstekleri @@ -1212,6 +1213,7 @@ labels=Etiketler org_labels_desc=Bu organizasyon altında tüm depolarla kullanılabilen organizasyon düzeyinde etiketler org_labels_desc_manage=yönet +milestone=Dönüm noktası milestones=Kilometre Taşları commits=İşleme commit=İşle @@ -2752,6 +2754,7 @@ teams.invite.by=%s tarafından davet edildi teams.invite.description=Takıma katılmak için aşağıdaki düğmeye tıklayın. + [admin] maintenance=Bakım dashboard=Pano diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 2b0e57c8e0..011a86abf6 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -37,6 +37,7 @@ webauthn_reload=Оновити repository=Репозиторій organization=Організація mirror=Дзеркало +issue_milestone=Етап new_repo=Новий репозиторій new_migrate=Нова міграція new_mirror=Нове дзеркало @@ -889,6 +890,7 @@ labels=Мітки org_labels_desc=Мітки рівня організації можуть використовуватися в усіх репозиторіях цієї організації org_labels_desc_manage=керувати +milestone=Етап milestones=Етап commits=Коміти commit=Коміт @@ -2003,6 +2005,7 @@ teams.all_repositories_write_permission_desc=Ця команда надає до teams.all_repositories_admin_permission_desc=Ця команда надає дозвіл Адміністрування для всіх репозиторіїв: учасники можуть переглядати, виконувати push та додавати співробітників. + [admin] dashboard=Панель управління users=Облікові записи користувачів diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 92de8a1280..a1c3d75913 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -54,6 +54,7 @@ webauthn_reload=重新加载 repository=仓库 organization=组织 mirror=镜像 +issue_milestone=里程碑 new_repo=创建仓库 new_migrate=迁移外部仓库 new_mirror=创建新的镜像 @@ -1247,6 +1248,7 @@ labels=标签 org_labels_desc=组织级别的标签,可以被本组织下的 所有仓库 使用 org_labels_desc_manage=管理 +milestone=里程碑 milestones=里程碑 commits=提交 commit=提交 @@ -2854,6 +2856,7 @@ teams.invite.by=邀请人 %s teams.invite.description=请点击下面的按钮加入团队。 + [admin] maintenance=维护 dashboard=管理面板 diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index 77f8d8a25d..eb11ee3a4a 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -685,6 +685,7 @@ teams.delete_team_success=該團隊已被刪除。 teams.repositories=團隊儲存庫 + [admin] dashboard=控制面版 organizations=組織管理 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index d03d9cf1fa..b84aaf1e1f 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -54,6 +54,7 @@ webauthn_reload=重新載入 repository=儲存庫 organization=組織 mirror=鏡像 +issue_milestone=里程碑 new_repo=新增儲存庫 new_migrate=遷移外部儲存庫 new_mirror=新鏡像 @@ -1241,6 +1242,7 @@ labels=標籤 org_labels_desc=組織層級標籤可用於此組織下的所有存儲庫。 org_labels_desc_manage=管理 +milestone=里程碑 milestones=里程碑 commits=提交歷史 commit=提交 @@ -2845,6 +2847,7 @@ teams.invite.by=邀請人 %s teams.invite.description=請點擊下方按鈕加入團隊。 + [admin] maintenance=維護 dashboard=資訊主頁 From a4676db7dd654705214b2568c2def8c8bcfb9777 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 3 Feb 2025 19:25:59 -0800 Subject: [PATCH 054/655] Fix commit status events (#33320) Fix #32873 Fix #33201 ~Fix #33244~ ~Fix #33302~ depends on ~#33396~ A part of this PR should be backported to v1.23 manually. --- options/locale/locale_en-US.ini | 2 + routers/web/repo/setting/webhook.go | 1 + services/forms/repo_form.go | 1 + services/webhook/dingtalk.go | 6 +++ services/webhook/discord.go | 6 +++ services/webhook/feishu.go | 6 +++ services/webhook/general.go | 12 ++++++ services/webhook/matrix.go | 7 ++++ services/webhook/msteams.go | 14 +++++++ services/webhook/packagist.go | 4 ++ services/webhook/payloader.go | 3 ++ services/webhook/slack.go | 6 +++ services/webhook/telegram.go | 6 +++ services/webhook/wechatwork.go | 6 +++ templates/repo/settings/webhook/settings.tmpl | 11 ++++++ tests/integration/repo_webhook_test.go | 39 +++++++++++++++++++ 16 files changed, 130 insertions(+) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 886628e4ff..2842ad16e7 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2331,6 +2331,8 @@ settings.event_fork = Fork settings.event_fork_desc = Repository forked. settings.event_wiki = Wiki settings.event_wiki_desc = Wiki page created, renamed, edited or deleted. +settings.event_statuses = Statuses +settings.event_statuses_desc = Commit Status updated from the API. settings.event_release = Release settings.event_release_desc = Release published, updated or deleted in a repository. settings.event_push = Push diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 997145b507..4ff2467041 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -184,6 +184,7 @@ func ParseHookEvent(form forms.WebhookForm) *webhook_module.HookEvent { webhook_module.HookEventWiki: form.Wiki, webhook_module.HookEventRepository: form.Repository, webhook_module.HookEventPackage: form.Package, + webhook_module.HookEventStatus: form.Status, }, BranchFilter: form.BranchFilter, } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 2c6373e03c..70019f3fa9 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -243,6 +243,7 @@ type WebhookForm struct { Repository bool Release bool Package bool + Status bool Active bool BranchFilter string `binding:"GlobPattern"` AuthorizationHeader string diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go index 992b8c566f..3ea8f50764 100644 --- a/services/webhook/dingtalk.go +++ b/services/webhook/dingtalk.go @@ -170,6 +170,12 @@ func (dc dingtalkConvertor) Package(p *api.PackagePayload) (DingtalkPayload, err return createDingtalkPayload(text, text, "view package", p.Package.HTMLURL), nil } +func (dc dingtalkConvertor) Status(p *api.CommitStatusPayload) (DingtalkPayload, error) { + text, _ := getStatusPayloadInfo(p, noneLinkFormatter, true) + + return createDingtalkPayload(text, text, "Status Changed", p.TargetURL), nil +} + func createDingtalkPayload(title, text, singleTitle, singleURL string) DingtalkPayload { return DingtalkPayload{ MsgType: "actionCard", diff --git a/services/webhook/discord.go b/services/webhook/discord.go index 30d930062e..43e5e533bf 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -265,6 +265,12 @@ func (d discordConvertor) Package(p *api.PackagePayload) (DiscordPayload, error) return d.createPayload(p.Sender, text, "", p.Package.HTMLURL, color), nil } +func (d discordConvertor) Status(p *api.CommitStatusPayload) (DiscordPayload, error) { + text, color := getStatusPayloadInfo(p, noneLinkFormatter, false) + + return d.createPayload(p.Sender, text, "", p.TargetURL, color), nil +} + func newDiscordRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) { meta := &DiscordMeta{} if err := json.Unmarshal([]byte(w.Meta), meta); err != nil { diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go index 4e6aebc39d..639118d2a5 100644 --- a/services/webhook/feishu.go +++ b/services/webhook/feishu.go @@ -166,6 +166,12 @@ func (fc feishuConvertor) Package(p *api.PackagePayload) (FeishuPayload, error) return newFeishuTextPayload(text), nil } +func (fc feishuConvertor) Status(p *api.CommitStatusPayload) (FeishuPayload, error) { + text, _ := getStatusPayloadInfo(p, noneLinkFormatter, true) + + return newFeishuTextPayload(text), nil +} + func newFeishuRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) { var pc payloadConvertor[FeishuPayload] = feishuConvertor{} return newJSONRequest(pc, w, t, true) diff --git a/services/webhook/general.go b/services/webhook/general.go index dde43bb349..91bf68600f 100644 --- a/services/webhook/general.go +++ b/services/webhook/general.go @@ -307,6 +307,18 @@ func getPackagePayloadInfo(p *api.PackagePayload, linkFormatter linkFormatter, w return text, color } +func getStatusPayloadInfo(p *api.CommitStatusPayload, linkFormatter linkFormatter, withSender bool) (text string, color int) { + refLink := linkFormatter(p.TargetURL, p.Context+"["+p.SHA+"]:"+p.Description) + + text = fmt.Sprintf("Commit Status changed: %s", refLink) + color = greenColor + if withSender { + text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + } + + return text, color +} + // ToHook convert models.Webhook to api.Hook // This function is not part of the convert package to prevent an import cycle func ToHook(repoLink string, w *webhook_model.Webhook) (*api.Hook, error) { diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go index 96dfa139ac..ec21712837 100644 --- a/services/webhook/matrix.go +++ b/services/webhook/matrix.go @@ -244,6 +244,13 @@ func (m matrixConvertor) Package(p *api.PackagePayload) (MatrixPayload, error) { return m.newPayload(text) } +func (m matrixConvertor) Status(p *api.CommitStatusPayload) (MatrixPayload, error) { + refLink := htmlLinkFormatter(p.TargetURL, p.Context+"["+p.SHA+"]:"+p.Description) + text := fmt.Sprintf("Commit Status changed: %s", refLink) + + return m.newPayload(text) +} + var urlRegex = regexp.MustCompile(`]*?href="([^">]*?)">(.*?)`) func getMessageBody(htmlText string) string { diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go index 1ae7c4f931..485f695be2 100644 --- a/services/webhook/msteams.go +++ b/services/webhook/msteams.go @@ -303,6 +303,20 @@ func (m msteamsConvertor) Package(p *api.PackagePayload) (MSTeamsPayload, error) ), nil } +func (m msteamsConvertor) Status(p *api.CommitStatusPayload) (MSTeamsPayload, error) { + title, color := getStatusPayloadInfo(p, noneLinkFormatter, false) + + return createMSTeamsPayload( + p.Repo, + p.Sender, + title, + "", + p.TargetURL, + color, + &MSTeamsFact{"CommitStatus:", p.Context}, + ), nil +} + func createMSTeamsPayload(r *api.Repository, s *api.User, title, text, actionTarget string, color int, fact *MSTeamsFact) MSTeamsPayload { facts := make([]MSTeamsFact, 0, 2) if r != nil { diff --git a/services/webhook/packagist.go b/services/webhook/packagist.go index e66895832b..6864fc822a 100644 --- a/services/webhook/packagist.go +++ b/services/webhook/packagist.go @@ -110,6 +110,10 @@ func (pc packagistConvertor) Package(_ *api.PackagePayload) (PackagistPayload, e return PackagistPayload{}, nil } +func (pc packagistConvertor) Status(_ *api.CommitStatusPayload) (PackagistPayload, error) { + return PackagistPayload{}, nil +} + func newPackagistRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) { meta := &PackagistMeta{} if err := json.Unmarshal([]byte(w.Meta), meta); err != nil { diff --git a/services/webhook/payloader.go b/services/webhook/payloader.go index ab280a25b6..c29ad8ac92 100644 --- a/services/webhook/payloader.go +++ b/services/webhook/payloader.go @@ -28,6 +28,7 @@ type payloadConvertor[T any] interface { Release(*api.ReleasePayload) (T, error) Wiki(*api.WikiPayload) (T, error) Package(*api.PackagePayload) (T, error) + Status(*api.CommitStatusPayload) (T, error) } func convertUnmarshalledJSON[T, P any](convert func(P) (T, error), data []byte) (t T, err error) { @@ -77,6 +78,8 @@ func newPayload[T any](rc payloadConvertor[T], data []byte, event webhook_module return convertUnmarshalledJSON(rc.Wiki, data) case webhook_module.HookEventPackage: return convertUnmarshalledJSON(rc.Package, data) + case webhook_module.HookEventStatus: + return convertUnmarshalledJSON(rc.Status, data) } return t, fmt.Errorf("newPayload unsupported event: %s", event) } diff --git a/services/webhook/slack.go b/services/webhook/slack.go index 0371ee23e6..80ed747fd1 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -167,6 +167,12 @@ func (s slackConvertor) Package(p *api.PackagePayload) (SlackPayload, error) { return s.createPayload(text, nil), nil } +func (s slackConvertor) Status(p *api.CommitStatusPayload) (SlackPayload, error) { + text, _ := getStatusPayloadInfo(p, SlackLinkFormatter, true) + + return s.createPayload(text, nil), nil +} + // Push implements payloadConvertor Push method func (s slackConvertor) Push(p *api.PushPayload) (SlackPayload, error) { // n new commits diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go index 6fbf995801..485e2d990b 100644 --- a/services/webhook/telegram.go +++ b/services/webhook/telegram.go @@ -174,6 +174,12 @@ func (t telegramConvertor) Package(p *api.PackagePayload) (TelegramPayload, erro return createTelegramPayloadHTML(text), nil } +func (t telegramConvertor) Status(p *api.CommitStatusPayload) (TelegramPayload, error) { + text, _ := getStatusPayloadInfo(p, htmlLinkFormatter, true) + + return createTelegramPayloadHTML(text), nil +} + func createTelegramPayloadHTML(msgHTML string) TelegramPayload { // https://core.telegram.org/bots/api#formatting-options return TelegramPayload{ diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go index 44e0ff7de5..1c834b4020 100644 --- a/services/webhook/wechatwork.go +++ b/services/webhook/wechatwork.go @@ -175,6 +175,12 @@ func (wc wechatworkConvertor) Package(p *api.PackagePayload) (WechatworkPayload, return newWechatworkMarkdownPayload(text), nil } +func (wc wechatworkConvertor) Status(p *api.CommitStatusPayload) (WechatworkPayload, error) { + text, _ := getStatusPayloadInfo(p, noneLinkFormatter, true) + + return newWechatworkMarkdownPayload(text), nil +} + func newWechatworkRequest(_ context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) { var pc payloadConvertor[WechatworkPayload] = wechatworkConvertor{} return newJSONRequest(pc, w, t, true) diff --git a/templates/repo/settings/webhook/settings.tmpl b/templates/repo/settings/webhook/settings.tmpl index 1a01a6aea8..3b28a4c6c0 100644 --- a/templates/repo/settings/webhook/settings.tmpl +++ b/templates/repo/settings/webhook/settings.tmpl @@ -109,6 +109,17 @@
+ +
+
+
+ + + {{ctx.Locale.Tr "repo.settings.event_statuses_desc"}} +
+
+
+
diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go index 17905513c3..2f9a815fef 100644 --- a/tests/integration/repo_webhook_test.go +++ b/tests/integration/repo_webhook_test.go @@ -16,6 +16,7 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/json" api "code.gitea.io/gitea/modules/structs" @@ -66,6 +67,19 @@ func testAPICreateWebhookForRepo(t *testing.T, session *TestSession, userName, r MakeRequest(t, req, http.StatusCreated) } +func testCreateWebhookForRepo(t *testing.T, session *TestSession, webhookType, userName, repoName, url, eventKind string) { + csrf := GetUserCSRFToken(t, session) + req := NewRequestWithValues(t, "POST", "/"+userName+"/"+repoName+"/settings/hooks/"+webhookType+"/new", map[string]string{ + "_csrf": csrf, + "payload_url": url, + "events": eventKind, + "active": "true", + "content_type": fmt.Sprintf("%d", webhook.ContentTypeJSON), + "http_method": "POST", + }) + session.MakeRequest(t, req, http.StatusSeeOther) +} + func testAPICreateWebhookForOrg(t *testing.T, session *TestSession, userName, url, event string) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll) req := NewRequestWithJSON(t, "POST", "/api/v1/orgs/"+userName+"/hooks", api.CreateHookOption{ @@ -562,3 +576,28 @@ func Test_WebhookStatus(t *testing.T) { assert.EqualValues(t, commitID, payloads[0].SHA) }) } + +func Test_WebhookStatus_NoWrongTrigger(t *testing.T) { + var trigger string + provider := newMockWebhookProvider(func(r *http.Request) { + assert.NotContains(t, r.Header["X-Github-Event-Type"], "status", "X-GitHub-Event-Type should not contain status") + assert.NotContains(t, r.Header["X-Gitea-Event-Type"], "status", "X-Gitea-Event-Type should not contain status") + assert.NotContains(t, r.Header["X-Gogs-Event-Type"], "status", "X-Gogs-Event-Type should not contain status") + trigger = "push" + }, http.StatusOK) + defer provider.Close() + + onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { + // 1. create a new webhook with special webhook for repo1 + session := loginUser(t, "user2") + + // create a push_only webhook from web UI + testCreateWebhookForRepo(t, session, "gitea", "user2", "repo1", provider.URL(), "push_only") + + // 2. trigger the webhook with a push action + testCreateFile(t, session, "user2", "repo1", "master", "test_webhook_push.md", "# a test file for webhook push") + + // 3. validate the webhook is triggered with right event + assert.EqualValues(t, "push", trigger) + }) +} From d0f4e92563e3486f87c2758c76bd774bdbc63738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrique=20Corr=C3=AAa?= <75134774+HeCorr@users.noreply.github.com> Date: Tue, 4 Feb 2025 02:21:23 -0300 Subject: [PATCH 055/655] Reject star-related requests if stars are disabled (#33208) This PR fixes #33205. If stars are disabled: * The `.../repo/stars` page returns a 403 Forbidden error * Star-related API endpoints return a 403 Forbidden error saying `Stars are disabled.` * Same for action endpoints --------- Co-authored-by: wxiaoguang --- routers/api/v1/api.go | 16 +++++-- routers/api/v1/repo/star.go | 2 + routers/api/v1/user/star.go | 8 ++++ routers/web/web.go | 13 ++++- templates/swagger/v1_json.tmpl | 15 ++++++ tests/integration/api_user_star_test.go | 64 +++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 5 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 438db4ae71..0aa38b8b6a 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -580,6 +580,16 @@ func reqWebhooksEnabled() func(ctx *context.APIContext) { } } +// reqStarsEnabled requires Starring to be enabled in the config. +func reqStarsEnabled() func(ctx *context.APIContext) { + return func(ctx *context.APIContext) { + if setting.Repository.DisableStars { + ctx.Error(http.StatusForbidden, "", "stars disabled by administrator") + return + } + } +} + func orgAssignment(args ...bool) func(ctx *context.APIContext) { var ( assignOrg bool @@ -995,7 +1005,7 @@ func Routes() *web.Router { m.Get("/{target}", user.CheckFollowing) }) - m.Get("/starred", user.GetStarredRepos) + m.Get("/starred", reqStarsEnabled(), user.GetStarredRepos) m.Get("/subscriptions", user.GetWatchedRepos) }, context.UserAssignmentAPI(), checkTokenPublicOnly()) @@ -1086,7 +1096,7 @@ func Routes() *web.Router { m.Put("", user.Star) m.Delete("", user.Unstar) }, repoAssignment(), checkTokenPublicOnly()) - }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)) + }, reqStarsEnabled(), tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)) m.Get("/times", repo.ListMyTrackedTimes) m.Get("/stopwatches", repo.GetStopwatches) m.Get("/subscriptions", user.GetMyWatchedRepos) @@ -1248,7 +1258,7 @@ func Routes() *web.Router { m.Post("/markup", reqToken(), bind(api.MarkupOption{}), misc.Markup) m.Post("/markdown", reqToken(), bind(api.MarkdownOption{}), misc.Markdown) m.Post("/markdown/raw", reqToken(), misc.MarkdownRaw) - m.Get("/stargazers", repo.ListStargazers) + m.Get("/stargazers", reqStarsEnabled(), repo.ListStargazers) m.Get("/subscribers", repo.ListSubscribers) m.Group("/subscription", func() { m.Get("", user.IsWatching) diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go index 99676de119..46ed17ad91 100644 --- a/routers/api/v1/repo/star.go +++ b/routers/api/v1/repo/star.go @@ -44,6 +44,8 @@ func ListStargazers(ctx *context.APIContext) { // "$ref": "#/responses/UserList" // "404": // "$ref": "#/responses/notFound" + // "403": + // "$ref": "#/responses/forbidden" stargazers, err := repo_model.GetStargazers(ctx, ctx.Repo.Repository, utils.GetListOptions(ctx)) if err != nil { diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go index ad9ed9548d..70e54bc1ae 100644 --- a/routers/api/v1/user/star.go +++ b/routers/api/v1/user/star.go @@ -66,6 +66,8 @@ func GetStarredRepos(ctx *context.APIContext) { // "$ref": "#/responses/RepositoryList" // "404": // "$ref": "#/responses/notFound" + // "403": + // "$ref": "#/responses/forbidden" private := ctx.ContextUser.ID == ctx.Doer.ID repos, err := getStarredRepos(ctx, ctx.ContextUser, private) @@ -97,6 +99,8 @@ func GetMyStarredRepos(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/RepositoryList" + // "403": + // "$ref": "#/responses/forbidden" repos, err := getStarredRepos(ctx, ctx.Doer, true) if err != nil { @@ -128,6 +132,8 @@ func IsStarring(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "404": // "$ref": "#/responses/notFound" + // "403": + // "$ref": "#/responses/forbidden" if repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) { ctx.Status(http.StatusNoContent) @@ -193,6 +199,8 @@ func Unstar(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "404": // "$ref": "#/responses/notFound" + // "403": + // "$ref": "#/responses/forbidden" err := repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, false) if err != nil { diff --git a/routers/web/web.go b/routers/web/web.go index f772f6dbb9..3cb6dc2551 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -347,6 +347,13 @@ func registerRoutes(m *web.Router) { } } + starsEnabled := func(ctx *context.Context) { + if setting.Repository.DisableStars { + ctx.Error(http.StatusForbidden) + return + } + } + lfsServerEnabled := func(ctx *context.Context) { if !setting.LFS.StartServer { ctx.Error(http.StatusNotFound) @@ -1593,10 +1600,12 @@ func registerRoutes(m *web.Router) { // end "/{username}/{reponame}": repo code m.Group("/{username}/{reponame}", func() { - m.Get("/stars", repo.Stars) + m.Get("/stars", starsEnabled, repo.Stars) m.Get("/watchers", repo.Watchers) m.Get("/search", reqUnitCodeReader, repo.Search) - m.Post("/action/{action}", reqSignIn, repo.Action) + m.Post("/action/{action:star|unstar}", reqSignIn, starsEnabled, repo.Action) + m.Post("/action/{action:watch|unwatch}", reqSignIn, repo.Action) + m.Post("/action/{action:accept_transfer|reject_transfer}", reqSignIn, repo.Action) }, optSignIn, context.RepoAssignment) common.AddOwnerRepoGitLFSRoutes(m, optSignInIgnoreCsrf, lfsServerEnabled) // "/{username}/{reponame}/{lfs-paths}": git-lfs support diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index c58b21062d..d22e01c787 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -13808,6 +13808,9 @@ "200": { "$ref": "#/responses/UserList" }, + "403": { + "$ref": "#/responses/forbidden" + }, "404": { "$ref": "#/responses/notFound" } @@ -17546,6 +17549,9 @@ "responses": { "200": { "$ref": "#/responses/RepositoryList" + }, + "403": { + "$ref": "#/responses/forbidden" } } } @@ -17577,6 +17583,9 @@ "204": { "$ref": "#/responses/empty" }, + "403": { + "$ref": "#/responses/forbidden" + }, "404": { "$ref": "#/responses/notFound" } @@ -17642,6 +17651,9 @@ "204": { "$ref": "#/responses/empty" }, + "403": { + "$ref": "#/responses/forbidden" + }, "404": { "$ref": "#/responses/notFound" } @@ -18318,6 +18330,9 @@ "200": { "$ref": "#/responses/RepositoryList" }, + "403": { + "$ref": "#/responses/forbidden" + }, "404": { "$ref": "#/responses/notFound" } diff --git a/tests/integration/api_user_star_test.go b/tests/integration/api_user_star_test.go index 0062889a92..368756528a 100644 --- a/tests/integration/api_user_star_test.go +++ b/tests/integration/api_user_star_test.go @@ -11,7 +11,9 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" @@ -91,3 +93,65 @@ func TestAPIStar(t *testing.T) { MakeRequest(t, req, http.StatusNoContent) }) } + +func TestAPIStarDisabled(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user := "user1" + repo := "user2/repo1" + + session := loginUser(t, user) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) + tokenWithUserScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser, auth_model.AccessTokenScopeWriteRepository) + + defer test.MockVariableValue(&setting.Repository.DisableStars, true)() + + t.Run("Star", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + AddTokenAuth(tokenWithUserScope) + MakeRequest(t, req, http.StatusForbidden) + + user34 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 34}) + req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + AddTokenAuth(getUserToken(t, user34.Name, auth_model.AccessTokenScopeWriteRepository)) + MakeRequest(t, req, http.StatusForbidden) + }) + + t.Run("GetStarredRepos", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/starred", user)). + AddTokenAuth(token) + MakeRequest(t, req, http.StatusForbidden) + }) + + t.Run("GetMyStarredRepos", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/api/v1/user/starred"). + AddTokenAuth(tokenWithUserScope) + MakeRequest(t, req, http.StatusForbidden) + }) + + t.Run("IsStarring", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + AddTokenAuth(tokenWithUserScope) + MakeRequest(t, req, http.StatusForbidden) + + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s", repo+"notexisting")). + AddTokenAuth(tokenWithUserScope) + MakeRequest(t, req, http.StatusForbidden) + }) + + t.Run("Unstar", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + AddTokenAuth(tokenWithUserScope) + MakeRequest(t, req, http.StatusForbidden) + }) +} From 09a3b07f108fff645628f2f7059ca9e4b4822880 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 5 Feb 2025 02:14:03 +0800 Subject: [PATCH 056/655] Refactor web route handler (#33488) --- routers/web/org/home.go | 2 +- routers/web/repo/repo.go | 91 --------- routers/web/repo/star.go | 31 ++++ routers/web/repo/transfer.go | 38 ++++ routers/web/repo/watch.go | 31 ++++ routers/web/user/profile.go | 6 +- routers/web/web.go | 25 +-- services/context/org.go | 348 ++++++++++++++++------------------- 8 files changed, 279 insertions(+), 293 deletions(-) create mode 100644 routers/web/repo/star.go create mode 100644 routers/web/repo/transfer.go create mode 100644 routers/web/repo/watch.go diff --git a/routers/web/org/home.go b/routers/web/org/home.go index 277adb60ca..27d1e14d85 100644 --- a/routers/web/org/home.go +++ b/routers/web/org/home.go @@ -34,7 +34,7 @@ func Home(ctx *context.Context) { } ctx.SetPathParam("org", uname) - context.HandleOrgAssignment(ctx) + context.OrgAssignment(context.OrgAssignmentOptions{})(ctx) if ctx.Written() { return } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 8ebf5bcf39..0d4513ec67 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -304,31 +304,6 @@ func CreatePost(ctx *context.Context) { handleCreateError(ctx, ctxUser, err, "CreatePost", tplCreate, &form) } -const ( - tplWatchUnwatch templates.TplName = "repo/watch_unwatch" - tplStarUnstar templates.TplName = "repo/star_unstar" -) - -func acceptTransfer(ctx *context.Context) { - err := repo_service.AcceptTransferOwnership(ctx, ctx.Repo.Repository, ctx.Doer) - if err == nil { - ctx.Flash.Success(ctx.Tr("repo.settings.transfer.success")) - ctx.Redirect(ctx.Repo.Repository.Link()) - return - } - handleActionError(ctx, err) -} - -func rejectTransfer(ctx *context.Context) { - err := repo_service.RejectRepositoryTransfer(ctx, ctx.Repo.Repository, ctx.Doer) - if err == nil { - ctx.Flash.Success(ctx.Tr("repo.settings.transfer.rejected")) - ctx.Redirect(ctx.Repo.Repository.Link()) - return - } - handleActionError(ctx, err) -} - func handleActionError(ctx *context.Context, err error) { if errors.Is(err, user_model.ErrBlockedUser) { ctx.Flash.Error(ctx.Tr("repo.action.blocked_user")) @@ -339,72 +314,6 @@ func handleActionError(ctx *context.Context, err error) { } } -// Action response for actions to a repository -func Action(ctx *context.Context) { - var err error - switch ctx.PathParam("action") { - case "watch": - err = repo_model.WatchRepo(ctx, ctx.Doer, ctx.Repo.Repository, true) - case "unwatch": - err = repo_model.WatchRepo(ctx, ctx.Doer, ctx.Repo.Repository, false) - case "star": - err = repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, true) - case "unstar": - err = repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, false) - case "accept_transfer": - acceptTransfer(ctx) - return - case "reject_transfer": - rejectTransfer(ctx) - return - case "desc": // FIXME: this is not used - if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusNotFound) - return - } - - ctx.Repo.Repository.Description = ctx.FormString("desc") - ctx.Repo.Repository.Website = ctx.FormString("site") - err = repo_service.UpdateRepository(ctx, ctx.Repo.Repository, false) - } - - if err != nil { - handleActionError(ctx, err) - return - } - - switch ctx.PathParam("action") { - case "watch", "unwatch": - ctx.Data["IsWatchingRepo"] = repo_model.IsWatching(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) - case "star", "unstar": - ctx.Data["IsStaringRepo"] = repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) - } - - // see the `hx-trigger="refreshUserCards ..."` comments in tmpl - ctx.RespHeader().Add("hx-trigger", "refreshUserCards") - - switch ctx.PathParam("action") { - case "watch", "unwatch", "star", "unstar": - // we have to reload the repository because NumStars or NumWatching (used in the templates) has just changed - ctx.Data["Repository"], err = repo_model.GetRepositoryByName(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.Name) - if err != nil { - ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.PathParam("action")), err) - return - } - } - - switch ctx.PathParam("action") { - case "watch", "unwatch": - ctx.HTML(http.StatusOK, tplWatchUnwatch) - return - case "star", "unstar": - ctx.HTML(http.StatusOK, tplStarUnstar) - return - } - - ctx.RedirectToCurrentSite(ctx.FormString("redirect_to"), ctx.Repo.RepoLink) -} - // RedirectDownload return a file based on the following infos: func RedirectDownload(ctx *context.Context) { var ( diff --git a/routers/web/repo/star.go b/routers/web/repo/star.go new file mode 100644 index 0000000000..00c06b7d02 --- /dev/null +++ b/routers/web/repo/star.go @@ -0,0 +1,31 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "net/http" + + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/services/context" +) + +const tplStarUnstar templates.TplName = "repo/star_unstar" + +func ActionStar(ctx *context.Context) { + err := repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, ctx.PathParam("action") == "star") + if err != nil { + handleActionError(ctx, err) + return + } + + ctx.Data["IsStaringRepo"] = repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) + ctx.Data["Repository"], err = repo_model.GetRepositoryByName(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.Name) + if err != nil { + ctx.ServerError("GetRepositoryByName", err) + return + } + ctx.RespHeader().Add("hx-trigger", "refreshUserCards") // see the `hx-trigger="refreshUserCards ..."` comments in tmpl + ctx.HTML(http.StatusOK, tplStarUnstar) +} diff --git a/routers/web/repo/transfer.go b/routers/web/repo/transfer.go new file mode 100644 index 0000000000..5553eee674 --- /dev/null +++ b/routers/web/repo/transfer.go @@ -0,0 +1,38 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "code.gitea.io/gitea/services/context" + repo_service "code.gitea.io/gitea/services/repository" +) + +func acceptTransfer(ctx *context.Context) { + err := repo_service.AcceptTransferOwnership(ctx, ctx.Repo.Repository, ctx.Doer) + if err == nil { + ctx.Flash.Success(ctx.Tr("repo.settings.transfer.success")) + ctx.Redirect(ctx.Repo.Repository.Link()) + return + } + handleActionError(ctx, err) +} + +func rejectTransfer(ctx *context.Context) { + err := repo_service.RejectRepositoryTransfer(ctx, ctx.Repo.Repository, ctx.Doer) + if err == nil { + ctx.Flash.Success(ctx.Tr("repo.settings.transfer.rejected")) + ctx.Redirect(ctx.Repo.Repository.Link()) + return + } + handleActionError(ctx, err) +} + +func ActionTransfer(ctx *context.Context) { + switch ctx.PathParam("action") { + case "accept_transfer": + acceptTransfer(ctx) + case "reject_transfer": + rejectTransfer(ctx) + } +} diff --git a/routers/web/repo/watch.go b/routers/web/repo/watch.go new file mode 100644 index 0000000000..70c548b8ce --- /dev/null +++ b/routers/web/repo/watch.go @@ -0,0 +1,31 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "net/http" + + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/services/context" +) + +const tplWatchUnwatch templates.TplName = "repo/watch_unwatch" + +func ActionWatch(ctx *context.Context) { + err := repo_model.WatchRepo(ctx, ctx.Doer, ctx.Repo.Repository, ctx.PathParam("action") == "watch") + if err != nil { + handleActionError(ctx, err) + return + } + + ctx.Data["IsWatchingRepo"] = repo_model.IsWatching(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) + ctx.Data["Repository"], err = repo_model.GetRepositoryByName(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.Name) + if err != nil { + ctx.ServerError("GetRepositoryByName", err) + return + } + ctx.RespHeader().Add("hx-trigger", "refreshUserCards") // see the `hx-trigger="refreshUserCards ..."` comments in tmpl + ctx.HTML(http.StatusOK, tplWatchUnwatch) +} diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 006ffdcf7e..7cda3c038c 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -313,8 +313,8 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb ctx.Data["Page"] = pager } -// Action response for follow/unfollow user request -func Action(ctx *context.Context) { +// ActionUserFollow is for follow/unfollow user request +func ActionUserFollow(ctx *context.Context) { var err error switch ctx.FormString("action") { case "follow": @@ -339,6 +339,6 @@ func Action(ctx *context.Context) { ctx.HTML(http.StatusOK, tplFollowUnfollow) return } - log.Error("Failed to apply action %q: unsupport context user type: %s", ctx.FormString("action"), ctx.ContextUser.Type) + log.Error("Failed to apply action %q: unsupported context user type: %s", ctx.FormString("action"), ctx.ContextUser.Type) ctx.Error(http.StatusBadRequest, fmt.Sprintf("Action %q failed", ctx.FormString("action"))) } diff --git a/routers/web/web.go b/routers/web/web.go index 3cb6dc2551..0963565c6a 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -822,7 +822,7 @@ func registerRoutes(m *web.Router) { m.Methods("GET, OPTIONS", "/attachments/{uuid}", optionsCorsHandler(), repo.GetAttachment) }, optSignIn) - m.Post("/{username}", reqSignIn, context.UserAssignmentWeb(), user.Action) + m.Post("/{username}", reqSignIn, context.UserAssignmentWeb(), user.ActionUserFollow) reqRepoAdmin := context.RequireRepoAdmin() reqRepoCodeWriter := context.RequireUnitWriter(unit.TypeCode) @@ -872,7 +872,7 @@ func registerRoutes(m *web.Router) { m.Group("/org", func() { m.Group("/{org}", func() { m.Get("/members", org.Members) - }, context.OrgAssignment()) + }, context.OrgAssignment(context.OrgAssignmentOptions{})) }, optSignIn) // end "/org": members @@ -898,19 +898,20 @@ func registerRoutes(m *web.Router) { m.Get("/milestones/{team}", reqMilestonesDashboardPageEnabled, user.Milestones) m.Post("/members/action/{action}", org.MembersAction) m.Get("/teams", org.Teams) - }, context.OrgAssignment(true, false, true)) + }, context.OrgAssignment(context.OrgAssignmentOptions{RequireMember: true, RequireTeamMember: true})) m.Group("/{org}", func() { m.Get("/teams/{team}", org.TeamMembers) m.Get("/teams/{team}/repositories", org.TeamRepositories) m.Post("/teams/{team}/action/{action}", org.TeamsAction) m.Post("/teams/{team}/action/repo/{action}", org.TeamsRepoAction) - }, context.OrgAssignment(true, false, true)) + }, context.OrgAssignment(context.OrgAssignmentOptions{RequireMember: true, RequireTeamMember: true})) - // require admin permission + // require member/team-admin permission (old logic is: requireMember=true, requireTeamAdmin=true) + // but it doesn't seem right: requireTeamAdmin does nothing m.Group("/{org}", func() { m.Get("/teams/-/search", org.SearchTeam) - }, context.OrgAssignment(true, false, false, true)) + }, context.OrgAssignment(context.OrgAssignmentOptions{RequireMember: true, RequireTeamAdmin: true})) // require owner permission m.Group("/{org}", func() { @@ -920,7 +921,7 @@ func registerRoutes(m *web.Router) { m.Post("/teams/{team}/edit", web.Bind(forms.CreateTeamForm{}), org.EditTeamPost) m.Post("/teams/{team}/delete", org.DeleteTeam) - m.Get("/worktime", context.OrgAssignment(false, true), org.Worktime) + m.Get("/worktime", context.OrgAssignment(context.OrgAssignmentOptions{RequireOwner: true}), org.Worktime) m.Group("/settings", func() { m.Combo("").Get(org.Settings). @@ -989,7 +990,7 @@ func registerRoutes(m *web.Router) { m.Post("", web.Bind(forms.BlockUserForm{}), org.BlockedUsersPost) }) }, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled, "PageIsOrgSettings", true)) - }, context.OrgAssignment(true, true)) + }, context.OrgAssignment(context.OrgAssignmentOptions{RequireOwner: true})) }, reqSignIn) // end "/org": most org routes @@ -1059,7 +1060,7 @@ func registerRoutes(m *web.Router) { m.Group("", func() { m.Get("/code", user.CodeSearch) }, reqUnitAccess(unit.TypeCode, perm.AccessModeRead, false), individualPermsChecker) - }, optSignIn, context.UserAssignmentWeb(), context.OrgAssignment()) + }, optSignIn, context.UserAssignmentWeb(), context.OrgAssignment(context.OrgAssignmentOptions{})) // end "/{username}/-": packages, projects, code m.Group("/{username}/{reponame}/-", func() { @@ -1603,9 +1604,9 @@ func registerRoutes(m *web.Router) { m.Get("/stars", starsEnabled, repo.Stars) m.Get("/watchers", repo.Watchers) m.Get("/search", reqUnitCodeReader, repo.Search) - m.Post("/action/{action:star|unstar}", reqSignIn, starsEnabled, repo.Action) - m.Post("/action/{action:watch|unwatch}", reqSignIn, repo.Action) - m.Post("/action/{action:accept_transfer|reject_transfer}", reqSignIn, repo.Action) + m.Post("/action/{action:star|unstar}", reqSignIn, starsEnabled, repo.ActionStar) + m.Post("/action/{action:watch|unwatch}", reqSignIn, repo.ActionWatch) + m.Post("/action/{action:accept_transfer|reject_transfer}", reqSignIn, repo.ActionTransfer) }, optSignIn, context.RepoAssignment) common.AddOwnerRepoGitLFSRoutes(m, optSignInIgnoreCsrf, lfsServerEnabled) // "/{username}/{reponame}/{lfs-paths}": git-lfs support diff --git a/services/context/org.go b/services/context/org.go index f4597a4ce1..3f73165076 100644 --- a/services/context/org.go +++ b/services/context/org.go @@ -62,217 +62,193 @@ func GetOrganizationByParams(ctx *Context) { } } -// HandleOrgAssignment handles organization assignment -// args: requireMember, requireOwner, requireTeamMember, requireTeamAdmin -func HandleOrgAssignment(ctx *Context, args ...bool) { - var ( - requireMember bool - requireOwner bool - requireTeamMember bool - requireTeamAdmin bool - ) - if len(args) >= 1 { - requireMember = args[0] - } - if len(args) >= 2 { - requireOwner = args[1] - } - if len(args) >= 3 { - requireTeamMember = args[2] - } - if len(args) >= 4 { - requireTeamAdmin = args[3] - } +type OrgAssignmentOptions struct { + RequireMember bool + RequireOwner bool + RequireTeamMember bool + RequireTeamAdmin bool +} - var err error - - if ctx.ContextUser == nil { - // if Organization is not defined, get it from params - if ctx.Org.Organization == nil { - GetOrganizationByParams(ctx) - if ctx.Written() { - return +// OrgAssignment returns a middleware to handle organization assignment +func OrgAssignment(opts OrgAssignmentOptions) func(ctx *Context) { + return func(ctx *Context) { + var err error + if ctx.ContextUser == nil { + // if Organization is not defined, get it from params + if ctx.Org.Organization == nil { + GetOrganizationByParams(ctx) + if ctx.Written() { + return + } } - } - } else if ctx.ContextUser.IsOrganization() { - if ctx.Org == nil { - ctx.Org = &Organization{} - } - ctx.Org.Organization = (*organization.Organization)(ctx.ContextUser) - } else { - // ContextUser is an individual User - return - } - - org := ctx.Org.Organization - - // Handle Visibility - if org.Visibility != structs.VisibleTypePublic && !ctx.IsSigned { - // We must be signed in to see limited or private organizations - ctx.NotFound("OrgAssignment", err) - return - } - - if org.Visibility == structs.VisibleTypePrivate { - requireMember = true - } else if ctx.IsSigned && ctx.Doer.IsRestricted { - requireMember = true - } - - ctx.ContextUser = org.AsUser() - ctx.Data["Org"] = org - - // Admin has super access. - if ctx.IsSigned && ctx.Doer.IsAdmin { - ctx.Org.IsOwner = true - ctx.Org.IsMember = true - ctx.Org.IsTeamMember = true - ctx.Org.IsTeamAdmin = true - ctx.Org.CanCreateOrgRepo = true - } else if ctx.IsSigned { - ctx.Org.IsOwner, err = org.IsOwnedBy(ctx, ctx.Doer.ID) - if err != nil { - ctx.ServerError("IsOwnedBy", err) + } else if ctx.ContextUser.IsOrganization() { + ctx.Org.Organization = (*organization.Organization)(ctx.ContextUser) + } else { + // ContextUser is an individual User return } - if ctx.Org.IsOwner { + org := ctx.Org.Organization + + // Handle Visibility + if org.Visibility != structs.VisibleTypePublic && !ctx.IsSigned { + // We must be signed in to see limited or private organizations + ctx.NotFound("OrgAssignment", err) + return + } + + if org.Visibility == structs.VisibleTypePrivate { + opts.RequireMember = true + } else if ctx.IsSigned && ctx.Doer.IsRestricted { + opts.RequireMember = true + } + + ctx.ContextUser = org.AsUser() + ctx.Data["Org"] = org + + // Admin has super access. + if ctx.IsSigned && ctx.Doer.IsAdmin { + ctx.Org.IsOwner = true ctx.Org.IsMember = true ctx.Org.IsTeamMember = true ctx.Org.IsTeamAdmin = true ctx.Org.CanCreateOrgRepo = true + } else if ctx.IsSigned { + ctx.Org.IsOwner, err = org.IsOwnedBy(ctx, ctx.Doer.ID) + if err != nil { + ctx.ServerError("IsOwnedBy", err) + return + } + + if ctx.Org.IsOwner { + ctx.Org.IsMember = true + ctx.Org.IsTeamMember = true + ctx.Org.IsTeamAdmin = true + ctx.Org.CanCreateOrgRepo = true + } else { + ctx.Org.IsMember, err = org.IsOrgMember(ctx, ctx.Doer.ID) + if err != nil { + ctx.ServerError("IsOrgMember", err) + return + } + ctx.Org.CanCreateOrgRepo, err = org.CanCreateOrgRepo(ctx, ctx.Doer.ID) + if err != nil { + ctx.ServerError("CanCreateOrgRepo", err) + return + } + } } else { - ctx.Org.IsMember, err = org.IsOrgMember(ctx, ctx.Doer.ID) - if err != nil { - ctx.ServerError("IsOrgMember", err) - return - } - ctx.Org.CanCreateOrgRepo, err = org.CanCreateOrgRepo(ctx, ctx.Doer.ID) - if err != nil { - ctx.ServerError("CanCreateOrgRepo", err) - return - } + // Fake data. + ctx.Data["SignedUser"] = &user_model.User{} } - } else { - // Fake data. - ctx.Data["SignedUser"] = &user_model.User{} - } - if (requireMember && !ctx.Org.IsMember) || - (requireOwner && !ctx.Org.IsOwner) { - ctx.NotFound("OrgAssignment", err) - return - } - ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner - ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember - ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled - ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled - ctx.Data["IsPublicMember"] = func(uid int64) bool { - is, _ := organization.IsPublicMembership(ctx, ctx.Org.Organization.ID, uid) - return is - } - ctx.Data["CanCreateOrgRepo"] = ctx.Org.CanCreateOrgRepo + if (opts.RequireMember && !ctx.Org.IsMember) || (opts.RequireOwner && !ctx.Org.IsOwner) { + ctx.NotFound("OrgAssignment", err) + return + } + ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner + ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember + ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled + ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + ctx.Data["IsPublicMember"] = func(uid int64) bool { + is, _ := organization.IsPublicMembership(ctx, ctx.Org.Organization.ID, uid) + return is + } + ctx.Data["CanCreateOrgRepo"] = ctx.Org.CanCreateOrgRepo - ctx.Org.OrgLink = org.AsUser().OrganisationLink() - ctx.Data["OrgLink"] = ctx.Org.OrgLink + ctx.Org.OrgLink = org.AsUser().OrganisationLink() + ctx.Data["OrgLink"] = ctx.Org.OrgLink - // Member - opts := &organization.FindOrgMembersOpts{ - Doer: ctx.Doer, - OrgID: org.ID, - IsDoerMember: ctx.Org.IsMember, - } - ctx.Data["NumMembers"], err = organization.CountOrgMembers(ctx, opts) - if err != nil { - ctx.ServerError("CountOrgMembers", err) - return - } + // Member + findMembersOpts := &organization.FindOrgMembersOpts{ + Doer: ctx.Doer, + OrgID: org.ID, + IsDoerMember: ctx.Org.IsMember, + } + ctx.Data["NumMembers"], err = organization.CountOrgMembers(ctx, findMembersOpts) + if err != nil { + ctx.ServerError("CountOrgMembers", err) + return + } - // Team. - if ctx.Org.IsMember { - shouldSeeAllTeams := false - if ctx.Org.IsOwner { - shouldSeeAllTeams = true - } else { - teams, err := org.GetUserTeams(ctx, ctx.Doer.ID) - if err != nil { - ctx.ServerError("GetUserTeams", err) - return + // Team. + if ctx.Org.IsMember { + shouldSeeAllTeams := false + if ctx.Org.IsOwner { + shouldSeeAllTeams = true + } else { + teams, err := org.GetUserTeams(ctx, ctx.Doer.ID) + if err != nil { + ctx.ServerError("GetUserTeams", err) + return + } + for _, team := range teams { + if team.IncludesAllRepositories && team.AccessMode >= perm.AccessModeAdmin { + shouldSeeAllTeams = true + break + } + } } - for _, team := range teams { - if team.IncludesAllRepositories && team.AccessMode >= perm.AccessModeAdmin { - shouldSeeAllTeams = true + if shouldSeeAllTeams { + ctx.Org.Teams, err = org.LoadTeams(ctx) + if err != nil { + ctx.ServerError("LoadTeams", err) + return + } + } else { + ctx.Org.Teams, err = org.GetUserTeams(ctx, ctx.Doer.ID) + if err != nil { + ctx.ServerError("GetUserTeams", err) + return + } + } + ctx.Data["NumTeams"] = len(ctx.Org.Teams) + } + + teamName := ctx.PathParam("team") + if len(teamName) > 0 { + teamExists := false + for _, team := range ctx.Org.Teams { + if team.LowerName == strings.ToLower(teamName) { + teamExists = true + ctx.Org.Team = team + ctx.Org.IsTeamMember = true + ctx.Data["Team"] = ctx.Org.Team break } } - } - if shouldSeeAllTeams { - ctx.Org.Teams, err = org.LoadTeams(ctx) - if err != nil { - ctx.ServerError("LoadTeams", err) + + if !teamExists { + ctx.NotFound("OrgAssignment", err) return } - } else { - ctx.Org.Teams, err = org.GetUserTeams(ctx, ctx.Doer.ID) - if err != nil { - ctx.ServerError("GetUserTeams", err) + + ctx.Data["IsTeamMember"] = ctx.Org.IsTeamMember + if opts.RequireTeamMember && !ctx.Org.IsTeamMember { + ctx.NotFound("OrgAssignment", err) + return + } + + ctx.Org.IsTeamAdmin = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.AccessMode >= perm.AccessModeAdmin + ctx.Data["IsTeamAdmin"] = ctx.Org.IsTeamAdmin + if opts.RequireTeamAdmin && !ctx.Org.IsTeamAdmin { + ctx.NotFound("OrgAssignment", err) return } } - ctx.Data["NumTeams"] = len(ctx.Org.Teams) - } + ctx.Data["ContextUser"] = ctx.ContextUser - teamName := ctx.PathParam("team") - if len(teamName) > 0 { - teamExists := false - for _, team := range ctx.Org.Teams { - if team.LowerName == strings.ToLower(teamName) { - teamExists = true - ctx.Org.Team = team - ctx.Org.IsTeamMember = true - ctx.Data["Team"] = ctx.Org.Team - break + ctx.Data["CanReadProjects"] = ctx.Org.CanReadUnit(ctx, unit.TypeProjects) + ctx.Data["CanReadPackages"] = ctx.Org.CanReadUnit(ctx, unit.TypePackages) + ctx.Data["CanReadCode"] = ctx.Org.CanReadUnit(ctx, unit.TypeCode) + + ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID) + if len(ctx.ContextUser.Description) != 0 { + content, err := markdown.RenderString(markup.NewRenderContext(ctx), ctx.ContextUser.Description) + if err != nil { + ctx.ServerError("RenderString", err) + return } + ctx.Data["RenderedDescription"] = content } - - if !teamExists { - ctx.NotFound("OrgAssignment", err) - return - } - - ctx.Data["IsTeamMember"] = ctx.Org.IsTeamMember - if requireTeamMember && !ctx.Org.IsTeamMember { - ctx.NotFound("OrgAssignment", err) - return - } - - ctx.Org.IsTeamAdmin = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.AccessMode >= perm.AccessModeAdmin - ctx.Data["IsTeamAdmin"] = ctx.Org.IsTeamAdmin - if requireTeamAdmin && !ctx.Org.IsTeamAdmin { - ctx.NotFound("OrgAssignment", err) - return - } - } - ctx.Data["ContextUser"] = ctx.ContextUser - - ctx.Data["CanReadProjects"] = ctx.Org.CanReadUnit(ctx, unit.TypeProjects) - ctx.Data["CanReadPackages"] = ctx.Org.CanReadUnit(ctx, unit.TypePackages) - ctx.Data["CanReadCode"] = ctx.Org.CanReadUnit(ctx, unit.TypeCode) - - ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID) - if len(ctx.ContextUser.Description) != 0 { - content, err := markdown.RenderString(markup.NewRenderContext(ctx), ctx.ContextUser.Description) - if err != nil { - ctx.ServerError("RenderString", err) - return - } - ctx.Data["RenderedDescription"] = content - } -} - -// OrgAssignment returns a middleware to handle organization assignment -// args: requireMember, requireOwner, requireTeamMember, requireTeamAdmin -func OrgAssignment(args ...bool) func(ctx *Context) { - return func(ctx *Context) { - HandleOrgAssignment(ctx, args...) } } From a6819570be680a4ac9b064ae35913fde08af679e Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 5 Feb 2025 00:32:05 +0000 Subject: [PATCH 057/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_ga-IE.ini | 8 ++++++++ options/locale/locale_pt-PT.ini | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index 84ec5c10ee..6708b07b97 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -2877,6 +2877,14 @@ view_as_role=Féach mar: %s view_as_public_hint=Tá tú ag féachaint ar an README mar úsáideoir poiblí. view_as_member_hint=Tá tú ag féachaint ar an README mar bhall den eagraíocht seo. +worktime=Am oibre +worktime.date_range_start=Dáta tosaithe +worktime.date_range_end=Dáta deiridh +worktime.query=Ceist +worktime.time=Am +worktime.by_repositories=De réir stórtha +worktime.by_milestones=De réir clocha míle +worktime.by_members=Ag baill [admin] maintenance=Cothabháil diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index c482949dd1..c51c0483db 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -2877,6 +2877,14 @@ view_as_role=Ver como: %s view_as_public_hint=Está a ver o README como um utilizador público. view_as_member_hint=Está a ver o README como um membro desta organização. +worktime=Tempo de trabalho +worktime.date_range_start=Data do início +worktime.date_range_end=Data do fim +worktime.query=Consulta +worktime.time=Tempo +worktime.by_repositories=Por repositórios +worktime.by_milestones=Por etapas +worktime.by_members=Por membros [admin] maintenance=Manutenção From 6999651b6d9804c5372b5abc67892b7eb74861db Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 4 Feb 2025 19:51:10 -0800 Subject: [PATCH 058/655] Fix unnecessary comment when moving issue on the same project column (#33496) Fix #33482 --- models/issues/issue_project.go | 10 ++++++---- modules/indexer/issues/util.go | 7 ++++++- services/projects/issue.go | 31 +++++++++++++++++++------------ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go index c4515fd898..f520604321 100644 --- a/models/issues/issue_project.go +++ b/models/issues/issue_project.go @@ -38,13 +38,15 @@ func (issue *Issue) projectID(ctx context.Context) int64 { } // ProjectColumnID return project column id if issue was assigned to one -func (issue *Issue) ProjectColumnID(ctx context.Context) int64 { +func (issue *Issue) ProjectColumnID(ctx context.Context) (int64, error) { var ip project_model.ProjectIssue has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip) - if err != nil || !has { - return 0 + if err != nil { + return 0, err + } else if !has { + return 0, nil } - return ip.ProjectColumnID + return ip.ProjectColumnID, nil } // LoadIssuesFromColumn load issues assigned to this column diff --git a/modules/indexer/issues/util.go b/modules/indexer/issues/util.go index deb19adc49..19d835a1d8 100644 --- a/modules/indexer/issues/util.go +++ b/modules/indexer/issues/util.go @@ -92,6 +92,11 @@ func getIssueIndexerData(ctx context.Context, issueID int64) (*internal.IndexerD projectID = issue.Project.ID } + projectColumnID, err := issue.ProjectColumnID(ctx) + if err != nil { + return nil, false, err + } + return &internal.IndexerData{ ID: issue.ID, RepoID: issue.RepoID, @@ -106,7 +111,7 @@ func getIssueIndexerData(ctx context.Context, issueID int64) (*internal.IndexerD NoLabel: len(labels) == 0, MilestoneID: issue.MilestoneID, ProjectID: projectID, - ProjectColumnID: issue.ProjectColumnID(ctx), + ProjectColumnID: projectColumnID, PosterID: issue.PosterID, AssigneeID: issue.AssigneeID, MentionIDs: mentionIDs, diff --git a/services/projects/issue.go b/services/projects/issue.go index db1621a39f..6ca0f16806 100644 --- a/services/projects/issue.go +++ b/services/projects/issue.go @@ -55,22 +55,29 @@ func MoveIssuesOnProjectColumn(ctx context.Context, doer *user_model.User, colum continue } - _, err = db.Exec(ctx, "UPDATE `project_issue` SET project_board_id=?, sorting=? WHERE issue_id=?", column.ID, sorting, issueID) + projectColumnID, err := curIssue.ProjectColumnID(ctx) if err != nil { return err } - // add timeline to issue - if _, err := issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{ - Type: issues_model.CommentTypeProjectColumn, - Doer: doer, - Repo: curIssue.Repo, - Issue: curIssue, - ProjectID: column.ProjectID, - ProjectTitle: project.Title, - ProjectColumnID: column.ID, - ProjectColumnTitle: column.Title, - }); err != nil { + if projectColumnID != column.ID { + // add timeline to issue + if _, err := issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeProjectColumn, + Doer: doer, + Repo: curIssue.Repo, + Issue: curIssue, + ProjectID: column.ProjectID, + ProjectTitle: project.Title, + ProjectColumnID: column.ID, + ProjectColumnTitle: column.Title, + }); err != nil { + return err + } + } + + _, err = db.Exec(ctx, "UPDATE `project_issue` SET project_board_id=?, sorting=? WHERE issue_id=?", column.ID, sorting, issueID) + if err != nil { return err } } From 7e596bd7a9378cadbbd9efaf9cc622de554e056c Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Tue, 4 Feb 2025 23:17:08 -0500 Subject: [PATCH 059/655] add `timetzdata` build tag to binary releases (#33463) `timetzdata` is already used in the docker images, this includes them for the binary release files too. Related to #33235 (I don't have a windows machine setup to test this though) --------- Co-authored-by: wxiaoguang --- main_timezones.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 main_timezones.go diff --git a/main_timezones.go b/main_timezones.go new file mode 100644 index 0000000000..e1233007c6 --- /dev/null +++ b/main_timezones.go @@ -0,0 +1,16 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +//go:build windows + +package main + +// Golang has the ability to load OS's timezone data from most UNIX systems (https://github.com/golang/go/blob/master/src/time/zoneinfo_unix.go) +// Even if the timezone data is missing, users could install the related packages to get it. +// But on Windows, although `zoneinfo_windows.go` tries to load the timezone data from Windows registry, +// some users still suffer from the issue that the timezone data is missing: https://github.com/go-gitea/gitea/issues/33235 +// So we import the tzdata package to make sure the timezone data is included in the binary. +// +// For non-Windows package builders, they could still use the "TAGS=timetzdata" to include the tzdata package in the binary. +// If we decided to add the tzdata for other platforms, modify the "go:build" directive above. +import _ "time/tzdata" From fa0c8ae50f6f69fcea64d4b22d5f257649f78bea Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 6 Feb 2025 00:09:58 +0800 Subject: [PATCH 060/655] Refactor gitdiff test (#33507) --- services/gitdiff/gitdiff_test.go | 17 ++++++++++------- .../gitdiff/testdata/academic-module/HEAD | 1 - .../gitdiff/testdata/academic-module/config | 10 ---------- .../gitdiff/testdata/academic-module/index | Bin 46960 -> 0 bytes .../testdata/academic-module/logs/HEAD | 1 - .../academic-module/logs/refs/heads/master | 1 - .../logs/refs/remotes/origin/HEAD | 1 - ...7efbc3613c7ba790e33b178fd9fc1fe17b4245.idx | Bin 65332 -> 0 bytes ...efbc3613c7ba790e33b178fd9fc1fe17b4245.pack | Bin 1167905 -> 0 bytes .../testdata/academic-module/packed-refs | 2 -- .../academic-module/refs/heads/master | 1 - .../academic-module/refs/remotes/origin/HEAD | 1 - 12 files changed, 10 insertions(+), 25 deletions(-) delete mode 100644 services/gitdiff/testdata/academic-module/HEAD delete mode 100644 services/gitdiff/testdata/academic-module/config delete mode 100644 services/gitdiff/testdata/academic-module/index delete mode 100644 services/gitdiff/testdata/academic-module/logs/HEAD delete mode 100644 services/gitdiff/testdata/academic-module/logs/refs/heads/master delete mode 100644 services/gitdiff/testdata/academic-module/logs/refs/remotes/origin/HEAD delete mode 100644 services/gitdiff/testdata/academic-module/objects/pack/pack-597efbc3613c7ba790e33b178fd9fc1fe17b4245.idx delete mode 100644 services/gitdiff/testdata/academic-module/objects/pack/pack-597efbc3613c7ba790e33b178fd9fc1fe17b4245.pack delete mode 100644 services/gitdiff/testdata/academic-module/packed-refs delete mode 100644 services/gitdiff/testdata/academic-module/refs/heads/master delete mode 100644 services/gitdiff/testdata/academic-module/refs/remotes/origin/HEAD diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index 1017d188dd..ca9b5a6f4e 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -5,6 +5,7 @@ package gitdiff import ( + "context" "strconv" "strings" "testing" @@ -628,23 +629,25 @@ func TestDiffLine_GetCommentSide(t *testing.T) { } func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) { - gitRepo, err := git.OpenRepository(git.DefaultContext, "./testdata/academic-module") + gitRepo, err := git.OpenRepository(context.Background(), "../../modules/git/tests/repos/repo5_pulls") require.NoError(t, err) defer gitRepo.Close() for _, behavior := range []git.TrustedCmdArgs{{"-w"}, {"--ignore-space-at-eol"}, {"-b"}, nil} { - diffs, err := GetDiff(db.DefaultContext, gitRepo, + diffs, err := GetDiff(context.Background(), gitRepo, &DiffOptions{ - AfterCommitID: "bd7063cc7c04689c4d082183d32a604ed27a24f9", - BeforeCommitID: "559c156f8e0178b71cb44355428f24001b08fc68", + AfterCommitID: "d8e0bbb45f200e67d9a784ce55bd90821af45ebd", + BeforeCommitID: "72866af952e98d02a73003501836074b286a78f6", MaxLines: setting.Git.MaxGitDiffLines, MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters, - MaxFiles: setting.Git.MaxGitDiffFiles, + MaxFiles: 1, WhitespaceBehavior: behavior, }) - assert.NoError(t, err, "Error when diff with %s", behavior) + require.NoError(t, err, "Error when diff with WhitespaceBehavior=%s", behavior) + assert.True(t, diffs.IsIncomplete) + assert.Len(t, diffs.Files, 1) for _, f := range diffs.Files { - assert.NotEmpty(t, f.Sections, "%s should have sections", f.Name) + assert.NotEmpty(t, f.Sections, "Diff file %q should have sections", f.Name) } } } diff --git a/services/gitdiff/testdata/academic-module/HEAD b/services/gitdiff/testdata/academic-module/HEAD deleted file mode 100644 index cb089cd89a..0000000000 --- a/services/gitdiff/testdata/academic-module/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/services/gitdiff/testdata/academic-module/config b/services/gitdiff/testdata/academic-module/config deleted file mode 100644 index 1bc26be514..0000000000 --- a/services/gitdiff/testdata/academic-module/config +++ /dev/null @@ -1,10 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - precomposeunicode = true -[branch "master"] - remote = origin - merge = refs/heads/master diff --git a/services/gitdiff/testdata/academic-module/index b/services/gitdiff/testdata/academic-module/index deleted file mode 100644 index e712c906e38cc15a772877636245db0a98a01402..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46960 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 diff --git a/services/gitdiff/testdata/academic-module/logs/HEAD b/services/gitdiff/testdata/academic-module/logs/HEAD deleted file mode 100644 index 16b2e1c0f6..0000000000 --- a/services/gitdiff/testdata/academic-module/logs/HEAD +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 bd7063cc7c04689c4d082183d32a604ed27a24f9 Lunny Xiao 1574829684 +0800 clone: from https://try.gitea.io/shemgp-aiias/academic-module diff --git a/services/gitdiff/testdata/academic-module/logs/refs/heads/master b/services/gitdiff/testdata/academic-module/logs/refs/heads/master deleted file mode 100644 index 16b2e1c0f6..0000000000 --- a/services/gitdiff/testdata/academic-module/logs/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 bd7063cc7c04689c4d082183d32a604ed27a24f9 Lunny Xiao 1574829684 +0800 clone: from https://try.gitea.io/shemgp-aiias/academic-module diff --git a/services/gitdiff/testdata/academic-module/logs/refs/remotes/origin/HEAD b/services/gitdiff/testdata/academic-module/logs/refs/remotes/origin/HEAD deleted file mode 100644 index 16b2e1c0f6..0000000000 --- a/services/gitdiff/testdata/academic-module/logs/refs/remotes/origin/HEAD +++ /dev/null @@ -1 +0,0 @@ -0000000000000000000000000000000000000000 bd7063cc7c04689c4d082183d32a604ed27a24f9 Lunny Xiao 1574829684 +0800 clone: from https://try.gitea.io/shemgp-aiias/academic-module diff --git a/services/gitdiff/testdata/academic-module/objects/pack/pack-597efbc3613c7ba790e33b178fd9fc1fe17b4245.idx b/services/gitdiff/testdata/academic-module/objects/pack/pack-597efbc3613c7ba790e33b178fd9fc1fe17b4245.idx deleted file mode 100644 index 4d759aa504b814e1c1ff1c9b8ff5849c3478233f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65332 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 F{|8~T2zCGf diff --git a/services/gitdiff/testdata/academic-module/objects/pack/pack-597efbc3613c7ba790e33b178fd9fc1fe17b4245.pack b/services/gitdiff/testdata/academic-module/objects/pack/pack-597efbc3613c7ba790e33b178fd9fc1fe17b4245.pack deleted file mode 100644 index 2dc49cfded0c7a59aa5d67a552bb296c7d4f83c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1167905 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⊥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

>+@TusCS+6C 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

Up2Us`*_ax9%#P!Bgc0WT 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

PZHA_{eE8sS^{5k!Lq4I2 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ⅇ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

nX|!M$BfRay{?iPzif^n}R}@BdoX{zlzA*) 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 z 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�R(hbQ07jH+2>U8XZ&0*F@W* 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 KvEnZw{r>^53*uw| diff --git a/services/gitdiff/testdata/academic-module/packed-refs b/services/gitdiff/testdata/academic-module/packed-refs deleted file mode 100644 index 13b5611650..0000000000 --- a/services/gitdiff/testdata/academic-module/packed-refs +++ /dev/null @@ -1,2 +0,0 @@ -# pack-refs with: peeled fully-peeled sorted -bd7063cc7c04689c4d082183d32a604ed27a24f9 refs/remotes/origin/master diff --git a/services/gitdiff/testdata/academic-module/refs/heads/master b/services/gitdiff/testdata/academic-module/refs/heads/master deleted file mode 100644 index bd2b56eaf4..0000000000 --- a/services/gitdiff/testdata/academic-module/refs/heads/master +++ /dev/null @@ -1 +0,0 @@ -bd7063cc7c04689c4d082183d32a604ed27a24f9 diff --git a/services/gitdiff/testdata/academic-module/refs/remotes/origin/HEAD b/services/gitdiff/testdata/academic-module/refs/remotes/origin/HEAD deleted file mode 100644 index 6efe28fff8..0000000000 --- a/services/gitdiff/testdata/academic-module/refs/remotes/origin/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/remotes/origin/master From a025fa70ab3e2aa0f6752e15e3b76b7bd5dded2a Mon Sep 17 00:00:00 2001 From: John Smith Date: Thu, 6 Feb 2025 03:09:43 +0800 Subject: [PATCH 061/655] Add alphabetical project sorting (#33504) Fixes #33500 --- models/project/project.go | 4 ++++ templates/projects/list.tmpl | 2 ++ 2 files changed, 6 insertions(+) diff --git a/models/project/project.go b/models/project/project.go index edeb0b4742..20b5df0b6e 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -244,6 +244,10 @@ func GetSearchOrderByBySortType(sortType string) db.SearchOrderBy { return db.SearchOrderByRecentUpdated case "leastupdate": return db.SearchOrderByLeastUpdated + case "alphabetically": + return "title ASC" + case "reversealphabetically": + return "title DESC" default: return db.SearchOrderByNewest } diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl index f5a48f7241..7c75585bf7 100644 --- a/templates/projects/list.tmpl +++ b/templates/projects/list.tmpl @@ -34,6 +34,8 @@ {{svg "octicon-triangle-down" 14 "dropdown icon"}}

From 943cc4f98952431c4e95a62301d56bcc7b708338 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Thu, 6 Feb 2025 00:31:49 +0000 Subject: [PATCH 062/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_pt-PT.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index c51c0483db..ba883dc7f9 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -2330,6 +2330,8 @@ settings.event_fork=Derivar settings.event_fork_desc=Feita a derivação do repositório. settings.event_wiki=Wiki settings.event_wiki_desc=Página do wiki criada, renomeada, editada ou eliminada. +settings.event_statuses=Estados +settings.event_statuses_desc=Estado do cometimento modificado através da API. settings.event_release=Lançamento settings.event_release_desc=Lançamento publicado, modificado ou eliminado num repositório. settings.event_push=Enviar From 40426addfa15226c72386346ee08d1577d00b263 Mon Sep 17 00:00:00 2001 From: Kerwin Bryant Date: Thu, 6 Feb 2025 21:07:44 +0800 Subject: [PATCH 063/655] Add cropping support when modifying the user/org/repo avatar (#33498) Fixed #33321 --------- Co-authored-by: wxiaoguang --- templates/admin/user/edit.tmpl | 3 +-- templates/org/settings/options.tmpl | 4 +--- templates/repo/settings/options.tmpl | 3 +-- templates/shared/avatar_upload_crop.tmpl | 8 ++++++++ templates/user/settings/profile.tmpl | 8 +------- web_src/css/features/cropper.css | 2 +- web_src/js/features/admin/common.ts | 5 ++++- web_src/js/features/common-organization.ts | 5 ++++- web_src/js/features/comp/Cropper.ts | 9 ++++++++- web_src/js/features/repo-settings.ts | 3 +++ web_src/js/features/user-settings.ts | 13 +++---------- 11 files changed, 35 insertions(+), 28 deletions(-) create mode 100644 templates/shared/avatar_upload_crop.tmpl diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index d591a645d8..c04d332660 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -195,8 +195,7 @@

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≷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
b4@uXIL%Z%8}u0S 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 z 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

- - + {{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl index 3b817d068b..76315f3eac 100644 --- a/templates/org/settings/options.tmpl +++ b/templates/org/settings/options.tmpl @@ -89,10 +89,8 @@
{{.CsrfTokenHtml}}
- - + {{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
-
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index cb596f013b..0520c87cc1 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -40,8 +40,7 @@ {{.CsrfTokenHtml}}
- - + {{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
diff --git a/templates/shared/avatar_upload_crop.tmpl b/templates/shared/avatar_upload_crop.tmpl new file mode 100644 index 0000000000..2c4166fa9c --- /dev/null +++ b/templates/shared/avatar_upload_crop.tmpl @@ -0,0 +1,8 @@ +{{- /* we do not need to set for/id here, global aria init code will add them automatically */ -}} + + +{{- /* the cropper-panel must be next sibling of the input "avatar" */ -}} +
+
{{ctx.Locale.Tr "settings.cropper_prompt"}}
+
+
diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 197763425c..03c3c18f28 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -124,13 +124,7 @@
- - -
- -
-
{{ctx.Locale.Tr "settings.cropper_prompt"}}
-
+ {{template "shared/avatar_upload_crop" dict "LabelText" (ctx.Locale.Tr "settings.choose_new_avatar")}}
diff --git a/web_src/css/features/cropper.css b/web_src/css/features/cropper.css index ed7171e770..f7f8168006 100644 --- a/web_src/css/features/cropper.css +++ b/web_src/css/features/cropper.css @@ -1,6 +1,6 @@ @import "cropperjs/dist/cropper.css"; -.page-content.user.profile .cropper-panel .cropper-wrapper { +.avatar-file-with-cropper + .cropper-panel .cropper-wrapper { max-width: 400px; max-height: 400px; } diff --git a/web_src/js/features/admin/common.ts b/web_src/js/features/admin/common.ts index b991749d81..14a49af81e 100644 --- a/web_src/js/features/admin/common.ts +++ b/web_src/js/features/admin/common.ts @@ -1,7 +1,8 @@ import $ from 'jquery'; import {checkAppUrl} from '../common-page.ts'; -import {hideElem, showElem, toggleElem} from '../../utils/dom.ts'; +import {hideElem, queryElems, showElem, toggleElem} from '../../utils/dom.ts'; import {POST} from '../../modules/fetch.ts'; +import {initAvatarUploaderWithCropper} from '../comp/Cropper.ts'; const {appSubUrl} = window.config; @@ -258,4 +259,6 @@ export function initAdminCommon(): void { window.location.href = this.getAttribute('data-redirect'); }); } + + queryElems(document, '.avatar-file-with-cropper', initAvatarUploaderWithCropper); } diff --git a/web_src/js/features/common-organization.ts b/web_src/js/features/common-organization.ts index a1f19bedea..9d5964c4c7 100644 --- a/web_src/js/features/common-organization.ts +++ b/web_src/js/features/common-organization.ts @@ -1,5 +1,6 @@ import {initCompLabelEdit} from './comp/LabelEdit.ts'; -import {toggleElem} from '../utils/dom.ts'; +import {queryElems, toggleElem} from '../utils/dom.ts'; +import {initAvatarUploaderWithCropper} from './comp/Cropper.ts'; export function initCommonOrganization() { if (!document.querySelectorAll('.organization').length) { @@ -13,4 +14,6 @@ export function initCommonOrganization() { // Labels initCompLabelEdit('.page-content.organization.settings.labels'); + + queryElems(document, '.avatar-file-with-cropper', initAvatarUploaderWithCropper); } diff --git a/web_src/js/features/comp/Cropper.ts b/web_src/js/features/comp/Cropper.ts index e65dcfbe13..aaa1691152 100644 --- a/web_src/js/features/comp/Cropper.ts +++ b/web_src/js/features/comp/Cropper.ts @@ -6,7 +6,7 @@ type CropperOpts = { fileInput: HTMLInputElement, } -export async function initCompCropper({container, fileInput, imageSource}: CropperOpts) { +async function initCompCropper({container, fileInput, imageSource}: CropperOpts) { const {default: Cropper} = await import(/* webpackChunkName: "cropperjs" */'cropperjs'); let currentFileName = ''; let currentFileLastModified = 0; @@ -38,3 +38,10 @@ export async function initCompCropper({container, fileInput, imageSource}: Cropp } }); } + +export async function initAvatarUploaderWithCropper(fileInput: HTMLInputElement) { + const panel = fileInput.nextElementSibling as HTMLElement; + if (!panel?.matches('.cropper-panel')) throw new Error('Missing cropper panel for avatar uploader'); + const imageSource = panel.querySelector('.cropper-source'); + await initCompCropper({container: panel, fileInput, imageSource}); +} diff --git a/web_src/js/features/repo-settings.ts b/web_src/js/features/repo-settings.ts index b61ef9a153..7e890a43e0 100644 --- a/web_src/js/features/repo-settings.ts +++ b/web_src/js/features/repo-settings.ts @@ -3,6 +3,7 @@ import {minimatch} from 'minimatch'; import {createMonaco} from './codeeditor.ts'; import {onInputDebounce, queryElems, toggleElem} from '../utils/dom.ts'; import {POST} from '../modules/fetch.ts'; +import {initAvatarUploaderWithCropper} from './comp/Cropper.ts'; import {initRepoSettingsBranchesDrag} from './repo-settings-branches.ts'; const {appSubUrl, csrfToken} = window.config; @@ -156,4 +157,6 @@ export function initRepoSettings() { initRepoSettingsSearchTeamBox(); initRepoSettingsGitHook(); initRepoSettingsBranchesDrag(); + + queryElems(document, '.avatar-file-with-cropper', initAvatarUploaderWithCropper); } diff --git a/web_src/js/features/user-settings.ts b/web_src/js/features/user-settings.ts index 6312a8b682..21d20e676f 100644 --- a/web_src/js/features/user-settings.ts +++ b/web_src/js/features/user-settings.ts @@ -1,17 +1,10 @@ -import {hideElem, showElem} from '../utils/dom.ts'; -import {initCompCropper} from './comp/Cropper.ts'; - -function initUserSettingsAvatarCropper() { - const fileInput = document.querySelector('#new-avatar'); - const container = document.querySelector('.user.settings.profile .cropper-panel'); - const imageSource = container.querySelector('.cropper-source'); - initCompCropper({container, fileInput, imageSource}); -} +import {hideElem, queryElems, showElem} from '../utils/dom.ts'; +import {initAvatarUploaderWithCropper} from './comp/Cropper.ts'; export function initUserSettings() { if (!document.querySelector('.user.settings.profile')) return; - initUserSettingsAvatarCropper(); + queryElems(document, '.avatar-file-with-cropper', initAvatarUploaderWithCropper); const usernameInput = document.querySelector('#username'); if (!usernameInput) return; From 0070ffe56061d4b8012d1818aeef75061b0a04c7 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Fri, 7 Feb 2025 01:10:49 +0100 Subject: [PATCH 064/655] Update MAINTAINERS (#33529) * Add myself to the maintainers file --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index f0caae4d22..7d21f449fe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -63,3 +63,4 @@ Kemal Zebari (@kemzeb) Rowan Bohde (@bohde) hiifong (@hiifong) metiftikci (@metiftikci) +Christopher Homberger (@ChristopherHX) From dbc18f400ad1426ca33f93a9717a89d8e4f016a9 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Fri, 7 Feb 2025 00:31:35 +0000 Subject: [PATCH 065/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_ga-IE.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index 6708b07b97..b92714b599 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -2330,6 +2330,8 @@ settings.event_fork=Forc settings.event_fork_desc=Forcadh stóras. settings.event_wiki=Vicí settings.event_wiki_desc=Leathanach Vicí cruthaithe, athainmnithe, curtha in eagar nó scriosta. +settings.event_statuses=Stádais +settings.event_statuses_desc=Nuashonraíodh Stádas Commit ón API. settings.event_release=Scaoileadh settings.event_release_desc=Scaoileadh foilsithe, nuashonraithe nó scriosta i stóras. settings.event_push=Brúigh From a1f1bccd7a26842e4dde8207a214f0652f4a15ea Mon Sep 17 00:00:00 2001 From: Alexander McRae Date: Thu, 6 Feb 2025 16:58:28 -0800 Subject: [PATCH 066/655] Add go wrapper around git diff-tree --raw -r -M (#33369) * Implemented calling git diff-tree * Ensures wrapper function is called with valid arguments * Parses output into go struct, using strong typing when possible --- modules/git/parse.go | 16 +- modules/git/tree_entry_mode.go | 27 +- services/gitdiff/git_diff_tree.go | 249 ++++++++++++++ services/gitdiff/git_diff_tree_test.go | 427 +++++++++++++++++++++++++ 4 files changed, 705 insertions(+), 14 deletions(-) create mode 100644 services/gitdiff/git_diff_tree.go create mode 100644 services/gitdiff/git_diff_tree_test.go diff --git a/modules/git/parse.go b/modules/git/parse.go index eb26632cc0..a7f5c58e89 100644 --- a/modules/git/parse.go +++ b/modules/git/parse.go @@ -46,19 +46,9 @@ func parseLsTreeLine(line []byte) (*LsTreeEntry, error) { entry.Size = optional.Some(size) } - switch string(entryMode) { - case "100644": - entry.EntryMode = EntryModeBlob - case "100755": - entry.EntryMode = EntryModeExec - case "120000": - entry.EntryMode = EntryModeSymlink - case "160000": - entry.EntryMode = EntryModeCommit - case "040000", "040755": // git uses 040000 for tree object, but some users may get 040755 for unknown reasons - entry.EntryMode = EntryModeTree - default: - return nil, fmt.Errorf("unknown type: %v", string(entryMode)) + entry.EntryMode, err = ParseEntryMode(string(entryMode)) + if err != nil || entry.EntryMode == EntryModeNoEntry { + return nil, fmt.Errorf("invalid ls-tree output (invalid mode): %q, err: %w", line, err) } entry.ID, err = NewIDFromString(string(entryObjectID)) diff --git a/modules/git/tree_entry_mode.go b/modules/git/tree_entry_mode.go index a399118cf8..ec4487549d 100644 --- a/modules/git/tree_entry_mode.go +++ b/modules/git/tree_entry_mode.go @@ -3,7 +3,10 @@ package git -import "strconv" +import ( + "fmt" + "strconv" +) // EntryMode the type of the object in the git tree type EntryMode int @@ -11,6 +14,9 @@ type EntryMode int // There are only a few file modes in Git. They look like unix file modes, but they can only be // one of these. const ( + // EntryModeNoEntry is possible if the file was added or removed in a commit. In the case of + // added the base commit will not have the file in its tree so a mode of 0o000000 is used. + EntryModeNoEntry EntryMode = 0o000000 // EntryModeBlob EntryModeBlob EntryMode = 0o100644 // EntryModeExec @@ -33,3 +39,22 @@ func ToEntryMode(value string) EntryMode { v, _ := strconv.ParseInt(value, 8, 32) return EntryMode(v) } + +func ParseEntryMode(mode string) (EntryMode, error) { + switch mode { + case "000000": + return EntryModeNoEntry, nil + case "100644": + return EntryModeBlob, nil + case "100755": + return EntryModeExec, nil + case "120000": + return EntryModeSymlink, nil + case "160000": + return EntryModeCommit, nil + case "040000", "040755": // git uses 040000 for tree object, but some users may get 040755 for unknown reasons + return EntryModeTree, nil + default: + return 0, fmt.Errorf("unparsable entry mode: %s", mode) + } +} diff --git a/services/gitdiff/git_diff_tree.go b/services/gitdiff/git_diff_tree.go new file mode 100644 index 0000000000..8039de145d --- /dev/null +++ b/services/gitdiff/git_diff_tree.go @@ -0,0 +1,249 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitdiff + +import ( + "bufio" + "context" + "fmt" + "io" + "strconv" + "strings" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" +) + +type DiffTree struct { + Files []*DiffTreeRecord +} + +type DiffTreeRecord struct { + // Status is one of 'added', 'deleted', 'modified', 'renamed', 'copied', 'typechanged', 'unmerged', 'unknown' + Status string + + // For renames and copies, the percentage of similarity between the source and target of the move/rename. + Score uint8 + + HeadPath string + BasePath string + HeadMode git.EntryMode + BaseMode git.EntryMode + HeadBlobID string + BaseBlobID string +} + +// GetDiffTree returns the list of path of the files that have changed between the two commits. +// If useMergeBase is true, the diff will be calculated using the merge base of the two commits. +// This is the same behavior as using a three-dot diff in git diff. +func GetDiffTree(ctx context.Context, gitRepo *git.Repository, useMergeBase bool, baseSha, headSha string) (*DiffTree, error) { + gitDiffTreeRecords, err := runGitDiffTree(ctx, gitRepo, useMergeBase, baseSha, headSha) + if err != nil { + return nil, err + } + + return &DiffTree{ + Files: gitDiffTreeRecords, + }, nil +} + +func runGitDiffTree(ctx context.Context, gitRepo *git.Repository, useMergeBase bool, baseSha, headSha string) ([]*DiffTreeRecord, error) { + useMergeBase, baseCommitID, headCommitID, err := validateGitDiffTreeArguments(gitRepo, useMergeBase, baseSha, headSha) + if err != nil { + return nil, err + } + + cmd := git.NewCommand(ctx, "diff-tree", "--raw", "-r", "--find-renames", "--root") + if useMergeBase { + cmd.AddArguments("--merge-base") + } + cmd.AddDynamicArguments(baseCommitID, headCommitID) + stdout, _, runErr := cmd.RunStdString(&git.RunOpts{Dir: gitRepo.Path}) + if runErr != nil { + log.Warn("git diff-tree: %v", runErr) + return nil, runErr + } + + return parseGitDiffTree(strings.NewReader(stdout)) +} + +func validateGitDiffTreeArguments(gitRepo *git.Repository, useMergeBase bool, baseSha, headSha string) (shouldUseMergeBase bool, resolvedBaseSha, resolvedHeadSha string, err error) { + // if the head is empty its an error + if headSha == "" { + return false, "", "", fmt.Errorf("headSha is empty") + } + + // if the head commit doesn't exist its and error + headCommit, err := gitRepo.GetCommit(headSha) + if err != nil { + return false, "", "", fmt.Errorf("failed to get commit headSha: %v", err) + } + headCommitID := headCommit.ID.String() + + // if the base is empty we should use the parent of the head commit + if baseSha == "" { + // if the headCommit has no parent we should use an empty commit + // this can happen when we are generating a diff against an orphaned commit + if headCommit.ParentCount() == 0 { + objectFormat, err := gitRepo.GetObjectFormat() + if err != nil { + return false, "", "", err + } + + // We set use merge base to false because we have no base commit + return false, objectFormat.EmptyTree().String(), headCommitID, nil + } + + baseCommit, err := headCommit.Parent(0) + if err != nil { + return false, "", "", fmt.Errorf("baseSha is '', attempted to use parent of commit %s, got error: %v", headCommit.ID.String(), err) + } + return useMergeBase, baseCommit.ID.String(), headCommitID, nil + } + + // try and get the base commit + baseCommit, err := gitRepo.GetCommit(baseSha) + // propagate the error if we couldn't get the base commit + if err != nil { + return useMergeBase, "", "", fmt.Errorf("failed to get base commit %s: %v", baseSha, err) + } + + return useMergeBase, baseCommit.ID.String(), headCommit.ID.String(), nil +} + +func parseGitDiffTree(gitOutput io.Reader) ([]*DiffTreeRecord, error) { + /* + The output of `git diff-tree --raw -r --find-renames` is of the form: + + : \t + + or for renames: + + : \t\t + + See: for more details + */ + results := make([]*DiffTreeRecord, 0) + + lines := bufio.NewScanner(gitOutput) + for lines.Scan() { + line := lines.Text() + + if len(line) == 0 { + continue + } + + record, err := parseGitDiffTreeLine(line) + if err != nil { + return nil, err + } + + results = append(results, record) + } + + if err := lines.Err(); err != nil { + return nil, err + } + + return results, nil +} + +func parseGitDiffTreeLine(line string) (*DiffTreeRecord, error) { + line = strings.TrimPrefix(line, ":") + splitSections := strings.SplitN(line, "\t", 2) + if len(splitSections) < 2 { + return nil, fmt.Errorf("unparsable output for diff-tree --raw: `%s`)", line) + } + + fields := strings.Fields(splitSections[0]) + if len(fields) < 5 { + return nil, fmt.Errorf("unparsable output for diff-tree --raw: `%s`, expected 5 space delimited values got %d)", line, len(fields)) + } + + baseMode, err := git.ParseEntryMode(fields[0]) + if err != nil { + return nil, err + } + + headMode, err := git.ParseEntryMode(fields[1]) + if err != nil { + return nil, err + } + + baseBlobID := fields[2] + headBlobID := fields[3] + + status, score, err := statusFromLetter(fields[4]) + if err != nil { + return nil, fmt.Errorf("unparsable output for diff-tree --raw: %s, error: %s", line, err) + } + + filePaths := strings.Split(splitSections[1], "\t") + + var headPath, basePath string + if status == "renamed" { + if len(filePaths) != 2 { + return nil, fmt.Errorf("unparsable output for diff-tree --raw: `%s`, expected 2 paths found %d", line, len(filePaths)) + } + basePath = filePaths[0] + headPath = filePaths[1] + } else { + basePath = filePaths[0] + headPath = filePaths[0] + } + + return &DiffTreeRecord{ + Status: status, + Score: score, + BaseMode: baseMode, + HeadMode: headMode, + BaseBlobID: baseBlobID, + HeadBlobID: headBlobID, + BasePath: basePath, + HeadPath: headPath, + }, nil +} + +func statusFromLetter(rawStatus string) (status string, score uint8, err error) { + if len(rawStatus) < 1 { + return "", 0, fmt.Errorf("empty status letter") + } + switch rawStatus[0] { + case 'A': + return "added", 0, nil + case 'D': + return "deleted", 0, nil + case 'M': + return "modified", 0, nil + case 'R': + score, err = tryParseStatusScore(rawStatus) + return "renamed", score, err + case 'C': + score, err = tryParseStatusScore(rawStatus) + return "copied", score, err + case 'T': + return "typechanged", 0, nil + case 'U': + return "unmerged", 0, nil + case 'X': + return "unknown", 0, nil + default: + return "", 0, fmt.Errorf("unknown status letter: '%s'", rawStatus) + } +} + +func tryParseStatusScore(rawStatus string) (uint8, error) { + if len(rawStatus) < 2 { + return 0, fmt.Errorf("status score missing") + } + + score, err := strconv.ParseUint(rawStatus[1:], 10, 8) + if err != nil { + return 0, fmt.Errorf("failed to parse status score: %w", err) + } else if score > 100 { + return 0, fmt.Errorf("status score out of range: %d", score) + } + + return uint8(score), nil +} diff --git a/services/gitdiff/git_diff_tree_test.go b/services/gitdiff/git_diff_tree_test.go new file mode 100644 index 0000000000..313d279e95 --- /dev/null +++ b/services/gitdiff/git_diff_tree_test.go @@ -0,0 +1,427 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitdiff + +import ( + "strings" + "testing" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/git" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGitDiffTree(t *testing.T) { + test := []struct { + Name string + RepoPath string + BaseSha string + HeadSha string + useMergeBase bool + Expected *DiffTree + }{ + { + Name: "happy path", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + BaseSha: "72866af952e98d02a73003501836074b286a78f6", + HeadSha: "d8e0bbb45f200e67d9a784ce55bd90821af45ebd", + Expected: &DiffTree{ + Files: []*DiffTreeRecord{ + { + Status: "modified", + HeadPath: "LICENSE", + BasePath: "LICENSE", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "ee469963e76ae1bb7ee83d7510df2864e6c8c640", + BaseBlobID: "c996f4725be8fc8c1d1c776e58c97ddc5d03b336", + }, + { + Status: "modified", + HeadPath: "README.md", + BasePath: "README.md", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "9dfc0a6257d8eff526f0cfaf6a8ea950f55a9dba", + BaseBlobID: "074e590b8e64898b02beef03ece83f962c94f54c", + }, + }, + }, + }, + { + Name: "first commit (no parent)", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + HeadSha: "72866af952e98d02a73003501836074b286a78f6", + Expected: &DiffTree{ + Files: []*DiffTreeRecord{ + { + Status: "added", + HeadPath: ".gitignore", + BasePath: ".gitignore", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "f1c181ec9c5c921245027c6b452ecfc1d3626364", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + { + Status: "added", + HeadPath: "LICENSE", + BasePath: "LICENSE", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "c996f4725be8fc8c1d1c776e58c97ddc5d03b336", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + { + Status: "added", + HeadPath: "README.md", + BasePath: "README.md", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "074e590b8e64898b02beef03ece83f962c94f54c", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + }, + }, + }, + { + Name: "first commit (no parent), merge base = true", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + HeadSha: "72866af952e98d02a73003501836074b286a78f6", + useMergeBase: true, + Expected: &DiffTree{ + Files: []*DiffTreeRecord{ + { + Status: "added", + HeadPath: ".gitignore", + BasePath: ".gitignore", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "f1c181ec9c5c921245027c6b452ecfc1d3626364", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + { + Status: "added", + HeadPath: "LICENSE", + BasePath: "LICENSE", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "c996f4725be8fc8c1d1c776e58c97ddc5d03b336", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + { + Status: "added", + HeadPath: "README.md", + BasePath: "README.md", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "074e590b8e64898b02beef03ece83f962c94f54c", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + }, + }, + }, + { + Name: "base and head same", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + BaseSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f", + HeadSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f", + Expected: &DiffTree{ + Files: []*DiffTreeRecord{}, + }, + }, + { + Name: "useMergeBase false", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + BaseSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f", + HeadSha: "111cac04bd7d20301964e27a93698aabb5781b80", // this commit can be found on the update-readme branch + useMergeBase: false, + Expected: &DiffTree{ + Files: []*DiffTreeRecord{ + { + Status: "modified", + HeadPath: "LICENSE", + BasePath: "LICENSE", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "c996f4725be8fc8c1d1c776e58c97ddc5d03b336", + BaseBlobID: "ed5119b3c1f45547b6785bc03eac7f87570fa17f", + }, + + { + Status: "modified", + HeadPath: "README.md", + BasePath: "README.md", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "fb39771a8865c9a67f2ab9b616c854805664553c", + BaseBlobID: "9dfc0a6257d8eff526f0cfaf6a8ea950f55a9dba", + }, + }, + }, + }, + { + Name: "useMergeBase true", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + BaseSha: "ed8f4d2fa5b2420706580d191f5dd50c4e491f3f", + HeadSha: "111cac04bd7d20301964e27a93698aabb5781b80", // this commit can be found on the update-readme branch + useMergeBase: true, + Expected: &DiffTree{ + Files: []*DiffTreeRecord{ + { + Status: "modified", + HeadPath: "README.md", + BasePath: "README.md", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "fb39771a8865c9a67f2ab9b616c854805664553c", + BaseBlobID: "9dfc0a6257d8eff526f0cfaf6a8ea950f55a9dba", + }, + }, + }, + }, + { + Name: "no base set", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + HeadSha: "d8e0bbb45f200e67d9a784ce55bd90821af45ebd", // this commit can be found on the update-readme branch + useMergeBase: false, + Expected: &DiffTree{ + Files: []*DiffTreeRecord{ + { + Status: "modified", + HeadPath: "LICENSE", + BasePath: "LICENSE", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "ee469963e76ae1bb7ee83d7510df2864e6c8c640", + BaseBlobID: "ed5119b3c1f45547b6785bc03eac7f87570fa17f", + }, + }, + }, + }, + } + + for _, tt := range test { + t.Run(tt.Name, func(t *testing.T) { + gitRepo, err := git.OpenRepository(git.DefaultContext, tt.RepoPath) + assert.NoError(t, err) + defer gitRepo.Close() + + diffPaths, err := GetDiffTree(db.DefaultContext, gitRepo, tt.useMergeBase, tt.BaseSha, tt.HeadSha) + require.NoError(t, err) + + assert.Equal(t, tt.Expected, diffPaths) + }) + } +} + +func TestParseGitDiffTree(t *testing.T) { + test := []struct { + Name string + GitOutput string + Expected []*DiffTreeRecord + }{ + { + Name: "file change", + GitOutput: ":100644 100644 64e43d23bcd08db12563a0a4d84309cadb437e1a 5dbc7792b5bb228647cfcc8dfe65fc649119dedc M\tResources/views/curriculum/edit.blade.php", + Expected: []*DiffTreeRecord{ + { + Status: "modified", + HeadPath: "Resources/views/curriculum/edit.blade.php", + BasePath: "Resources/views/curriculum/edit.blade.php", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "5dbc7792b5bb228647cfcc8dfe65fc649119dedc", + BaseBlobID: "64e43d23bcd08db12563a0a4d84309cadb437e1a", + }, + }, + }, + { + Name: "file added", + GitOutput: ":000000 100644 0000000000000000000000000000000000000000 0063162fb403db15ceb0517b34ab782e4e58b619 A\tResources/views/class/index.blade.php", + Expected: []*DiffTreeRecord{ + { + Status: "added", + HeadPath: "Resources/views/class/index.blade.php", + BasePath: "Resources/views/class/index.blade.php", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "0063162fb403db15ceb0517b34ab782e4e58b619", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + }, + }, + { + Name: "file deleted", + GitOutput: ":100644 000000 bac4286303c8c0017ea2f0a48c561ddcc0330a14 0000000000000000000000000000000000000000 D\tResources/views/classes/index.blade.php", + Expected: []*DiffTreeRecord{ + { + Status: "deleted", + HeadPath: "Resources/views/classes/index.blade.php", + BasePath: "Resources/views/classes/index.blade.php", + HeadMode: git.EntryModeNoEntry, + BaseMode: git.EntryModeBlob, + HeadBlobID: "0000000000000000000000000000000000000000", + BaseBlobID: "bac4286303c8c0017ea2f0a48c561ddcc0330a14", + }, + }, + }, + { + Name: "file renamed", + GitOutput: ":100644 100644 c8a055cfb45cd39747292983ad1797ceab40f5b1 97248f79a90aaf81fe7fd74b33c1cb182dd41783 R087\tDatabase/Seeders/AdminDatabaseSeeder.php\tDatabase/Seeders/AcademicDatabaseSeeder.php", + Expected: []*DiffTreeRecord{ + { + Status: "renamed", + Score: 87, + HeadPath: "Database/Seeders/AcademicDatabaseSeeder.php", + BasePath: "Database/Seeders/AdminDatabaseSeeder.php", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "97248f79a90aaf81fe7fd74b33c1cb182dd41783", + BaseBlobID: "c8a055cfb45cd39747292983ad1797ceab40f5b1", + }, + }, + }, + { + Name: "no changes", + GitOutput: ``, + Expected: []*DiffTreeRecord{}, + }, + { + Name: "multiple changes", + GitOutput: ":000000 100644 0000000000000000000000000000000000000000 db736b44533a840981f1f17b7029d0f612b69550 A\tHttp/Controllers/ClassController.php\n" + + ":100644 000000 9a4d2344d4d0145db7c91b3f3e123c74367d4ef4 0000000000000000000000000000000000000000 D\tHttp/Controllers/ClassesController.php\n" + + ":100644 100644 f060d6aede65d423f49e7dc248dfa0d8835ef920 b82c8e39a3602dedadb44669956d6eb5b6a7cc86 M\tHttp/Controllers/ProgramDirectorController.php\n", + Expected: []*DiffTreeRecord{ + { + Status: "added", + HeadPath: "Http/Controllers/ClassController.php", + BasePath: "Http/Controllers/ClassController.php", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "db736b44533a840981f1f17b7029d0f612b69550", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + { + Status: "deleted", + HeadPath: "Http/Controllers/ClassesController.php", + BasePath: "Http/Controllers/ClassesController.php", + HeadMode: git.EntryModeNoEntry, + BaseMode: git.EntryModeBlob, + HeadBlobID: "0000000000000000000000000000000000000000", + BaseBlobID: "9a4d2344d4d0145db7c91b3f3e123c74367d4ef4", + }, + { + Status: "modified", + HeadPath: "Http/Controllers/ProgramDirectorController.php", + BasePath: "Http/Controllers/ProgramDirectorController.php", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "b82c8e39a3602dedadb44669956d6eb5b6a7cc86", + BaseBlobID: "f060d6aede65d423f49e7dc248dfa0d8835ef920", + }, + }, + }, + { + Name: "spaces in file path", + GitOutput: ":000000 100644 0000000000000000000000000000000000000000 db736b44533a840981f1f17b7029d0f612b69550 A\tHttp /Controllers/Class Controller.php\n" + + ":100644 000000 9a4d2344d4d0145db7c91b3f3e123c74367d4ef4 0000000000000000000000000000000000000000 D\tHttp/Cont rollers/Classes Controller.php\n" + + ":100644 100644 f060d6aede65d423f49e7dc248dfa0d8835ef920 b82c8e39a3602dedadb44669956d6eb5b6a7cc86 R010\tHttp/Controllers/Program Director Controller.php\tHttp/Cont rollers/ProgramDirectorController.php\n", + Expected: []*DiffTreeRecord{ + { + Status: "added", + HeadPath: "Http /Controllers/Class Controller.php", + BasePath: "Http /Controllers/Class Controller.php", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeNoEntry, + HeadBlobID: "db736b44533a840981f1f17b7029d0f612b69550", + BaseBlobID: "0000000000000000000000000000000000000000", + }, + { + Status: "deleted", + HeadPath: "Http/Cont rollers/Classes Controller.php", + BasePath: "Http/Cont rollers/Classes Controller.php", + HeadMode: git.EntryModeNoEntry, + BaseMode: git.EntryModeBlob, + HeadBlobID: "0000000000000000000000000000000000000000", + BaseBlobID: "9a4d2344d4d0145db7c91b3f3e123c74367d4ef4", + }, + { + Status: "renamed", + Score: 10, + HeadPath: "Http/Cont rollers/ProgramDirectorController.php", + BasePath: "Http/Controllers/Program Director Controller.php", + HeadMode: git.EntryModeBlob, + BaseMode: git.EntryModeBlob, + HeadBlobID: "b82c8e39a3602dedadb44669956d6eb5b6a7cc86", + BaseBlobID: "f060d6aede65d423f49e7dc248dfa0d8835ef920", + }, + }, + }, + { + Name: "file type changed", + GitOutput: ":100644 120000 344e0ca8aa791cc4164fb0ea645f334fd40d00f0 a7c2973de00bfdc6ca51d315f401b5199fe01dc3 T\twebpack.mix.js", + Expected: []*DiffTreeRecord{ + { + Status: "typechanged", + HeadPath: "webpack.mix.js", + BasePath: "webpack.mix.js", + HeadMode: git.EntryModeSymlink, + BaseMode: git.EntryModeBlob, + HeadBlobID: "a7c2973de00bfdc6ca51d315f401b5199fe01dc3", + BaseBlobID: "344e0ca8aa791cc4164fb0ea645f334fd40d00f0", + }, + }, + }, + } + + for _, tt := range test { + t.Run(tt.Name, func(t *testing.T) { + entries, err := parseGitDiffTree(strings.NewReader(tt.GitOutput)) + assert.NoError(t, err) + assert.Equal(t, tt.Expected, entries) + }) + } +} + +func TestGitDiffTreeErrors(t *testing.T) { + test := []struct { + Name string + RepoPath string + BaseSha string + HeadSha string + }{ + { + Name: "head doesn't exist", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + BaseSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2", + HeadSha: "asdfasdfasdf", + }, + { + Name: "base doesn't exist", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + BaseSha: "asdfasdfasdf", + HeadSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2", + }, + { + Name: "head not set", + RepoPath: "../../modules/git/tests/repos/repo5_pulls", + BaseSha: "f32b0a9dfd09a60f616f29158f772cedd89942d2", + }, + } + + for _, tt := range test { + t.Run(tt.Name, func(t *testing.T) { + gitRepo, err := git.OpenRepository(git.DefaultContext, tt.RepoPath) + assert.NoError(t, err) + defer gitRepo.Close() + + diffPaths, err := GetDiffTree(db.DefaultContext, gitRepo, true, tt.BaseSha, tt.HeadSha) + assert.Error(t, err) + assert.Nil(t, diffPaths) + }) + } +} From 466cc725bc69d9222abf17d7a22d86e7dbe991ac Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 6 Feb 2025 19:05:25 -0800 Subject: [PATCH 067/655] Move gitgraph from modules to services layer (#33527) Just move, no code change. --- routers/web/repo/commit.go | 2 +- {modules => services/repository}/gitgraph/graph.go | 0 {modules => services/repository}/gitgraph/graph_models.go | 0 {modules => services/repository}/gitgraph/graph_test.go | 0 {modules => services/repository}/gitgraph/parser.go | 0 5 files changed, 1 insertion(+), 1 deletion(-) rename {modules => services/repository}/gitgraph/graph.go (100%) rename {modules => services/repository}/gitgraph/graph_models.go (100%) rename {modules => services/repository}/gitgraph/graph_test.go (100%) rename {modules => services/repository}/gitgraph/parser.go (100%) diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 8ffda8ae0a..c8291d98c6 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -22,7 +22,6 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/gitgraph" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" @@ -32,6 +31,7 @@ import ( "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/gitdiff" repo_service "code.gitea.io/gitea/services/repository" + "code.gitea.io/gitea/services/repository/gitgraph" ) const ( diff --git a/modules/gitgraph/graph.go b/services/repository/gitgraph/graph.go similarity index 100% rename from modules/gitgraph/graph.go rename to services/repository/gitgraph/graph.go diff --git a/modules/gitgraph/graph_models.go b/services/repository/gitgraph/graph_models.go similarity index 100% rename from modules/gitgraph/graph_models.go rename to services/repository/gitgraph/graph_models.go diff --git a/modules/gitgraph/graph_test.go b/services/repository/gitgraph/graph_test.go similarity index 100% rename from modules/gitgraph/graph_test.go rename to services/repository/gitgraph/graph_test.go diff --git a/modules/gitgraph/parser.go b/services/repository/gitgraph/parser.go similarity index 100% rename from modules/gitgraph/parser.go rename to services/repository/gitgraph/parser.go From 1ec8d80fa3b49e6a4c6a6239eedc6a9909cfb23d Mon Sep 17 00:00:00 2001 From: TheFox0x7 Date: Fri, 7 Feb 2025 06:37:32 +0100 Subject: [PATCH 068/655] refactor: decouple context from migration structs (#33399) Use context as much as possible. --------- Co-authored-by: wxiaoguang --- modules/migration/downloader.go | 21 ++- modules/migration/null_downloader.go | 23 ++-- modules/migration/retry_downloader.go | 43 +++--- modules/migration/uploader.go | 24 ++-- services/migrations/codebase.go | 50 +++---- services/migrations/codebase_test.go | 18 +-- services/migrations/codecommit.go | 27 ++-- services/migrations/dump.go | 48 ++++--- services/migrations/git.go | 8 +- services/migrations/gitea_downloader.go | 35 ++--- services/migrations/gitea_downloader_test.go | 26 ++-- services/migrations/gitea_uploader.go | 116 ++++++++-------- services/migrations/gitea_uploader_test.go | 24 ++-- services/migrations/github.go | 133 +++++++++---------- services/migrations/github_test.go | 25 ++-- services/migrations/gitlab.go | 61 ++++----- services/migrations/gitlab_test.go | 29 ++-- services/migrations/gogs.go | 85 ++++++------ services/migrations/gogs_test.go | 16 +-- services/migrations/migrate.go | 56 ++++---- services/migrations/onedev.go | 52 ++++---- services/migrations/onedev_test.go | 17 +-- services/migrations/restore.go | 27 ++-- 23 files changed, 455 insertions(+), 509 deletions(-) diff --git a/modules/migration/downloader.go b/modules/migration/downloader.go index 08dbbc29a9..669222dea2 100644 --- a/modules/migration/downloader.go +++ b/modules/migration/downloader.go @@ -12,18 +12,17 @@ import ( // Downloader downloads the site repo information type Downloader interface { - SetContext(context.Context) - GetRepoInfo() (*Repository, error) - GetTopics() ([]string, error) - GetMilestones() ([]*Milestone, error) - GetReleases() ([]*Release, error) - GetLabels() ([]*Label, error) - GetIssues(page, perPage int) ([]*Issue, bool, error) - GetComments(commentable Commentable) ([]*Comment, bool, error) - GetAllComments(page, perPage int) ([]*Comment, bool, error) + GetRepoInfo(ctx context.Context) (*Repository, error) + GetTopics(ctx context.Context) ([]string, error) + GetMilestones(ctx context.Context) ([]*Milestone, error) + GetReleases(ctx context.Context) ([]*Release, error) + GetLabels(ctx context.Context) ([]*Label, error) + GetIssues(ctx context.Context, page, perPage int) ([]*Issue, bool, error) + GetComments(ctx context.Context, commentable Commentable) ([]*Comment, bool, error) + GetAllComments(ctx context.Context, page, perPage int) ([]*Comment, bool, error) SupportGetRepoComments() bool - GetPullRequests(page, perPage int) ([]*PullRequest, bool, error) - GetReviews(reviewable Reviewable) ([]*Review, error) + GetPullRequests(ctx context.Context, page, perPage int) ([]*PullRequest, bool, error) + GetReviews(ctx context.Context, reviewable Reviewable) ([]*Review, error) FormatCloneURL(opts MigrateOptions, remoteAddr string) (string, error) } diff --git a/modules/migration/null_downloader.go b/modules/migration/null_downloader.go index e5b69331df..e488f6914f 100644 --- a/modules/migration/null_downloader.go +++ b/modules/migration/null_downloader.go @@ -13,56 +13,53 @@ type NullDownloader struct{} var _ Downloader = &NullDownloader{} -// SetContext set context -func (n NullDownloader) SetContext(_ context.Context) {} - // GetRepoInfo returns a repository information -func (n NullDownloader) GetRepoInfo() (*Repository, error) { +func (n NullDownloader) GetRepoInfo(_ context.Context) (*Repository, error) { return nil, ErrNotSupported{Entity: "RepoInfo"} } // GetTopics return repository topics -func (n NullDownloader) GetTopics() ([]string, error) { +func (n NullDownloader) GetTopics(_ context.Context) ([]string, error) { return nil, ErrNotSupported{Entity: "Topics"} } // GetMilestones returns milestones -func (n NullDownloader) GetMilestones() ([]*Milestone, error) { +func (n NullDownloader) GetMilestones(_ context.Context) ([]*Milestone, error) { return nil, ErrNotSupported{Entity: "Milestones"} } // GetReleases returns releases -func (n NullDownloader) GetReleases() ([]*Release, error) { +func (n NullDownloader) GetReleases(_ context.Context) ([]*Release, error) { return nil, ErrNotSupported{Entity: "Releases"} } // GetLabels returns labels -func (n NullDownloader) GetLabels() ([]*Label, error) { +func (n NullDownloader) GetLabels(_ context.Context) ([]*Label, error) { return nil, ErrNotSupported{Entity: "Labels"} } // GetIssues returns issues according start and limit -func (n NullDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) { +func (n NullDownloader) GetIssues(_ context.Context, page, perPage int) ([]*Issue, bool, error) { return nil, false, ErrNotSupported{Entity: "Issues"} } // GetComments returns comments of an issue or PR -func (n NullDownloader) GetComments(commentable Commentable) ([]*Comment, bool, error) { +func (n NullDownloader) GetComments(_ context.Context, commentable Commentable) ([]*Comment, bool, error) { return nil, false, ErrNotSupported{Entity: "Comments"} } // GetAllComments returns paginated comments -func (n NullDownloader) GetAllComments(page, perPage int) ([]*Comment, bool, error) { +func (n NullDownloader) GetAllComments(_ context.Context, page, perPage int) ([]*Comment, bool, error) { return nil, false, ErrNotSupported{Entity: "AllComments"} } // GetPullRequests returns pull requests according page and perPage -func (n NullDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bool, error) { +func (n NullDownloader) GetPullRequests(_ context.Context, page, perPage int) ([]*PullRequest, bool, error) { return nil, false, ErrNotSupported{Entity: "PullRequests"} } // GetReviews returns pull requests review -func (n NullDownloader) GetReviews(reviewable Reviewable) ([]*Review, error) { +func (n NullDownloader) GetReviews(_ context.Context, reviewable Reviewable) ([]*Review, error) { return nil, ErrNotSupported{Entity: "Reviews"} } diff --git a/modules/migration/retry_downloader.go b/modules/migration/retry_downloader.go index 1cacf5f375..2926c40df7 100644 --- a/modules/migration/retry_downloader.go +++ b/modules/migration/retry_downloader.go @@ -49,21 +49,15 @@ func (d *RetryDownloader) retry(work func() error) error { return err } -// SetContext set context -func (d *RetryDownloader) SetContext(ctx context.Context) { - d.ctx = ctx - d.Downloader.SetContext(ctx) -} - // GetRepoInfo returns a repository information with retry -func (d *RetryDownloader) GetRepoInfo() (*Repository, error) { +func (d *RetryDownloader) GetRepoInfo(ctx context.Context) (*Repository, error) { var ( repo *Repository err error ) err = d.retry(func() error { - repo, err = d.Downloader.GetRepoInfo() + repo, err = d.Downloader.GetRepoInfo(ctx) return err }) @@ -71,14 +65,14 @@ func (d *RetryDownloader) GetRepoInfo() (*Repository, error) { } // GetTopics returns a repository's topics with retry -func (d *RetryDownloader) GetTopics() ([]string, error) { +func (d *RetryDownloader) GetTopics(ctx context.Context) ([]string, error) { var ( topics []string err error ) err = d.retry(func() error { - topics, err = d.Downloader.GetTopics() + topics, err = d.Downloader.GetTopics(ctx) return err }) @@ -86,14 +80,14 @@ func (d *RetryDownloader) GetTopics() ([]string, error) { } // GetMilestones returns a repository's milestones with retry -func (d *RetryDownloader) GetMilestones() ([]*Milestone, error) { +func (d *RetryDownloader) GetMilestones(ctx context.Context) ([]*Milestone, error) { var ( milestones []*Milestone err error ) err = d.retry(func() error { - milestones, err = d.Downloader.GetMilestones() + milestones, err = d.Downloader.GetMilestones(ctx) return err }) @@ -101,14 +95,14 @@ func (d *RetryDownloader) GetMilestones() ([]*Milestone, error) { } // GetReleases returns a repository's releases with retry -func (d *RetryDownloader) GetReleases() ([]*Release, error) { +func (d *RetryDownloader) GetReleases(ctx context.Context) ([]*Release, error) { var ( releases []*Release err error ) err = d.retry(func() error { - releases, err = d.Downloader.GetReleases() + releases, err = d.Downloader.GetReleases(ctx) return err }) @@ -116,14 +110,14 @@ func (d *RetryDownloader) GetReleases() ([]*Release, error) { } // GetLabels returns a repository's labels with retry -func (d *RetryDownloader) GetLabels() ([]*Label, error) { +func (d *RetryDownloader) GetLabels(ctx context.Context) ([]*Label, error) { var ( labels []*Label err error ) err = d.retry(func() error { - labels, err = d.Downloader.GetLabels() + labels, err = d.Downloader.GetLabels(ctx) return err }) @@ -131,7 +125,7 @@ func (d *RetryDownloader) GetLabels() ([]*Label, error) { } // GetIssues returns a repository's issues with retry -func (d *RetryDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) { +func (d *RetryDownloader) GetIssues(ctx context.Context, page, perPage int) ([]*Issue, bool, error) { var ( issues []*Issue isEnd bool @@ -139,7 +133,7 @@ func (d *RetryDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) { ) err = d.retry(func() error { - issues, isEnd, err = d.Downloader.GetIssues(page, perPage) + issues, isEnd, err = d.Downloader.GetIssues(ctx, page, perPage) return err }) @@ -147,7 +141,7 @@ func (d *RetryDownloader) GetIssues(page, perPage int) ([]*Issue, bool, error) { } // GetComments returns a repository's comments with retry -func (d *RetryDownloader) GetComments(commentable Commentable) ([]*Comment, bool, error) { +func (d *RetryDownloader) GetComments(ctx context.Context, commentable Commentable) ([]*Comment, bool, error) { var ( comments []*Comment isEnd bool @@ -155,7 +149,7 @@ func (d *RetryDownloader) GetComments(commentable Commentable) ([]*Comment, bool ) err = d.retry(func() error { - comments, isEnd, err = d.Downloader.GetComments(commentable) + comments, isEnd, err = d.Downloader.GetComments(ctx, commentable) return err }) @@ -163,7 +157,7 @@ func (d *RetryDownloader) GetComments(commentable Commentable) ([]*Comment, bool } // GetPullRequests returns a repository's pull requests with retry -func (d *RetryDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bool, error) { +func (d *RetryDownloader) GetPullRequests(ctx context.Context, page, perPage int) ([]*PullRequest, bool, error) { var ( prs []*PullRequest err error @@ -171,7 +165,7 @@ func (d *RetryDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bo ) err = d.retry(func() error { - prs, isEnd, err = d.Downloader.GetPullRequests(page, perPage) + prs, isEnd, err = d.Downloader.GetPullRequests(ctx, page, perPage) return err }) @@ -179,14 +173,13 @@ func (d *RetryDownloader) GetPullRequests(page, perPage int) ([]*PullRequest, bo } // GetReviews returns pull requests reviews -func (d *RetryDownloader) GetReviews(reviewable Reviewable) ([]*Review, error) { +func (d *RetryDownloader) GetReviews(ctx context.Context, reviewable Reviewable) ([]*Review, error) { var ( reviews []*Review err error ) - err = d.retry(func() error { - reviews, err = d.Downloader.GetReviews(reviewable) + reviews, err = d.Downloader.GetReviews(ctx, reviewable) return err }) diff --git a/modules/migration/uploader.go b/modules/migration/uploader.go index ff642aa4fa..65752e248e 100644 --- a/modules/migration/uploader.go +++ b/modules/migration/uploader.go @@ -4,20 +4,22 @@ package migration +import "context" + // Uploader uploads all the information of one repository type Uploader interface { MaxBatchInsertSize(tp string) int - CreateRepo(repo *Repository, opts MigrateOptions) error - CreateTopics(topic ...string) error - CreateMilestones(milestones ...*Milestone) error - CreateReleases(releases ...*Release) error - SyncTags() error - CreateLabels(labels ...*Label) error - CreateIssues(issues ...*Issue) error - CreateComments(comments ...*Comment) error - CreatePullRequests(prs ...*PullRequest) error - CreateReviews(reviews ...*Review) error + CreateRepo(ctx context.Context, repo *Repository, opts MigrateOptions) error + CreateTopics(ctx context.Context, topic ...string) error + CreateMilestones(ctx context.Context, milestones ...*Milestone) error + CreateReleases(ctx context.Context, releases ...*Release) error + SyncTags(ctx context.Context) error + CreateLabels(ctx context.Context, labels ...*Label) error + CreateIssues(ctx context.Context, issues ...*Issue) error + CreateComments(ctx context.Context, comments ...*Comment) error + CreatePullRequests(ctx context.Context, prs ...*PullRequest) error + CreateReviews(ctx context.Context, reviews ...*Review) error Rollback() error - Finish() error + Finish(ctx context.Context) error Close() } diff --git a/services/migrations/codebase.go b/services/migrations/codebase.go index 492fc908e9..880dd21497 100644 --- a/services/migrations/codebase.go +++ b/services/migrations/codebase.go @@ -66,7 +66,6 @@ type codebaseUser struct { // from Codebase type CodebaseDownloader struct { base.NullDownloader - ctx context.Context client *http.Client baseURL *url.URL projectURL *url.URL @@ -77,17 +76,11 @@ type CodebaseDownloader struct { commitMap map[string]string } -// SetContext set context -func (d *CodebaseDownloader) SetContext(ctx context.Context) { - d.ctx = ctx -} - // NewCodebaseDownloader creates a new downloader -func NewCodebaseDownloader(ctx context.Context, projectURL *url.URL, project, repoName, username, password string) *CodebaseDownloader { +func NewCodebaseDownloader(_ context.Context, projectURL *url.URL, project, repoName, username, password string) *CodebaseDownloader { baseURL, _ := url.Parse("https://api3.codebasehq.com") downloader := &CodebaseDownloader{ - ctx: ctx, baseURL: baseURL, projectURL: projectURL, project: project, @@ -127,7 +120,7 @@ func (d *CodebaseDownloader) FormatCloneURL(opts base.MigrateOptions, remoteAddr return opts.CloneAddr, nil } -func (d *CodebaseDownloader) callAPI(endpoint string, parameter map[string]string, result any) error { +func (d *CodebaseDownloader) callAPI(ctx context.Context, endpoint string, parameter map[string]string, result any) error { u, err := d.baseURL.Parse(endpoint) if err != nil { return err @@ -141,7 +134,7 @@ func (d *CodebaseDownloader) callAPI(endpoint string, parameter map[string]strin u.RawQuery = query.Encode() } - req, err := http.NewRequestWithContext(d.ctx, "GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { return err } @@ -158,7 +151,7 @@ func (d *CodebaseDownloader) callAPI(endpoint string, parameter map[string]strin // GetRepoInfo returns repository information // https://support.codebasehq.com/kb/projects -func (d *CodebaseDownloader) GetRepoInfo() (*base.Repository, error) { +func (d *CodebaseDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, error) { var rawRepository struct { XMLName xml.Name `xml:"repository"` Name string `xml:"name"` @@ -169,6 +162,7 @@ func (d *CodebaseDownloader) GetRepoInfo() (*base.Repository, error) { } err := d.callAPI( + ctx, fmt.Sprintf("/%s/%s", d.project, d.repoName), nil, &rawRepository, @@ -187,7 +181,7 @@ func (d *CodebaseDownloader) GetRepoInfo() (*base.Repository, error) { // GetMilestones returns milestones // https://support.codebasehq.com/kb/tickets-and-milestones/milestones -func (d *CodebaseDownloader) GetMilestones() ([]*base.Milestone, error) { +func (d *CodebaseDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone, error) { var rawMilestones struct { XMLName xml.Name `xml:"ticketing-milestone"` Type string `xml:"type,attr"` @@ -209,6 +203,7 @@ func (d *CodebaseDownloader) GetMilestones() ([]*base.Milestone, error) { } err := d.callAPI( + ctx, fmt.Sprintf("/%s/milestones", d.project), nil, &rawMilestones, @@ -245,7 +240,7 @@ func (d *CodebaseDownloader) GetMilestones() ([]*base.Milestone, error) { // GetLabels returns labels // https://support.codebasehq.com/kb/tickets-and-milestones/statuses-priorities-and-categories -func (d *CodebaseDownloader) GetLabels() ([]*base.Label, error) { +func (d *CodebaseDownloader) GetLabels(ctx context.Context) ([]*base.Label, error) { var rawTypes struct { XMLName xml.Name `xml:"ticketing-types"` Type string `xml:"type,attr"` @@ -259,6 +254,7 @@ func (d *CodebaseDownloader) GetLabels() ([]*base.Label, error) { } err := d.callAPI( + ctx, fmt.Sprintf("/%s/tickets/types", d.project), nil, &rawTypes, @@ -284,7 +280,7 @@ type codebaseIssueContext struct { // GetIssues returns issues, limits are not supported // https://support.codebasehq.com/kb/tickets-and-milestones // https://support.codebasehq.com/kb/tickets-and-milestones/updating-tickets -func (d *CodebaseDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) { +func (d *CodebaseDownloader) GetIssues(ctx context.Context, _, _ int) ([]*base.Issue, bool, error) { var rawIssues struct { XMLName xml.Name `xml:"tickets"` Type string `xml:"type,attr"` @@ -324,6 +320,7 @@ func (d *CodebaseDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, } err := d.callAPI( + ctx, fmt.Sprintf("/%s/tickets", d.project), nil, &rawIssues, @@ -358,6 +355,7 @@ func (d *CodebaseDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, } `xml:"ticket-note"` } err := d.callAPI( + ctx, fmt.Sprintf("/%s/tickets/%d/notes", d.project, issue.TicketID.Value), nil, ¬es, @@ -370,7 +368,7 @@ func (d *CodebaseDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, if len(note.Content) == 0 { continue } - poster := d.tryGetUser(note.UserID.Value) + poster := d.tryGetUser(ctx, note.UserID.Value) comments = append(comments, &base.Comment{ IssueIndex: issue.TicketID.Value, Index: note.ID.Value, @@ -390,7 +388,7 @@ func (d *CodebaseDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, if issue.Status.TreatAsClosed.Value { state = "closed" } - poster := d.tryGetUser(issue.ReporterID.Value) + poster := d.tryGetUser(ctx, issue.ReporterID.Value) issues = append(issues, &base.Issue{ Title: issue.Summary, Number: issue.TicketID.Value, @@ -419,7 +417,7 @@ func (d *CodebaseDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, } // GetComments returns comments -func (d *CodebaseDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) { +func (d *CodebaseDownloader) GetComments(_ context.Context, commentable base.Commentable) ([]*base.Comment, bool, error) { context, ok := commentable.GetContext().(codebaseIssueContext) if !ok { return nil, false, fmt.Errorf("unexpected context: %+v", commentable.GetContext()) @@ -430,7 +428,7 @@ func (d *CodebaseDownloader) GetComments(commentable base.Commentable) ([]*base. // GetPullRequests returns pull requests // https://support.codebasehq.com/kb/repositories/merge-requests -func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) { +func (d *CodebaseDownloader) GetPullRequests(ctx context.Context, page, perPage int) ([]*base.PullRequest, bool, error) { var rawMergeRequests struct { XMLName xml.Name `xml:"merge-requests"` Type string `xml:"type,attr"` @@ -443,6 +441,7 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq } err := d.callAPI( + ctx, fmt.Sprintf("/%s/%s/merge_requests", d.project, d.repoName), map[string]string{ "query": `"Target Project" is "` + d.repoName + `"`, @@ -503,6 +502,7 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq } `xml:"comments"` } err := d.callAPI( + ctx, fmt.Sprintf("/%s/%s/merge_requests/%d", d.project, d.repoName, mr.ID.Value), nil, &rawMergeRequest, @@ -531,7 +531,7 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq } continue } - poster := d.tryGetUser(comment.UserID.Value) + poster := d.tryGetUser(ctx, comment.UserID.Value) comments = append(comments, &base.Comment{ IssueIndex: number, Index: comment.ID.Value, @@ -547,7 +547,7 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq comments = append(comments, &base.Comment{}) } - poster := d.tryGetUser(rawMergeRequest.UserID.Value) + poster := d.tryGetUser(ctx, rawMergeRequest.UserID.Value) pullRequests = append(pullRequests, &base.PullRequest{ Title: rawMergeRequest.Subject, @@ -563,12 +563,12 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq MergedTime: mergedTime, Head: base.PullRequestBranch{ Ref: rawMergeRequest.SourceRef, - SHA: d.getHeadCommit(rawMergeRequest.SourceRef), + SHA: d.getHeadCommit(ctx, rawMergeRequest.SourceRef), RepoName: d.repoName, }, Base: base.PullRequestBranch{ Ref: rawMergeRequest.TargetRef, - SHA: d.getHeadCommit(rawMergeRequest.TargetRef), + SHA: d.getHeadCommit(ctx, rawMergeRequest.TargetRef), RepoName: d.repoName, }, ForeignIndex: rawMergeRequest.ID.Value, @@ -584,7 +584,7 @@ func (d *CodebaseDownloader) GetPullRequests(page, perPage int) ([]*base.PullReq return pullRequests, true, nil } -func (d *CodebaseDownloader) tryGetUser(userID int64) *codebaseUser { +func (d *CodebaseDownloader) tryGetUser(ctx context.Context, userID int64) *codebaseUser { if len(d.userMap) == 0 { var rawUsers struct { XMLName xml.Name `xml:"users"` @@ -602,6 +602,7 @@ func (d *CodebaseDownloader) tryGetUser(userID int64) *codebaseUser { } err := d.callAPI( + ctx, "/users", nil, &rawUsers, @@ -627,7 +628,7 @@ func (d *CodebaseDownloader) tryGetUser(userID int64) *codebaseUser { return user } -func (d *CodebaseDownloader) getHeadCommit(ref string) string { +func (d *CodebaseDownloader) getHeadCommit(ctx context.Context, ref string) string { commitRef, ok := d.commitMap[ref] if !ok { var rawCommits struct { @@ -638,6 +639,7 @@ func (d *CodebaseDownloader) getHeadCommit(ref string) string { } `xml:"commit"` } err := d.callAPI( + ctx, fmt.Sprintf("/%s/%s/commits/%s", d.project, d.repoName, ref), nil, &rawCommits, diff --git a/services/migrations/codebase_test.go b/services/migrations/codebase_test.go index 68721e0641..ec4da1bff5 100644 --- a/services/migrations/codebase_test.go +++ b/services/migrations/codebase_test.go @@ -30,9 +30,9 @@ func TestCodebaseDownloadRepo(t *testing.T) { if cloneUser != "" { u.User = url.UserPassword(cloneUser, clonePassword) } - + ctx := context.Background() factory := &CodebaseDownloaderFactory{} - downloader, err := factory.New(context.Background(), base.MigrateOptions{ + downloader, err := factory.New(ctx, base.MigrateOptions{ CloneAddr: u.String(), AuthUsername: apiUser, AuthPassword: apiPassword, @@ -40,7 +40,7 @@ func TestCodebaseDownloadRepo(t *testing.T) { if err != nil { t.Fatalf("Error creating Codebase downloader: %v", err) } - repo, err := downloader.GetRepoInfo() + repo, err := downloader.GetRepoInfo(ctx) assert.NoError(t, err) assertRepositoryEqual(t, &base.Repository{ Name: "test", @@ -50,7 +50,7 @@ func TestCodebaseDownloadRepo(t *testing.T) { OriginalURL: cloneAddr, }, repo) - milestones, err := downloader.GetMilestones() + milestones, err := downloader.GetMilestones(ctx) assert.NoError(t, err) assertMilestonesEqual(t, []*base.Milestone{ { @@ -65,11 +65,11 @@ func TestCodebaseDownloadRepo(t *testing.T) { }, }, milestones) - labels, err := downloader.GetLabels() + labels, err := downloader.GetLabels(ctx) assert.NoError(t, err) assert.Len(t, labels, 4) - issues, isEnd, err := downloader.GetIssues(1, 2) + issues, isEnd, err := downloader.GetIssues(ctx, 1, 2) assert.NoError(t, err) assert.True(t, isEnd) assertIssuesEqual(t, []*base.Issue{ @@ -106,7 +106,7 @@ func TestCodebaseDownloadRepo(t *testing.T) { }, }, issues) - comments, _, err := downloader.GetComments(issues[0]) + comments, _, err := downloader.GetComments(ctx, issues[0]) assert.NoError(t, err) assertCommentsEqual(t, []*base.Comment{ { @@ -119,7 +119,7 @@ func TestCodebaseDownloadRepo(t *testing.T) { }, }, comments) - prs, _, err := downloader.GetPullRequests(1, 1) + prs, _, err := downloader.GetPullRequests(ctx, 1, 1) assert.NoError(t, err) assertPullRequestsEqual(t, []*base.PullRequest{ { @@ -144,7 +144,7 @@ func TestCodebaseDownloadRepo(t *testing.T) { }, }, prs) - rvs, err := downloader.GetReviews(prs[0]) + rvs, err := downloader.GetReviews(ctx, prs[0]) assert.NoError(t, err) assert.Empty(t, rvs) } diff --git a/services/migrations/codecommit.go b/services/migrations/codecommit.go index fead527f5b..c45f9e5943 100644 --- a/services/migrations/codecommit.go +++ b/services/migrations/codecommit.go @@ -62,9 +62,8 @@ func (c *CodeCommitDownloaderFactory) GitServiceType() structs.GitServiceType { return structs.CodeCommitService } -func NewCodeCommitDownloader(ctx context.Context, repoName, baseURL, accessKeyID, secretAccessKey, region string) *CodeCommitDownloader { +func NewCodeCommitDownloader(_ context.Context, repoName, baseURL, accessKeyID, secretAccessKey, region string) *CodeCommitDownloader { downloader := CodeCommitDownloader{ - ctx: ctx, repoName: repoName, baseURL: baseURL, codeCommitClient: codecommit.New(codecommit.Options{ @@ -79,21 +78,15 @@ func NewCodeCommitDownloader(ctx context.Context, repoName, baseURL, accessKeyID // CodeCommitDownloader implements a downloader for AWS CodeCommit type CodeCommitDownloader struct { base.NullDownloader - ctx context.Context codeCommitClient *codecommit.Client repoName string baseURL string allPullRequestIDs []string } -// SetContext set context -func (c *CodeCommitDownloader) SetContext(ctx context.Context) { - c.ctx = ctx -} - // GetRepoInfo returns a repository information -func (c *CodeCommitDownloader) GetRepoInfo() (*base.Repository, error) { - output, err := c.codeCommitClient.GetRepository(c.ctx, &codecommit.GetRepositoryInput{ +func (c *CodeCommitDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, error) { + output, err := c.codeCommitClient.GetRepository(ctx, &codecommit.GetRepositoryInput{ RepositoryName: util.ToPointer(c.repoName), }) if err != nil { @@ -117,14 +110,14 @@ func (c *CodeCommitDownloader) GetRepoInfo() (*base.Repository, error) { } // GetComments returns comments of an issue or PR -func (c *CodeCommitDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) { +func (c *CodeCommitDownloader) GetComments(ctx context.Context, commentable base.Commentable) ([]*base.Comment, bool, error) { var ( nextToken *string comments []*base.Comment ) for { - resp, err := c.codeCommitClient.GetCommentsForPullRequest(c.ctx, &codecommit.GetCommentsForPullRequestInput{ + resp, err := c.codeCommitClient.GetCommentsForPullRequest(ctx, &codecommit.GetCommentsForPullRequestInput{ NextToken: nextToken, PullRequestId: util.ToPointer(strconv.FormatInt(commentable.GetForeignIndex(), 10)), }) @@ -155,8 +148,8 @@ func (c *CodeCommitDownloader) GetComments(commentable base.Commentable) ([]*bas } // GetPullRequests returns pull requests according page and perPage -func (c *CodeCommitDownloader) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) { - allPullRequestIDs, err := c.getAllPullRequestIDs() +func (c *CodeCommitDownloader) GetPullRequests(ctx context.Context, page, perPage int) ([]*base.PullRequest, bool, error) { + allPullRequestIDs, err := c.getAllPullRequestIDs(ctx) if err != nil { return nil, false, err } @@ -170,7 +163,7 @@ func (c *CodeCommitDownloader) GetPullRequests(page, perPage int) ([]*base.PullR prs := make([]*base.PullRequest, 0, len(batch)) for _, id := range batch { - output, err := c.codeCommitClient.GetPullRequest(c.ctx, &codecommit.GetPullRequestInput{ + output, err := c.codeCommitClient.GetPullRequest(ctx, &codecommit.GetPullRequestInput{ PullRequestId: util.ToPointer(id), }) if err != nil { @@ -231,7 +224,7 @@ func (c *CodeCommitDownloader) FormatCloneURL(opts MigrateOptions, remoteAddr st return u.String(), nil } -func (c *CodeCommitDownloader) getAllPullRequestIDs() ([]string, error) { +func (c *CodeCommitDownloader) getAllPullRequestIDs(ctx context.Context) ([]string, error) { if len(c.allPullRequestIDs) > 0 { return c.allPullRequestIDs, nil } @@ -242,7 +235,7 @@ func (c *CodeCommitDownloader) getAllPullRequestIDs() ([]string, error) { ) for { - output, err := c.codeCommitClient.ListPullRequests(c.ctx, &codecommit.ListPullRequestsInput{ + output, err := c.codeCommitClient.ListPullRequests(ctx, &codecommit.ListPullRequestsInput{ RepositoryName: util.ToPointer(c.repoName), NextToken: nextToken, }) diff --git a/services/migrations/dump.go b/services/migrations/dump.go index 07812002af..11efc18163 100644 --- a/services/migrations/dump.go +++ b/services/migrations/dump.go @@ -32,7 +32,6 @@ var _ base.Uploader = &RepositoryDumper{} // RepositoryDumper implements an Uploader to the local directory type RepositoryDumper struct { - ctx context.Context baseDir string repoOwner string repoName string @@ -56,7 +55,6 @@ func NewRepositoryDumper(ctx context.Context, baseDir, repoOwner, repoName strin return nil, err } return &RepositoryDumper{ - ctx: ctx, opts: opts, baseDir: baseDir, repoOwner: repoOwner, @@ -105,7 +103,7 @@ func (g *RepositoryDumper) setURLToken(remoteAddr string) (string, error) { } // CreateRepo creates a repository -func (g *RepositoryDumper) CreateRepo(repo *base.Repository, opts base.MigrateOptions) error { +func (g *RepositoryDumper) CreateRepo(ctx context.Context, repo *base.Repository, opts base.MigrateOptions) error { f, err := os.Create(filepath.Join(g.baseDir, "repo.yml")) if err != nil { return err @@ -149,7 +147,7 @@ func (g *RepositoryDumper) CreateRepo(repo *base.Repository, opts base.MigrateOp return err } - err = git.Clone(g.ctx, remoteAddr, repoPath, git.CloneRepoOptions{ + err = git.Clone(ctx, remoteAddr, repoPath, git.CloneRepoOptions{ Mirror: true, Quiet: true, Timeout: migrateTimeout, @@ -158,19 +156,19 @@ func (g *RepositoryDumper) CreateRepo(repo *base.Repository, opts base.MigrateOp if err != nil { return fmt.Errorf("Clone: %w", err) } - if err := git.WriteCommitGraph(g.ctx, repoPath); err != nil { + if err := git.WriteCommitGraph(ctx, repoPath); err != nil { return err } if opts.Wiki { wikiPath := g.wikiPath() - wikiRemotePath := repository.WikiRemoteURL(g.ctx, remoteAddr) + wikiRemotePath := repository.WikiRemoteURL(ctx, remoteAddr) if len(wikiRemotePath) > 0 { if err := os.MkdirAll(wikiPath, os.ModePerm); err != nil { return fmt.Errorf("Failed to remove %s: %w", wikiPath, err) } - if err := git.Clone(g.ctx, wikiRemotePath, wikiPath, git.CloneRepoOptions{ + if err := git.Clone(ctx, wikiRemotePath, wikiPath, git.CloneRepoOptions{ Mirror: true, Quiet: true, Timeout: migrateTimeout, @@ -181,13 +179,13 @@ func (g *RepositoryDumper) CreateRepo(repo *base.Repository, opts base.MigrateOp if err := os.RemoveAll(wikiPath); err != nil { return fmt.Errorf("Failed to remove %s: %w", wikiPath, err) } - } else if err := git.WriteCommitGraph(g.ctx, wikiPath); err != nil { + } else if err := git.WriteCommitGraph(ctx, wikiPath); err != nil { return err } } } - g.gitRepo, err = git.OpenRepository(g.ctx, g.gitPath()) + g.gitRepo, err = git.OpenRepository(ctx, g.gitPath()) return err } @@ -220,7 +218,7 @@ func (g *RepositoryDumper) Close() { } // CreateTopics creates topics -func (g *RepositoryDumper) CreateTopics(topics ...string) error { +func (g *RepositoryDumper) CreateTopics(_ context.Context, topics ...string) error { f, err := os.Create(filepath.Join(g.baseDir, "topic.yml")) if err != nil { return err @@ -242,7 +240,7 @@ func (g *RepositoryDumper) CreateTopics(topics ...string) error { } // CreateMilestones creates milestones -func (g *RepositoryDumper) CreateMilestones(milestones ...*base.Milestone) error { +func (g *RepositoryDumper) CreateMilestones(_ context.Context, milestones ...*base.Milestone) error { var err error if g.milestoneFile == nil { g.milestoneFile, err = os.Create(filepath.Join(g.baseDir, "milestone.yml")) @@ -264,7 +262,7 @@ func (g *RepositoryDumper) CreateMilestones(milestones ...*base.Milestone) error } // CreateLabels creates labels -func (g *RepositoryDumper) CreateLabels(labels ...*base.Label) error { +func (g *RepositoryDumper) CreateLabels(_ context.Context, labels ...*base.Label) error { var err error if g.labelFile == nil { g.labelFile, err = os.Create(filepath.Join(g.baseDir, "label.yml")) @@ -286,7 +284,7 @@ func (g *RepositoryDumper) CreateLabels(labels ...*base.Label) error { } // CreateReleases creates releases -func (g *RepositoryDumper) CreateReleases(releases ...*base.Release) error { +func (g *RepositoryDumper) CreateReleases(_ context.Context, releases ...*base.Release) error { if g.opts.ReleaseAssets { for _, release := range releases { attachDir := filepath.Join("release_assets", release.TagName) @@ -354,12 +352,12 @@ func (g *RepositoryDumper) CreateReleases(releases ...*base.Release) error { } // SyncTags syncs releases with tags in the database -func (g *RepositoryDumper) SyncTags() error { +func (g *RepositoryDumper) SyncTags(ctx context.Context) error { return nil } // CreateIssues creates issues -func (g *RepositoryDumper) CreateIssues(issues ...*base.Issue) error { +func (g *RepositoryDumper) CreateIssues(_ context.Context, issues ...*base.Issue) error { var err error if g.issueFile == nil { g.issueFile, err = os.Create(filepath.Join(g.baseDir, "issue.yml")) @@ -412,7 +410,7 @@ func (g *RepositoryDumper) encodeItems(number int64, items []any, dir string, it } // CreateComments creates comments of issues -func (g *RepositoryDumper) CreateComments(comments ...*base.Comment) error { +func (g *RepositoryDumper) CreateComments(_ context.Context, comments ...*base.Comment) error { commentsMap := make(map[int64][]any, len(comments)) for _, comment := range comments { commentsMap[comment.IssueIndex] = append(commentsMap[comment.IssueIndex], comment) @@ -421,7 +419,7 @@ func (g *RepositoryDumper) CreateComments(comments ...*base.Comment) error { return g.createItems(g.commentDir(), g.commentFiles, commentsMap) } -func (g *RepositoryDumper) handlePullRequest(pr *base.PullRequest) error { +func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullRequest) error { // SECURITY: this pr must have been ensured safe if !pr.EnsuredSafe { log.Error("PR #%d in %s/%s has not been checked for safety ... We will ignore this.", pr.Number, g.repoOwner, g.repoName) @@ -490,7 +488,7 @@ func (g *RepositoryDumper) handlePullRequest(pr *base.PullRequest) error { if pr.Head.CloneURL == "" || pr.Head.Ref == "" { // Set head information if pr.Head.SHA is available if pr.Head.SHA != "" { - _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) + _, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.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) } @@ -520,7 +518,7 @@ func (g *RepositoryDumper) handlePullRequest(pr *base.PullRequest) error { if !ok { // Set head information if pr.Head.SHA is available if pr.Head.SHA != "" { - _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) + _, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.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) } @@ -555,7 +553,7 @@ func (g *RepositoryDumper) handlePullRequest(pr *base.PullRequest) error { fetchArg = git.BranchPrefix + fetchArg } - _, _, err = git.NewCommand(g.ctx, "fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(&git.RunOpts{Dir: g.gitPath()}) + _, _, err = git.NewCommand(ctx, "fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(&git.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 @@ -579,7 +577,7 @@ func (g *RepositoryDumper) handlePullRequest(pr *base.PullRequest) error { pr.Head.SHA = headSha } if pr.Head.SHA != "" { - _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.gitPath()}) + _, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.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) } @@ -589,7 +587,7 @@ func (g *RepositoryDumper) handlePullRequest(pr *base.PullRequest) error { } // CreatePullRequests creates pull requests -func (g *RepositoryDumper) CreatePullRequests(prs ...*base.PullRequest) error { +func (g *RepositoryDumper) CreatePullRequests(ctx context.Context, prs ...*base.PullRequest) error { var err error if g.pullrequestFile == nil { if err := os.MkdirAll(g.baseDir, os.ModePerm); err != nil { @@ -607,7 +605,7 @@ func (g *RepositoryDumper) CreatePullRequests(prs ...*base.PullRequest) error { count := 0 for i := 0; i < len(prs); i++ { pr := prs[i] - if err := g.handlePullRequest(pr); err != nil { + if err := g.handlePullRequest(ctx, pr); err != nil { log.Error("PR #%d in %s/%s failed - skipping", pr.Number, g.repoOwner, g.repoName, err) continue } @@ -620,7 +618,7 @@ func (g *RepositoryDumper) CreatePullRequests(prs ...*base.PullRequest) error { } // CreateReviews create pull request reviews -func (g *RepositoryDumper) CreateReviews(reviews ...*base.Review) error { +func (g *RepositoryDumper) CreateReviews(_ context.Context, reviews ...*base.Review) error { reviewsMap := make(map[int64][]any, len(reviews)) for _, review := range reviews { reviewsMap[review.IssueIndex] = append(reviewsMap[review.IssueIndex], review) @@ -636,7 +634,7 @@ func (g *RepositoryDumper) Rollback() error { } // Finish when migrating succeed, this will update something. -func (g *RepositoryDumper) Finish() error { +func (g *RepositoryDumper) Finish(_ context.Context) error { return nil } diff --git a/services/migrations/git.go b/services/migrations/git.go index 22ffd5e765..1ed99499a1 100644 --- a/services/migrations/git.go +++ b/services/migrations/git.go @@ -28,12 +28,8 @@ func NewPlainGitDownloader(ownerName, repoName, remoteURL string) *PlainGitDownl } } -// SetContext set context -func (g *PlainGitDownloader) SetContext(ctx context.Context) { -} - // GetRepoInfo returns a repository information -func (g *PlainGitDownloader) GetRepoInfo() (*base.Repository, error) { +func (g *PlainGitDownloader) GetRepoInfo(_ context.Context) (*base.Repository, error) { // convert github repo to stand Repo return &base.Repository{ Owner: g.ownerName, @@ -43,6 +39,6 @@ func (g *PlainGitDownloader) GetRepoInfo() (*base.Repository, error) { } // GetTopics return empty string slice -func (g PlainGitDownloader) GetTopics() ([]string, error) { +func (g PlainGitDownloader) GetTopics(_ context.Context) ([]string, error) { return []string{}, nil } diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go index 272bf02e11..f92f318293 100644 --- a/services/migrations/gitea_downloader.go +++ b/services/migrations/gitea_downloader.go @@ -67,7 +67,6 @@ func (f *GiteaDownloaderFactory) GitServiceType() structs.GitServiceType { // GiteaDownloader implements a Downloader interface to get repository information's type GiteaDownloader struct { base.NullDownloader - ctx context.Context client *gitea_sdk.Client baseURL string repoOwner string @@ -114,7 +113,6 @@ func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, passwo } return &GiteaDownloader{ - ctx: ctx, client: giteaClient, baseURL: baseURL, repoOwner: path[0], @@ -124,11 +122,6 @@ func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, passwo }, nil } -// SetContext set context -func (g *GiteaDownloader) SetContext(ctx context.Context) { - g.ctx = ctx -} - // String implements Stringer func (g *GiteaDownloader) String() string { return fmt.Sprintf("migration from gitea server %s %s/%s", g.baseURL, g.repoOwner, g.repoName) @@ -142,7 +135,7 @@ func (g *GiteaDownloader) LogString() string { } // GetRepoInfo returns a repository information -func (g *GiteaDownloader) GetRepoInfo() (*base.Repository, error) { +func (g *GiteaDownloader) GetRepoInfo(_ context.Context) (*base.Repository, error) { if g == nil { return nil, errors.New("error: GiteaDownloader is nil") } @@ -164,19 +157,19 @@ func (g *GiteaDownloader) GetRepoInfo() (*base.Repository, error) { } // GetTopics return gitea topics -func (g *GiteaDownloader) GetTopics() ([]string, error) { +func (g *GiteaDownloader) GetTopics(_ context.Context) ([]string, error) { topics, _, err := g.client.ListRepoTopics(g.repoOwner, g.repoName, gitea_sdk.ListRepoTopicsOptions{}) return topics, err } // GetMilestones returns milestones -func (g *GiteaDownloader) GetMilestones() ([]*base.Milestone, error) { +func (g *GiteaDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone, error) { milestones := make([]*base.Milestone, 0, g.maxPerPage) for i := 1; ; i++ { // make sure gitea can shutdown gracefully select { - case <-g.ctx.Done(): + case <-ctx.Done(): return nil, nil default: } @@ -235,13 +228,13 @@ func (g *GiteaDownloader) convertGiteaLabel(label *gitea_sdk.Label) *base.Label } // GetLabels returns labels -func (g *GiteaDownloader) GetLabels() ([]*base.Label, error) { +func (g *GiteaDownloader) GetLabels(ctx context.Context) ([]*base.Label, error) { labels := make([]*base.Label, 0, g.maxPerPage) for i := 1; ; i++ { // make sure gitea can shutdown gracefully select { - case <-g.ctx.Done(): + case <-ctx.Done(): return nil, nil default: } @@ -323,13 +316,13 @@ func (g *GiteaDownloader) convertGiteaRelease(rel *gitea_sdk.Release) *base.Rele } // GetReleases returns releases -func (g *GiteaDownloader) GetReleases() ([]*base.Release, error) { +func (g *GiteaDownloader) GetReleases(ctx context.Context) ([]*base.Release, error) { releases := make([]*base.Release, 0, g.maxPerPage) for i := 1; ; i++ { // make sure gitea can shutdown gracefully select { - case <-g.ctx.Done(): + case <-ctx.Done(): return nil, nil default: } @@ -395,7 +388,7 @@ func (g *GiteaDownloader) getCommentReactions(commentID int64) ([]*base.Reaction } // GetIssues returns issues according start and limit -func (g *GiteaDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) { +func (g *GiteaDownloader) GetIssues(_ context.Context, page, perPage int) ([]*base.Issue, bool, error) { if perPage > g.maxPerPage { perPage = g.maxPerPage } @@ -458,13 +451,13 @@ func (g *GiteaDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, err } // GetComments returns comments according issueNumber -func (g *GiteaDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) { +func (g *GiteaDownloader) GetComments(ctx context.Context, commentable base.Commentable) ([]*base.Comment, bool, error) { allComments := make([]*base.Comment, 0, g.maxPerPage) for i := 1; ; i++ { // make sure gitea can shutdown gracefully select { - case <-g.ctx.Done(): + case <-ctx.Done(): return nil, false, nil default: } @@ -504,7 +497,7 @@ func (g *GiteaDownloader) GetComments(commentable base.Commentable) ([]*base.Com } // GetPullRequests returns pull requests according page and perPage -func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) { +func (g *GiteaDownloader) GetPullRequests(_ context.Context, page, perPage int) ([]*base.PullRequest, bool, error) { if perPage > g.maxPerPage { perPage = g.maxPerPage } @@ -624,7 +617,7 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques } // GetReviews returns pull requests review -func (g *GiteaDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) { +func (g *GiteaDownloader) GetReviews(ctx context.Context, reviewable base.Reviewable) ([]*base.Review, error) { if err := g.client.CheckServerVersionConstraint(">=1.12"); err != nil { log.Info("GiteaDownloader: instance to old, skip GetReviews") return nil, nil @@ -635,7 +628,7 @@ func (g *GiteaDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Review for i := 1; ; i++ { // make sure gitea can shutdown gracefully select { - case <-g.ctx.Done(): + case <-ctx.Done(): return nil, nil default: } diff --git a/services/migrations/gitea_downloader_test.go b/services/migrations/gitea_downloader_test.go index 6f6ef99d96..3dccc4017e 100644 --- a/services/migrations/gitea_downloader_test.go +++ b/services/migrations/gitea_downloader_test.go @@ -28,12 +28,12 @@ func TestGiteaDownloadRepo(t *testing.T) { if err != nil || resp.StatusCode != http.StatusOK { t.Skipf("Can't reach https://gitea.com, skipping %s", t.Name()) } - - downloader, err := NewGiteaDownloader(context.Background(), "https://gitea.com", "gitea/test_repo", "", "", giteaToken) + ctx := context.Background() + downloader, err := NewGiteaDownloader(ctx, "https://gitea.com", "gitea/test_repo", "", "", giteaToken) require.NoError(t, err, "NewGiteaDownloader error occur") require.NotNil(t, downloader, "NewGiteaDownloader is nil") - repo, err := downloader.GetRepoInfo() + repo, err := downloader.GetRepoInfo(ctx) assert.NoError(t, err) assertRepositoryEqual(t, &base.Repository{ Name: "test_repo", @@ -45,12 +45,12 @@ func TestGiteaDownloadRepo(t *testing.T) { DefaultBranch: "master", }, repo) - topics, err := downloader.GetTopics() + topics, err := downloader.GetTopics(ctx) assert.NoError(t, err) sort.Strings(topics) assert.EqualValues(t, []string{"ci", "gitea", "migration", "test"}, topics) - labels, err := downloader.GetLabels() + labels, err := downloader.GetLabels(ctx) assert.NoError(t, err) assertLabelsEqual(t, []*base.Label{ { @@ -80,7 +80,7 @@ func TestGiteaDownloadRepo(t *testing.T) { }, }, labels) - milestones, err := downloader.GetMilestones() + milestones, err := downloader.GetMilestones(ctx) assert.NoError(t, err) assertMilestonesEqual(t, []*base.Milestone{ { @@ -100,7 +100,7 @@ func TestGiteaDownloadRepo(t *testing.T) { }, }, milestones) - releases, err := downloader.GetReleases() + releases, err := downloader.GetReleases(ctx) assert.NoError(t, err) assertReleasesEqual(t, []*base.Release{ { @@ -131,13 +131,13 @@ func TestGiteaDownloadRepo(t *testing.T) { }, }, releases) - issues, isEnd, err := downloader.GetIssues(1, 50) + issues, isEnd, err := downloader.GetIssues(ctx, 1, 50) assert.NoError(t, err) assert.True(t, isEnd) assert.Len(t, issues, 7) assert.EqualValues(t, "open", issues[0].State) - issues, isEnd, err = downloader.GetIssues(3, 2) + issues, isEnd, err = downloader.GetIssues(ctx, 3, 2) assert.NoError(t, err) assert.False(t, isEnd) @@ -194,7 +194,7 @@ func TestGiteaDownloadRepo(t *testing.T) { }, }, issues) - comments, _, err := downloader.GetComments(&base.Issue{Number: 4, ForeignIndex: 4}) + comments, _, err := downloader.GetComments(ctx, &base.Issue{Number: 4, ForeignIndex: 4}) assert.NoError(t, err) assertCommentsEqual(t, []*base.Comment{ { @@ -217,11 +217,11 @@ func TestGiteaDownloadRepo(t *testing.T) { }, }, comments) - prs, isEnd, err := downloader.GetPullRequests(1, 50) + prs, isEnd, err := downloader.GetPullRequests(ctx, 1, 50) assert.NoError(t, err) assert.True(t, isEnd) assert.Len(t, prs, 6) - prs, isEnd, err = downloader.GetPullRequests(1, 3) + prs, isEnd, err = downloader.GetPullRequests(ctx, 1, 3) assert.NoError(t, err) assert.False(t, isEnd) assert.Len(t, prs, 3) @@ -259,7 +259,7 @@ func TestGiteaDownloadRepo(t *testing.T) { PatchURL: "https://gitea.com/gitea/test_repo/pulls/12.patch", }, prs[1]) - reviews, err := downloader.GetReviews(&base.Issue{Number: 7, ForeignIndex: 7}) + reviews, err := downloader.GetReviews(ctx, &base.Issue{Number: 7, ForeignIndex: 7}) assert.NoError(t, err) assertReviewsEqual(t, []*base.Review{ { diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index 9e06b77b66..eb16d6cb42 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -41,7 +41,6 @@ var _ base.Uploader = &GiteaLocalUploader{} // GiteaLocalUploader implements an Uploader to gitea sites type GiteaLocalUploader struct { - ctx context.Context doer *user_model.User repoOwner string repoName string @@ -58,9 +57,8 @@ type GiteaLocalUploader struct { } // NewGiteaLocalUploader creates an gitea Uploader via gitea API v1 -func NewGiteaLocalUploader(ctx context.Context, doer *user_model.User, repoOwner, repoName string) *GiteaLocalUploader { +func NewGiteaLocalUploader(_ context.Context, doer *user_model.User, repoOwner, repoName string) *GiteaLocalUploader { return &GiteaLocalUploader{ - ctx: ctx, doer: doer, repoOwner: repoOwner, repoName: repoName, @@ -93,15 +91,15 @@ func (g *GiteaLocalUploader) MaxBatchInsertSize(tp string) int { } // CreateRepo creates a repository -func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.MigrateOptions) error { - owner, err := user_model.GetUserByName(g.ctx, g.repoOwner) +func (g *GiteaLocalUploader) CreateRepo(ctx context.Context, repo *base.Repository, opts base.MigrateOptions) error { + owner, err := user_model.GetUserByName(ctx, g.repoOwner) if err != nil { return err } var r *repo_model.Repository if opts.MigrateToRepoID <= 0 { - r, err = repo_service.CreateRepositoryDirectly(g.ctx, g.doer, owner, repo_service.CreateRepoOptions{ + r, err = repo_service.CreateRepositoryDirectly(ctx, g.doer, owner, repo_service.CreateRepoOptions{ Name: g.repoName, Description: repo.Description, OriginalURL: repo.OriginalURL, @@ -111,7 +109,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate Status: repo_model.RepositoryBeingMigrated, }) } else { - r, err = repo_model.GetRepositoryByID(g.ctx, opts.MigrateToRepoID) + r, err = repo_model.GetRepositoryByID(ctx, opts.MigrateToRepoID) } if err != nil { return err @@ -119,7 +117,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate r.DefaultBranch = repo.DefaultBranch r.Description = repo.Description - r, err = repo_service.MigrateRepositoryGitData(g.ctx, owner, r, base.MigrateOptions{ + r, err = repo_service.MigrateRepositoryGitData(ctx, owner, r, base.MigrateOptions{ RepoName: g.repoName, Description: repo.Description, OriginalURL: repo.OriginalURL, @@ -139,7 +137,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate if err != nil { return err } - g.gitRepo, err = gitrepo.OpenRepository(g.ctx, g.repo) + g.gitRepo, err = gitrepo.OpenRepository(ctx, g.repo) if err != nil { return err } @@ -150,7 +148,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate return err } g.repo.ObjectFormatName = objectFormat.Name() - return repo_model.UpdateRepositoryCols(g.ctx, g.repo, "object_format_name") + return repo_model.UpdateRepositoryCols(ctx, g.repo, "object_format_name") } // Close closes this uploader @@ -161,7 +159,7 @@ func (g *GiteaLocalUploader) Close() { } // CreateTopics creates topics -func (g *GiteaLocalUploader) CreateTopics(topics ...string) error { +func (g *GiteaLocalUploader) CreateTopics(ctx context.Context, topics ...string) error { // Ignore topics too long for the db c := 0 for _, topic := range topics { @@ -173,11 +171,11 @@ func (g *GiteaLocalUploader) CreateTopics(topics ...string) error { c++ } topics = topics[:c] - return repo_model.SaveTopics(g.ctx, g.repo.ID, topics...) + return repo_model.SaveTopics(ctx, g.repo.ID, topics...) } // CreateMilestones creates milestones -func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) error { +func (g *GiteaLocalUploader) CreateMilestones(ctx context.Context, milestones ...*base.Milestone) error { mss := make([]*issues_model.Milestone, 0, len(milestones)) for _, milestone := range milestones { var deadline timeutil.TimeStamp @@ -216,7 +214,7 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err mss = append(mss, &ms) } - err := issues_model.InsertMilestones(g.ctx, mss...) + err := issues_model.InsertMilestones(ctx, mss...) if err != nil { return err } @@ -228,7 +226,7 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err } // CreateLabels creates labels -func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { +func (g *GiteaLocalUploader) CreateLabels(ctx context.Context, labels ...*base.Label) error { lbs := make([]*issues_model.Label, 0, len(labels)) for _, l := range labels { if color, err := label.NormalizeColor(l.Color); err != nil { @@ -247,7 +245,7 @@ func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { }) } - err := issues_model.NewLabels(g.ctx, lbs...) + err := issues_model.NewLabels(ctx, lbs...) if err != nil { return err } @@ -258,7 +256,7 @@ func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { } // CreateReleases creates releases -func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { +func (g *GiteaLocalUploader) CreateReleases(ctx context.Context, releases ...*base.Release) error { rels := make([]*repo_model.Release, 0, len(releases)) for _, release := range releases { if release.Created.IsZero() { @@ -292,7 +290,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { CreatedUnix: timeutil.TimeStamp(release.Created.Unix()), } - if err := g.remapUser(release, &rel); err != nil { + if err := g.remapUser(ctx, release, &rel); err != nil { return err } @@ -361,16 +359,16 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { rels = append(rels, &rel) } - return repo_model.InsertReleases(g.ctx, rels...) + return repo_model.InsertReleases(ctx, rels...) } // SyncTags syncs releases with tags in the database -func (g *GiteaLocalUploader) SyncTags() error { - return repo_module.SyncReleasesWithTags(g.ctx, g.repo, g.gitRepo) +func (g *GiteaLocalUploader) SyncTags(ctx context.Context) error { + return repo_module.SyncReleasesWithTags(ctx, g.repo, g.gitRepo) } // CreateIssues creates issues -func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { +func (g *GiteaLocalUploader) CreateIssues(ctx context.Context, issues ...*base.Issue) error { iss := make([]*issues_model.Issue, 0, len(issues)) for _, issue := range issues { var labels []*issues_model.Label @@ -419,7 +417,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { UpdatedUnix: timeutil.TimeStamp(issue.Updated.Unix()), } - if err := g.remapUser(issue, &is); err != nil { + if err := g.remapUser(ctx, issue, &is); err != nil { return err } @@ -432,7 +430,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { Type: reaction.Content, CreatedUnix: timeutil.TimeStampNow(), } - if err := g.remapUser(reaction, &res); err != nil { + if err := g.remapUser(ctx, reaction, &res); err != nil { return err } is.Reactions = append(is.Reactions, &res) @@ -441,7 +439,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { } if len(iss) > 0 { - if err := issues_model.InsertIssues(g.ctx, iss...); err != nil { + if err := issues_model.InsertIssues(ctx, iss...); err != nil { return err } @@ -454,7 +452,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { } // CreateComments creates comments of issues -func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { +func (g *GiteaLocalUploader) CreateComments(ctx context.Context, comments ...*base.Comment) error { cms := make([]*issues_model.Comment, 0, len(comments)) for _, comment := range comments { var issue *issues_model.Issue @@ -513,7 +511,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { default: } - if err := g.remapUser(comment, &cm); err != nil { + if err := g.remapUser(ctx, comment, &cm); err != nil { return err } @@ -523,7 +521,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { Type: reaction.Content, CreatedUnix: timeutil.TimeStampNow(), } - if err := g.remapUser(reaction, &res); err != nil { + if err := g.remapUser(ctx, reaction, &res); err != nil { return err } cm.Reactions = append(cm.Reactions, &res) @@ -535,35 +533,35 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { if len(cms) == 0 { return nil } - return issues_model.InsertIssueComments(g.ctx, cms) + return issues_model.InsertIssueComments(ctx, cms) } // CreatePullRequests creates pull requests -func (g *GiteaLocalUploader) CreatePullRequests(prs ...*base.PullRequest) error { +func (g *GiteaLocalUploader) CreatePullRequests(ctx context.Context, prs ...*base.PullRequest) error { gprs := make([]*issues_model.PullRequest, 0, len(prs)) for _, pr := range prs { - gpr, err := g.newPullRequest(pr) + gpr, err := g.newPullRequest(ctx, pr) if err != nil { return err } - if err := g.remapUser(pr, gpr.Issue); err != nil { + if err := g.remapUser(ctx, pr, gpr.Issue); err != nil { return err } gprs = append(gprs, gpr) } - if err := issues_model.InsertPullRequests(g.ctx, gprs...); err != nil { + if err := issues_model.InsertPullRequests(ctx, gprs...); err != nil { return err } for _, pr := range gprs { g.issues[pr.Issue.Index] = pr.Issue - pull.AddToTaskQueue(g.ctx, pr) + pull.AddToTaskQueue(ctx, pr) } return nil } -func (g *GiteaLocalUploader) updateGitForPullRequest(pr *base.PullRequest) (head string, err error) { +func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *base.PullRequest) (head string, err error) { // SECURITY: this pr must have been must have been ensured safe if !pr.EnsuredSafe { log.Error("PR #%d in %s/%s has not been checked for safety.", pr.Number, g.repoOwner, g.repoName) @@ -664,7 +662,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(pr *base.PullRequest) (head fetchArg = git.BranchPrefix + fetchArg } - _, _, err = git.NewCommand(g.ctx, "fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) + _, _, err = git.NewCommand(ctx, "fetch", "--no-tags").AddDashesAndList(remote, fetchArg).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) if err != nil { log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) return head, nil @@ -683,7 +681,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(pr *base.PullRequest) (head pr.Head.SHA = headSha } - _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) + _, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) if err != nil { return "", err } @@ -700,13 +698,13 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(pr *base.PullRequest) (head // 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(g.ctx, "rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) + _, _, err = git.NewCommand(ctx, "rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA).RunStdString(&git.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.GetGitRefName()) } else { // set head information - _, _, err = git.NewCommand(g.ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) + _, _, err = git.NewCommand(ctx, "update-ref", "--no-deref").AddDynamicArguments(pr.GetGitRefName(), pr.Head.SHA).RunStdString(&git.RunOpts{Dir: g.repo.RepoPath()}) 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) } @@ -716,7 +714,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(pr *base.PullRequest) (head return head, nil } -func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model.PullRequest, error) { +func (g *GiteaLocalUploader) newPullRequest(ctx context.Context, pr *base.PullRequest) (*issues_model.PullRequest, error) { var labels []*issues_model.Label for _, label := range pr.Labels { lb, ok := g.labels[label.Name] @@ -727,7 +725,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model milestoneID := g.milestones[pr.Milestone] - head, err := g.updateGitForPullRequest(pr) + head, err := g.updateGitForPullRequest(ctx, pr) if err != nil { return nil, fmt.Errorf("updateGitForPullRequest: %w", err) } @@ -779,7 +777,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model UpdatedUnix: timeutil.TimeStamp(pr.Updated.Unix()), } - if err := g.remapUser(pr, &issue); err != nil { + if err := g.remapUser(ctx, pr, &issue); err != nil { return nil, err } @@ -789,7 +787,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model Type: reaction.Content, CreatedUnix: timeutil.TimeStampNow(), } - if err := g.remapUser(reaction, &res); err != nil { + if err := g.remapUser(ctx, reaction, &res); err != nil { return nil, err } issue.Reactions = append(issue.Reactions, &res) @@ -839,7 +837,7 @@ func convertReviewState(state string) issues_model.ReviewType { } // CreateReviews create pull request reviews of currently migrated issues -func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { +func (g *GiteaLocalUploader) CreateReviews(ctx context.Context, reviews ...*base.Review) error { cms := make([]*issues_model.Review, 0, len(reviews)) for _, review := range reviews { var issue *issues_model.Issue @@ -860,7 +858,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { UpdatedUnix: timeutil.TimeStamp(review.CreatedAt.Unix()), } - if err := g.remapUser(review, &cm); err != nil { + if err := g.remapUser(ctx, review, &cm); err != nil { return err } @@ -870,7 +868,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { pr, ok := g.prCache[issue.ID] if !ok { var err error - pr, err = issues_model.GetPullRequestByIssueIDWithNoAttributes(g.ctx, issue.ID) + pr, err = issues_model.GetPullRequestByIssueIDWithNoAttributes(ctx, issue.ID) if err != nil { return err } @@ -940,7 +938,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { UpdatedUnix: timeutil.TimeStamp(comment.UpdatedAt.Unix()), } - if err := g.remapUser(review, &c); err != nil { + if err := g.remapUser(ctx, review, &c); err != nil { return err } @@ -948,7 +946,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { } } - return issues_model.InsertReviews(g.ctx, cms) + return issues_model.InsertReviews(ctx, cms) } // Rollback when migrating failed, this will rollback all the changes. @@ -962,31 +960,31 @@ func (g *GiteaLocalUploader) Rollback() error { } // Finish when migrating success, this will do some status update things. -func (g *GiteaLocalUploader) Finish() error { +func (g *GiteaLocalUploader) Finish(ctx context.Context) error { if g.repo == nil || g.repo.ID <= 0 { return ErrRepoNotCreated } // update issue_index - if err := issues_model.RecalculateIssueIndexForRepo(g.ctx, g.repo.ID); err != nil { + if err := issues_model.RecalculateIssueIndexForRepo(ctx, g.repo.ID); err != nil { return err } - if err := models.UpdateRepoStats(g.ctx, g.repo.ID); err != nil { + if err := models.UpdateRepoStats(ctx, g.repo.ID); err != nil { return err } g.repo.Status = repo_model.RepositoryReady - return repo_model.UpdateRepositoryCols(g.ctx, g.repo, "status") + return repo_model.UpdateRepositoryCols(ctx, g.repo, "status") } -func (g *GiteaLocalUploader) remapUser(source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) error { +func (g *GiteaLocalUploader) remapUser(ctx context.Context, source user_model.ExternalUserMigrated, target user_model.ExternalUserRemappable) error { var userID int64 var err error if g.sameApp { - userID, err = g.remapLocalUser(source) + userID, err = g.remapLocalUser(ctx, source) } else { - userID, err = g.remapExternalUser(source) + userID, err = g.remapExternalUser(ctx, source) } if err != nil { return err @@ -998,10 +996,10 @@ func (g *GiteaLocalUploader) remapUser(source user_model.ExternalUserMigrated, t return target.RemapExternalUser(source.GetExternalName(), source.GetExternalID(), g.doer.ID) } -func (g *GiteaLocalUploader) remapLocalUser(source user_model.ExternalUserMigrated) (int64, error) { +func (g *GiteaLocalUploader) remapLocalUser(ctx context.Context, source user_model.ExternalUserMigrated) (int64, error) { userid, ok := g.userMap[source.GetExternalID()] if !ok { - name, err := user_model.GetUserNameByID(g.ctx, source.GetExternalID()) + name, err := user_model.GetUserNameByID(ctx, source.GetExternalID()) if err != nil { return 0, err } @@ -1016,10 +1014,10 @@ func (g *GiteaLocalUploader) remapLocalUser(source user_model.ExternalUserMigrat return userid, nil } -func (g *GiteaLocalUploader) remapExternalUser(source user_model.ExternalUserMigrated) (userid int64, err error) { +func (g *GiteaLocalUploader) remapExternalUser(ctx context.Context, source user_model.ExternalUserMigrated) (userid int64, err error) { userid, ok := g.userMap[source.GetExternalID()] if !ok { - userid, err = user_model.GetUserIDByExternalUserID(g.ctx, g.gitServiceType.Name(), fmt.Sprintf("%d", source.GetExternalID())) + userid, err = user_model.GetUserIDByExternalUserID(ctx, g.gitServiceType.Name(), fmt.Sprintf("%d", source.GetExternalID())) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) return 0, err diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index f2379dadf8..18d1171597 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -132,8 +132,9 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + ctx := context.Background() repoName := "migrated" - uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName) + uploader := NewGiteaLocalUploader(ctx, doer, doer.Name, repoName) // call remapLocalUser uploader.sameApp = true @@ -150,7 +151,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { // target := repo_model.Release{} uploader.userMap = make(map[int64]int64) - err := uploader.remapUser(&source, &target) + err := uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) assert.EqualValues(t, doer.ID, target.GetUserID()) @@ -161,7 +162,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { source.PublisherID = user.ID target = repo_model.Release{} uploader.userMap = make(map[int64]int64) - err = uploader.remapUser(&source, &target) + err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) assert.EqualValues(t, doer.ID, target.GetUserID()) @@ -172,7 +173,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { source.PublisherName = user.Name target = repo_model.Release{} uploader.userMap = make(map[int64]int64) - err = uploader.remapUser(&source, &target) + err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) assert.EqualValues(t, user.ID, target.GetUserID()) } @@ -180,9 +181,9 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { func TestGiteaUploadRemapExternalUser(t *testing.T) { unittest.PrepareTestEnv(t) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - + ctx := context.Background() repoName := "migrated" - uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName) + uploader := NewGiteaLocalUploader(ctx, doer, doer.Name, repoName) uploader.gitServiceType = structs.GiteaService // call remapExternalUser uploader.sameApp = false @@ -200,7 +201,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { // uploader.userMap = make(map[int64]int64) target := repo_model.Release{} - err := uploader.remapUser(&source, &target) + err := uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) assert.EqualValues(t, doer.ID, target.GetUserID()) @@ -223,7 +224,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { // uploader.userMap = make(map[int64]int64) target = repo_model.Release{} - err = uploader.remapUser(&source, &target) + err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) assert.EqualValues(t, linkedUser.ID, target.GetUserID()) } @@ -301,11 +302,12 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { assert.NoError(t, err) toRepoName := "migrated" - uploader := NewGiteaLocalUploader(context.Background(), fromRepoOwner, fromRepoOwner.Name, toRepoName) + ctx := context.Background() + uploader := NewGiteaLocalUploader(ctx, fromRepoOwner, fromRepoOwner.Name, toRepoName) uploader.gitServiceType = structs.GiteaService assert.NoError(t, repo_service.Init(context.Background())) - assert.NoError(t, uploader.CreateRepo(&base.Repository{ + assert.NoError(t, uploader.CreateRepo(ctx, &base.Repository{ Description: "description", OriginalURL: fromRepo.RepoPath(), CloneURL: fromRepo.RepoPath(), @@ -505,7 +507,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { testCase.pr.EnsuredSafe = true - head, err := uploader.updateGitForPullRequest(&testCase.pr) + head, err := uploader.updateGitForPullRequest(ctx, &testCase.pr) assert.NoError(t, err) assert.EqualValues(t, testCase.head, head) diff --git a/services/migrations/github.go b/services/migrations/github.go index 604ab84b39..b00d6ed27f 100644 --- a/services/migrations/github.go +++ b/services/migrations/github.go @@ -64,7 +64,6 @@ func (f *GithubDownloaderV3Factory) GitServiceType() structs.GitServiceType { // from github via APIv3 type GithubDownloaderV3 struct { base.NullDownloader - ctx context.Context clients []*github.Client baseURL string repoOwner string @@ -79,12 +78,11 @@ type GithubDownloaderV3 struct { } // NewGithubDownloaderV3 creates a github Downloader via github v3 API -func NewGithubDownloaderV3(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GithubDownloaderV3 { +func NewGithubDownloaderV3(_ context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GithubDownloaderV3 { downloader := GithubDownloaderV3{ userName: userName, baseURL: baseURL, password: password, - ctx: ctx, repoOwner: repoOwner, repoName: repoName, maxPerPage: 100, @@ -141,12 +139,7 @@ func (g *GithubDownloaderV3) addClient(client *http.Client, baseURL string) { g.rates = append(g.rates, nil) } -// SetContext set context -func (g *GithubDownloaderV3) SetContext(ctx context.Context) { - g.ctx = ctx -} - -func (g *GithubDownloaderV3) waitAndPickClient() { +func (g *GithubDownloaderV3) waitAndPickClient(ctx context.Context) { var recentIdx int var maxRemaining int for i := 0; i < len(g.clients); i++ { @@ -160,13 +153,13 @@ func (g *GithubDownloaderV3) waitAndPickClient() { for g.rates[g.curClientIdx] != nil && g.rates[g.curClientIdx].Remaining <= GithubLimitRateRemaining { timer := time.NewTimer(time.Until(g.rates[g.curClientIdx].Reset.Time)) select { - case <-g.ctx.Done(): + case <-ctx.Done(): timer.Stop() return case <-timer.C: } - err := g.RefreshRate() + err := g.RefreshRate(ctx) if err != nil { log.Error("g.getClient().RateLimit.Get: %s", err) } @@ -174,8 +167,8 @@ func (g *GithubDownloaderV3) waitAndPickClient() { } // RefreshRate update the current rate (doesn't count in rate limit) -func (g *GithubDownloaderV3) RefreshRate() error { - rates, _, err := g.getClient().RateLimit.Get(g.ctx) +func (g *GithubDownloaderV3) RefreshRate(ctx context.Context) error { + rates, _, err := g.getClient().RateLimit.Get(ctx) if err != nil { // if rate limit is not enabled, ignore it if strings.Contains(err.Error(), "404") { @@ -198,9 +191,9 @@ func (g *GithubDownloaderV3) setRate(rate *github.Rate) { } // GetRepoInfo returns a repository information -func (g *GithubDownloaderV3) GetRepoInfo() (*base.Repository, error) { - g.waitAndPickClient() - gr, resp, err := g.getClient().Repositories.Get(g.ctx, g.repoOwner, g.repoName) +func (g *GithubDownloaderV3) GetRepoInfo(ctx context.Context) (*base.Repository, error) { + g.waitAndPickClient(ctx) + gr, resp, err := g.getClient().Repositories.Get(ctx, g.repoOwner, g.repoName) if err != nil { return nil, err } @@ -219,9 +212,9 @@ func (g *GithubDownloaderV3) GetRepoInfo() (*base.Repository, error) { } // GetTopics return github topics -func (g *GithubDownloaderV3) GetTopics() ([]string, error) { - g.waitAndPickClient() - r, resp, err := g.getClient().Repositories.Get(g.ctx, g.repoOwner, g.repoName) +func (g *GithubDownloaderV3) GetTopics(ctx context.Context) ([]string, error) { + g.waitAndPickClient(ctx) + r, resp, err := g.getClient().Repositories.Get(ctx, g.repoOwner, g.repoName) if err != nil { return nil, err } @@ -230,12 +223,12 @@ func (g *GithubDownloaderV3) GetTopics() ([]string, error) { } // GetMilestones returns milestones -func (g *GithubDownloaderV3) GetMilestones() ([]*base.Milestone, error) { +func (g *GithubDownloaderV3) GetMilestones(ctx context.Context) ([]*base.Milestone, error) { perPage := g.maxPerPage milestones := make([]*base.Milestone, 0, perPage) for i := 1; ; i++ { - g.waitAndPickClient() - ms, resp, err := g.getClient().Issues.ListMilestones(g.ctx, g.repoOwner, g.repoName, + g.waitAndPickClient(ctx) + ms, resp, err := g.getClient().Issues.ListMilestones(ctx, g.repoOwner, g.repoName, &github.MilestoneListOptions{ State: "all", ListOptions: github.ListOptions{ @@ -279,12 +272,12 @@ func convertGithubLabel(label *github.Label) *base.Label { } // GetLabels returns labels -func (g *GithubDownloaderV3) GetLabels() ([]*base.Label, error) { +func (g *GithubDownloaderV3) GetLabels(ctx context.Context) ([]*base.Label, error) { perPage := g.maxPerPage labels := make([]*base.Label, 0, perPage) for i := 1; ; i++ { - g.waitAndPickClient() - ls, resp, err := g.getClient().Issues.ListLabels(g.ctx, g.repoOwner, g.repoName, + g.waitAndPickClient(ctx) + ls, resp, err := g.getClient().Issues.ListLabels(ctx, g.repoOwner, g.repoName, &github.ListOptions{ Page: i, PerPage: perPage, @@ -304,7 +297,7 @@ func (g *GithubDownloaderV3) GetLabels() ([]*base.Label, error) { return labels, nil } -func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease) *base.Release { +func (g *GithubDownloaderV3) convertGithubRelease(ctx context.Context, rel *github.RepositoryRelease) *base.Release { // GitHub allows commitish to be a reference. // In this case, we need to remove the prefix, i.e. convert "refs/heads/main" to "main". targetCommitish := strings.TrimPrefix(rel.GetTargetCommitish(), git.BranchPrefix) @@ -339,12 +332,12 @@ func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease) Created: asset.CreatedAt.Time, Updated: asset.UpdatedAt.Time, DownloadFunc: func() (io.ReadCloser, error) { - g.waitAndPickClient() - readCloser, redirectURL, err := g.getClient().Repositories.DownloadReleaseAsset(g.ctx, g.repoOwner, g.repoName, assetID, nil) + g.waitAndPickClient(ctx) + readCloser, redirectURL, err := g.getClient().Repositories.DownloadReleaseAsset(ctx, g.repoOwner, g.repoName, assetID, nil) if err != nil { return nil, err } - if err := g.RefreshRate(); err != nil { + if err := g.RefreshRate(ctx); err != nil { log.Error("g.getClient().RateLimits: %s", err) } @@ -364,13 +357,13 @@ func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease) return io.NopCloser(strings.NewReader(redirectURL)), nil } - g.waitAndPickClient() - req, err := http.NewRequestWithContext(g.ctx, "GET", redirectURL, nil) + g.waitAndPickClient(ctx) + req, err := http.NewRequestWithContext(ctx, "GET", redirectURL, nil) if err != nil { return nil, err } resp, err := httpClient.Do(req) - err1 := g.RefreshRate() + err1 := g.RefreshRate(ctx) if err1 != nil { log.Error("g.RefreshRate(): %s", err1) } @@ -385,12 +378,12 @@ func (g *GithubDownloaderV3) convertGithubRelease(rel *github.RepositoryRelease) } // GetReleases returns releases -func (g *GithubDownloaderV3) GetReleases() ([]*base.Release, error) { +func (g *GithubDownloaderV3) GetReleases(ctx context.Context) ([]*base.Release, error) { perPage := g.maxPerPage releases := make([]*base.Release, 0, perPage) for i := 1; ; i++ { - g.waitAndPickClient() - ls, resp, err := g.getClient().Repositories.ListReleases(g.ctx, g.repoOwner, g.repoName, + g.waitAndPickClient(ctx) + ls, resp, err := g.getClient().Repositories.ListReleases(ctx, g.repoOwner, g.repoName, &github.ListOptions{ Page: i, PerPage: perPage, @@ -401,7 +394,7 @@ func (g *GithubDownloaderV3) GetReleases() ([]*base.Release, error) { g.setRate(&resp.Rate) for _, release := range ls { - releases = append(releases, g.convertGithubRelease(release)) + releases = append(releases, g.convertGithubRelease(ctx, release)) } if len(ls) < perPage { break @@ -411,7 +404,7 @@ func (g *GithubDownloaderV3) GetReleases() ([]*base.Release, error) { } // GetIssues returns issues according start and limit -func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool, error) { +func (g *GithubDownloaderV3) GetIssues(ctx context.Context, page, perPage int) ([]*base.Issue, bool, error) { if perPage > g.maxPerPage { perPage = g.maxPerPage } @@ -426,8 +419,8 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool, } allIssues := make([]*base.Issue, 0, perPage) - g.waitAndPickClient() - issues, resp, err := g.getClient().Issues.ListByRepo(g.ctx, g.repoOwner, g.repoName, opt) + g.waitAndPickClient(ctx) + issues, resp, err := g.getClient().Issues.ListByRepo(ctx, g.repoOwner, g.repoName, opt) if err != nil { return nil, false, fmt.Errorf("error while listing repos: %w", err) } @@ -447,8 +440,8 @@ func (g *GithubDownloaderV3) GetIssues(page, perPage int) ([]*base.Issue, bool, var reactions []*base.Reaction if !g.SkipReactions { for i := 1; ; i++ { - g.waitAndPickClient() - res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, issue.GetNumber(), &github.ListOptions{ + g.waitAndPickClient(ctx) + res, resp, err := g.getClient().Reactions.ListIssueReactions(ctx, g.repoOwner, g.repoName, issue.GetNumber(), &github.ListOptions{ Page: i, PerPage: perPage, }) @@ -503,12 +496,12 @@ func (g *GithubDownloaderV3) SupportGetRepoComments() bool { } // GetComments returns comments according issueNumber -func (g *GithubDownloaderV3) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) { - comments, err := g.getComments(commentable) +func (g *GithubDownloaderV3) GetComments(ctx context.Context, commentable base.Commentable) ([]*base.Comment, bool, error) { + comments, err := g.getComments(ctx, commentable) return comments, false, err } -func (g *GithubDownloaderV3) getComments(commentable base.Commentable) ([]*base.Comment, error) { +func (g *GithubDownloaderV3) getComments(ctx context.Context, commentable base.Commentable) ([]*base.Comment, error) { var ( allComments = make([]*base.Comment, 0, g.maxPerPage) created = "created" @@ -522,8 +515,8 @@ func (g *GithubDownloaderV3) getComments(commentable base.Commentable) ([]*base. }, } for { - g.waitAndPickClient() - comments, resp, err := g.getClient().Issues.ListComments(g.ctx, g.repoOwner, g.repoName, int(commentable.GetForeignIndex()), opt) + g.waitAndPickClient(ctx) + comments, resp, err := g.getClient().Issues.ListComments(ctx, g.repoOwner, g.repoName, int(commentable.GetForeignIndex()), opt) if err != nil { return nil, fmt.Errorf("error while listing repos: %w", err) } @@ -533,8 +526,8 @@ func (g *GithubDownloaderV3) getComments(commentable base.Commentable) ([]*base. var reactions []*base.Reaction if !g.SkipReactions { for i := 1; ; i++ { - g.waitAndPickClient() - res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ + g.waitAndPickClient(ctx) + res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ Page: i, PerPage: g.maxPerPage, }) @@ -576,7 +569,7 @@ func (g *GithubDownloaderV3) getComments(commentable base.Commentable) ([]*base. } // GetAllComments returns repository comments according page and perPageSize -func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment, bool, error) { +func (g *GithubDownloaderV3) GetAllComments(ctx context.Context, page, perPage int) ([]*base.Comment, bool, error) { var ( allComments = make([]*base.Comment, 0, perPage) created = "created" @@ -594,8 +587,8 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment, }, } - g.waitAndPickClient() - comments, resp, err := g.getClient().Issues.ListComments(g.ctx, g.repoOwner, g.repoName, 0, opt) + g.waitAndPickClient(ctx) + comments, resp, err := g.getClient().Issues.ListComments(ctx, g.repoOwner, g.repoName, 0, opt) if err != nil { return nil, false, fmt.Errorf("error while listing repos: %w", err) } @@ -608,8 +601,8 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment, var reactions []*base.Reaction if !g.SkipReactions { for i := 1; ; i++ { - g.waitAndPickClient() - res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(g.ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ + g.waitAndPickClient(ctx) + res, resp, err := g.getClient().Reactions.ListIssueCommentReactions(ctx, g.repoOwner, g.repoName, comment.GetID(), &github.ListOptions{ Page: i, PerPage: g.maxPerPage, }) @@ -648,7 +641,7 @@ func (g *GithubDownloaderV3) GetAllComments(page, perPage int) ([]*base.Comment, } // GetPullRequests returns pull requests according page and perPage -func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) { +func (g *GithubDownloaderV3) GetPullRequests(ctx context.Context, page, perPage int) ([]*base.PullRequest, bool, error) { if perPage > g.maxPerPage { perPage = g.maxPerPage } @@ -662,8 +655,8 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq }, } allPRs := make([]*base.PullRequest, 0, perPage) - g.waitAndPickClient() - prs, resp, err := g.getClient().PullRequests.List(g.ctx, g.repoOwner, g.repoName, opt) + g.waitAndPickClient(ctx) + prs, resp, err := g.getClient().PullRequests.List(ctx, g.repoOwner, g.repoName, opt) if err != nil { return nil, false, fmt.Errorf("error while listing repos: %w", err) } @@ -679,8 +672,8 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq var reactions []*base.Reaction if !g.SkipReactions { for i := 1; ; i++ { - g.waitAndPickClient() - res, resp, err := g.getClient().Reactions.ListIssueReactions(g.ctx, g.repoOwner, g.repoName, pr.GetNumber(), &github.ListOptions{ + g.waitAndPickClient(ctx) + res, resp, err := g.getClient().Reactions.ListIssueReactions(ctx, g.repoOwner, g.repoName, pr.GetNumber(), &github.ListOptions{ Page: i, PerPage: perPage, }) @@ -702,7 +695,7 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq } // download patch and saved as tmp file - g.waitAndPickClient() + g.waitAndPickClient(ctx) allPRs = append(allPRs, &base.PullRequest{ Title: pr.GetTitle(), @@ -759,15 +752,15 @@ func convertGithubReview(r *github.PullRequestReview) *base.Review { } } -func (g *GithubDownloaderV3) convertGithubReviewComments(cs []*github.PullRequestComment) ([]*base.ReviewComment, error) { +func (g *GithubDownloaderV3) convertGithubReviewComments(ctx context.Context, cs []*github.PullRequestComment) ([]*base.ReviewComment, error) { rcs := make([]*base.ReviewComment, 0, len(cs)) for _, c := range cs { // get reactions var reactions []*base.Reaction if !g.SkipReactions { for i := 1; ; i++ { - g.waitAndPickClient() - res, resp, err := g.getClient().Reactions.ListPullRequestCommentReactions(g.ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListOptions{ + g.waitAndPickClient(ctx) + res, resp, err := g.getClient().Reactions.ListPullRequestCommentReactions(ctx, g.repoOwner, g.repoName, c.GetID(), &github.ListOptions{ Page: i, PerPage: g.maxPerPage, }) @@ -806,7 +799,7 @@ func (g *GithubDownloaderV3) convertGithubReviewComments(cs []*github.PullReques } // GetReviews returns pull requests review -func (g *GithubDownloaderV3) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) { +func (g *GithubDownloaderV3) GetReviews(ctx context.Context, reviewable base.Reviewable) ([]*base.Review, error) { allReviews := make([]*base.Review, 0, g.maxPerPage) if g.SkipReviews { return allReviews, nil @@ -816,8 +809,8 @@ func (g *GithubDownloaderV3) GetReviews(reviewable base.Reviewable) ([]*base.Rev } // Get approve/request change reviews for { - g.waitAndPickClient() - reviews, resp, err := g.getClient().PullRequests.ListReviews(g.ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), opt) + g.waitAndPickClient(ctx) + reviews, resp, err := g.getClient().PullRequests.ListReviews(ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), opt) if err != nil { return nil, fmt.Errorf("error while listing repos: %w", err) } @@ -830,14 +823,14 @@ func (g *GithubDownloaderV3) GetReviews(reviewable base.Reviewable) ([]*base.Rev PerPage: g.maxPerPage, } for { - g.waitAndPickClient() - reviewComments, resp, err := g.getClient().PullRequests.ListReviewComments(g.ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), review.GetID(), opt2) + g.waitAndPickClient(ctx) + reviewComments, resp, err := g.getClient().PullRequests.ListReviewComments(ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), review.GetID(), opt2) if err != nil { return nil, fmt.Errorf("error while listing repos: %w", err) } g.setRate(&resp.Rate) - cs, err := g.convertGithubReviewComments(reviewComments) + cs, err := g.convertGithubReviewComments(ctx, reviewComments) if err != nil { return nil, err } @@ -856,8 +849,8 @@ func (g *GithubDownloaderV3) GetReviews(reviewable base.Reviewable) ([]*base.Rev } // Get requested reviews for { - g.waitAndPickClient() - reviewers, resp, err := g.getClient().PullRequests.ListReviewers(g.ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), opt) + g.waitAndPickClient(ctx) + reviewers, resp, err := g.getClient().PullRequests.ListReviewers(ctx, g.repoOwner, g.repoName, int(reviewable.GetForeignIndex()), opt) if err != nil { return nil, fmt.Errorf("error while listing repos: %w", err) } diff --git a/services/migrations/github_test.go b/services/migrations/github_test.go index 2b89e6dc0f..899f9fe52c 100644 --- a/services/migrations/github_test.go +++ b/services/migrations/github_test.go @@ -21,11 +21,12 @@ func TestGitHubDownloadRepo(t *testing.T) { if token == "" { t.Skip("Skipping GitHub migration test because GITHUB_READ_TOKEN is empty") } - downloader := NewGithubDownloaderV3(context.Background(), "https://github.com", "", "", token, "go-gitea", "test_repo") - err := downloader.RefreshRate() + ctx := context.Background() + downloader := NewGithubDownloaderV3(ctx, "https://github.com", "", "", token, "go-gitea", "test_repo") + err := downloader.RefreshRate(ctx) assert.NoError(t, err) - repo, err := downloader.GetRepoInfo() + repo, err := downloader.GetRepoInfo(ctx) assert.NoError(t, err) assertRepositoryEqual(t, &base.Repository{ Name: "test_repo", @@ -36,11 +37,11 @@ func TestGitHubDownloadRepo(t *testing.T) { DefaultBranch: "master", }, repo) - topics, err := downloader.GetTopics() + topics, err := downloader.GetTopics(ctx) assert.NoError(t, err) assert.Contains(t, topics, "gitea") - milestones, err := downloader.GetMilestones() + milestones, err := downloader.GetMilestones(ctx) assert.NoError(t, err) assertMilestonesEqual(t, []*base.Milestone{ { @@ -63,7 +64,7 @@ func TestGitHubDownloadRepo(t *testing.T) { }, }, milestones) - labels, err := downloader.GetLabels() + labels, err := downloader.GetLabels(ctx) assert.NoError(t, err) assertLabelsEqual(t, []*base.Label{ { @@ -113,7 +114,7 @@ func TestGitHubDownloadRepo(t *testing.T) { }, }, labels) - releases, err := downloader.GetReleases() + releases, err := downloader.GetReleases(ctx) assert.NoError(t, err) assertReleasesEqual(t, []*base.Release{ { @@ -129,7 +130,7 @@ func TestGitHubDownloadRepo(t *testing.T) { }, releases) // downloader.GetIssues() - issues, isEnd, err := downloader.GetIssues(1, 2) + issues, isEnd, err := downloader.GetIssues(ctx, 1, 2) assert.NoError(t, err) assert.False(t, isEnd) assertIssuesEqual(t, []*base.Issue{ @@ -218,7 +219,7 @@ func TestGitHubDownloadRepo(t *testing.T) { }, issues) // downloader.GetComments() - comments, _, err := downloader.GetComments(&base.Issue{Number: 2, ForeignIndex: 2}) + comments, _, err := downloader.GetComments(ctx, &base.Issue{Number: 2, ForeignIndex: 2}) assert.NoError(t, err) assertCommentsEqual(t, []*base.Comment{ { @@ -248,7 +249,7 @@ func TestGitHubDownloadRepo(t *testing.T) { }, comments) // downloader.GetPullRequests() - prs, _, err := downloader.GetPullRequests(1, 2) + prs, _, err := downloader.GetPullRequests(ctx, 1, 2) assert.NoError(t, err) assertPullRequestsEqual(t, []*base.PullRequest{ { @@ -338,7 +339,7 @@ func TestGitHubDownloadRepo(t *testing.T) { }, }, prs) - reviews, err := downloader.GetReviews(&base.PullRequest{Number: 3, ForeignIndex: 3}) + reviews, err := downloader.GetReviews(ctx, &base.PullRequest{Number: 3, ForeignIndex: 3}) assert.NoError(t, err) assertReviewsEqual(t, []*base.Review{ { @@ -370,7 +371,7 @@ func TestGitHubDownloadRepo(t *testing.T) { }, }, reviews) - reviews, err = downloader.GetReviews(&base.PullRequest{Number: 4, ForeignIndex: 4}) + reviews, err = downloader.GetReviews(ctx, &base.PullRequest{Number: 4, ForeignIndex: 4}) assert.NoError(t, err) assertReviewsEqual(t, []*base.Review{ { diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index 07d5040b5b..efc5b960cf 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -80,7 +80,6 @@ func (r *gitlabIIDResolver) generatePullRequestNumber(mrIID int) int64 { // because Gitlab has individual Issue and Pull Request numbers. type GitlabDownloader struct { base.NullDownloader - ctx context.Context client *gitlab.Client baseURL string repoID int @@ -143,7 +142,6 @@ func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, passw } return &GitlabDownloader{ - ctx: ctx, client: gitlabClient, baseURL: baseURL, repoID: gr.ID, @@ -164,14 +162,9 @@ func (g *GitlabDownloader) LogString() string { return fmt.Sprintf("", g.baseURL, g.repoID, g.repoName) } -// SetContext set context -func (g *GitlabDownloader) SetContext(ctx context.Context) { - g.ctx = ctx -} - // GetRepoInfo returns a repository information -func (g *GitlabDownloader) GetRepoInfo() (*base.Repository, error) { - gr, _, err := g.client.Projects.GetProject(g.repoID, nil, nil, gitlab.WithContext(g.ctx)) +func (g *GitlabDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, error) { + gr, _, err := g.client.Projects.GetProject(g.repoID, nil, nil, gitlab.WithContext(ctx)) if err != nil { return nil, err } @@ -207,8 +200,8 @@ func (g *GitlabDownloader) GetRepoInfo() (*base.Repository, error) { } // GetTopics return gitlab topics -func (g *GitlabDownloader) GetTopics() ([]string, error) { - gr, _, err := g.client.Projects.GetProject(g.repoID, nil, nil, gitlab.WithContext(g.ctx)) +func (g *GitlabDownloader) GetTopics(ctx context.Context) ([]string, error) { + gr, _, err := g.client.Projects.GetProject(g.repoID, nil, nil, gitlab.WithContext(ctx)) if err != nil { return nil, err } @@ -216,7 +209,7 @@ func (g *GitlabDownloader) GetTopics() ([]string, error) { } // GetMilestones returns milestones -func (g *GitlabDownloader) GetMilestones() ([]*base.Milestone, error) { +func (g *GitlabDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone, error) { perPage := g.maxPerPage state := "all" milestones := make([]*base.Milestone, 0, perPage) @@ -227,7 +220,7 @@ func (g *GitlabDownloader) GetMilestones() ([]*base.Milestone, error) { Page: i, PerPage: perPage, }, - }, nil, gitlab.WithContext(g.ctx)) + }, nil, gitlab.WithContext(ctx)) if err != nil { return nil, err } @@ -288,14 +281,14 @@ func (g *GitlabDownloader) normalizeColor(val string) string { } // GetLabels returns labels -func (g *GitlabDownloader) GetLabels() ([]*base.Label, error) { +func (g *GitlabDownloader) GetLabels(ctx context.Context) ([]*base.Label, error) { perPage := g.maxPerPage labels := make([]*base.Label, 0, perPage) for i := 1; ; i++ { ls, _, err := g.client.Labels.ListLabels(g.repoID, &gitlab.ListLabelsOptions{ListOptions: gitlab.ListOptions{ Page: i, PerPage: perPage, - }}, nil, gitlab.WithContext(g.ctx)) + }}, nil, gitlab.WithContext(ctx)) if err != nil { return nil, err } @@ -314,7 +307,7 @@ func (g *GitlabDownloader) GetLabels() ([]*base.Label, error) { return labels, nil } -func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Release { +func (g *GitlabDownloader) convertGitlabRelease(ctx context.Context, rel *gitlab.Release) *base.Release { var zero int r := &base.Release{ TagName: rel.TagName, @@ -337,7 +330,7 @@ func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Relea Size: &zero, DownloadCount: &zero, DownloadFunc: func() (io.ReadCloser, error) { - link, _, err := g.client.ReleaseLinks.GetReleaseLink(g.repoID, rel.TagName, assetID, gitlab.WithContext(g.ctx)) + link, _, err := g.client.ReleaseLinks.GetReleaseLink(g.repoID, rel.TagName, assetID, gitlab.WithContext(ctx)) if err != nil { return nil, err } @@ -351,7 +344,7 @@ func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Relea if err != nil { return nil, err } - req = req.WithContext(g.ctx) + req = req.WithContext(ctx) resp, err := httpClient.Do(req) if err != nil { return nil, err @@ -366,7 +359,7 @@ func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Relea } // GetReleases returns releases -func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) { +func (g *GitlabDownloader) GetReleases(ctx context.Context) ([]*base.Release, error) { perPage := g.maxPerPage releases := make([]*base.Release, 0, perPage) for i := 1; ; i++ { @@ -375,13 +368,13 @@ func (g *GitlabDownloader) GetReleases() ([]*base.Release, error) { Page: i, PerPage: perPage, }, - }, nil, gitlab.WithContext(g.ctx)) + }, nil, gitlab.WithContext(ctx)) if err != nil { return nil, err } for _, release := range ls { - releases = append(releases, g.convertGitlabRelease(release)) + releases = append(releases, g.convertGitlabRelease(ctx, release)) } if len(ls) < perPage { break @@ -397,7 +390,7 @@ type gitlabIssueContext struct { // GetIssues returns issues according start and limit // // Note: issue label description and colors are not supported by the go-gitlab library at this time -func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) { +func (g *GitlabDownloader) GetIssues(ctx context.Context, page, perPage int) ([]*base.Issue, bool, error) { state := "all" sort := "asc" @@ -416,7 +409,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er allIssues := make([]*base.Issue, 0, perPage) - issues, _, err := g.client.Issues.ListProjectIssues(g.repoID, opt, nil, gitlab.WithContext(g.ctx)) + issues, _, err := g.client.Issues.ListProjectIssues(g.repoID, opt, nil, gitlab.WithContext(ctx)) if err != nil { return nil, false, fmt.Errorf("error while listing issues: %w", err) } @@ -436,7 +429,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er var reactions []*gitlab.AwardEmoji awardPage := 1 for { - awards, _, err := g.client.AwardEmoji.ListIssueAwardEmoji(g.repoID, issue.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx)) + awards, _, err := g.client.AwardEmoji.ListIssueAwardEmoji(g.repoID, issue.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(ctx)) if err != nil { return nil, false, fmt.Errorf("error while listing issue awards: %w", err) } @@ -477,7 +470,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er // GetComments returns comments according issueNumber // TODO: figure out how to transfer comment reactions -func (g *GitlabDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) { +func (g *GitlabDownloader) GetComments(ctx context.Context, commentable base.Commentable) ([]*base.Comment, bool, error) { context, ok := commentable.GetContext().(gitlabIssueContext) if !ok { return nil, false, fmt.Errorf("unexpected context: %+v", commentable.GetContext()) @@ -495,12 +488,12 @@ func (g *GitlabDownloader) GetComments(commentable base.Commentable) ([]*base.Co comments, resp, err = g.client.Discussions.ListIssueDiscussions(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListIssueDiscussionsOptions{ Page: page, PerPage: g.maxPerPage, - }, nil, gitlab.WithContext(g.ctx)) + }, nil, gitlab.WithContext(ctx)) } else { comments, resp, err = g.client.Discussions.ListMergeRequestDiscussions(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListMergeRequestDiscussionsOptions{ Page: page, PerPage: g.maxPerPage, - }, nil, gitlab.WithContext(g.ctx)) + }, nil, gitlab.WithContext(ctx)) } if err != nil { @@ -528,14 +521,14 @@ func (g *GitlabDownloader) GetComments(commentable base.Commentable) ([]*base.Co Page: page, PerPage: g.maxPerPage, }, - }, nil, gitlab.WithContext(g.ctx)) + }, nil, gitlab.WithContext(ctx)) } else { stateEvents, resp, err = g.client.ResourceStateEvents.ListIssueStateEvents(g.repoID, int(commentable.GetForeignIndex()), &gitlab.ListStateEventsOptions{ ListOptions: gitlab.ListOptions{ Page: page, PerPage: g.maxPerPage, }, - }, nil, gitlab.WithContext(g.ctx)) + }, nil, gitlab.WithContext(ctx)) } if err != nil { return nil, false, fmt.Errorf("error while listing state events: %v %w", g.repoID, err) @@ -604,7 +597,7 @@ func (g *GitlabDownloader) convertNoteToComment(localIndex int64, note *gitlab.N } // GetPullRequests returns pull requests according page and perPage -func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) { +func (g *GitlabDownloader) GetPullRequests(ctx context.Context, page, perPage int) ([]*base.PullRequest, bool, error) { if perPage > g.maxPerPage { perPage = g.maxPerPage } @@ -620,7 +613,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque allPRs := make([]*base.PullRequest, 0, perPage) - prs, _, err := g.client.MergeRequests.ListProjectMergeRequests(g.repoID, opt, nil, gitlab.WithContext(g.ctx)) + prs, _, err := g.client.MergeRequests.ListProjectMergeRequests(g.repoID, opt, nil, gitlab.WithContext(ctx)) if err != nil { return nil, false, fmt.Errorf("error while listing merge requests: %w", err) } @@ -673,7 +666,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque var reactions []*gitlab.AwardEmoji awardPage := 1 for { - awards, _, err := g.client.AwardEmoji.ListMergeRequestAwardEmoji(g.repoID, pr.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx)) + awards, _, err := g.client.AwardEmoji.ListMergeRequestAwardEmoji(g.repoID, pr.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(ctx)) if err != nil { return nil, false, fmt.Errorf("error while listing merge requests awards: %w", err) } @@ -733,8 +726,8 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque } // GetReviews returns pull requests review -func (g *GitlabDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) { - approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, int(reviewable.GetForeignIndex()), gitlab.WithContext(g.ctx)) +func (g *GitlabDownloader) GetReviews(ctx context.Context, reviewable base.Reviewable) ([]*base.Review, error) { + approvals, resp, err := g.client.MergeRequestApprovals.GetConfiguration(g.repoID, int(reviewable.GetForeignIndex()), gitlab.WithContext(ctx)) if err != nil { if resp != nil && resp.StatusCode == http.StatusNotFound { log.Error(fmt.Sprintf("GitlabDownloader: while migrating a error occurred: '%s'", err.Error())) diff --git a/services/migrations/gitlab_test.go b/services/migrations/gitlab_test.go index 556fe771c5..223a3b86d7 100644 --- a/services/migrations/gitlab_test.go +++ b/services/migrations/gitlab_test.go @@ -31,12 +31,12 @@ func TestGitlabDownloadRepo(t *testing.T) { if err != nil || resp.StatusCode != http.StatusOK { t.Skipf("Can't access test repo, skipping %s", t.Name()) } - - downloader, err := NewGitlabDownloader(context.Background(), "https://gitlab.com", "gitea/test_repo", "", "", gitlabPersonalAccessToken) + ctx := context.Background() + downloader, err := NewGitlabDownloader(ctx, "https://gitlab.com", "gitea/test_repo", "", "", gitlabPersonalAccessToken) if err != nil { t.Fatalf("NewGitlabDownloader is nil: %v", err) } - repo, err := downloader.GetRepoInfo() + repo, err := downloader.GetRepoInfo(ctx) assert.NoError(t, err) // Repo Owner is blank in Gitlab Group repos assertRepositoryEqual(t, &base.Repository{ @@ -48,12 +48,12 @@ func TestGitlabDownloadRepo(t *testing.T) { DefaultBranch: "master", }, repo) - topics, err := downloader.GetTopics() + topics, err := downloader.GetTopics(ctx) assert.NoError(t, err) assert.Len(t, topics, 2) assert.EqualValues(t, []string{"migration", "test"}, topics) - milestones, err := downloader.GetMilestones() + milestones, err := downloader.GetMilestones(ctx) assert.NoError(t, err) assertMilestonesEqual(t, []*base.Milestone{ { @@ -71,7 +71,7 @@ func TestGitlabDownloadRepo(t *testing.T) { }, }, milestones) - labels, err := downloader.GetLabels() + labels, err := downloader.GetLabels(ctx) assert.NoError(t, err) assertLabelsEqual(t, []*base.Label{ { @@ -112,7 +112,7 @@ func TestGitlabDownloadRepo(t *testing.T) { }, }, labels) - releases, err := downloader.GetReleases() + releases, err := downloader.GetReleases(ctx) assert.NoError(t, err) assertReleasesEqual(t, []*base.Release{ { @@ -126,7 +126,7 @@ func TestGitlabDownloadRepo(t *testing.T) { }, }, releases) - issues, isEnd, err := downloader.GetIssues(1, 2) + issues, isEnd, err := downloader.GetIssues(ctx, 1, 2) assert.NoError(t, err) assert.False(t, isEnd) @@ -214,7 +214,7 @@ func TestGitlabDownloadRepo(t *testing.T) { }, }, issues) - comments, _, err := downloader.GetComments(&base.Issue{ + comments, _, err := downloader.GetComments(ctx, &base.Issue{ Number: 2, ForeignIndex: 2, Context: gitlabIssueContext{IsMergeRequest: false}, @@ -255,7 +255,7 @@ func TestGitlabDownloadRepo(t *testing.T) { }, }, comments) - prs, _, err := downloader.GetPullRequests(1, 1) + prs, _, err := downloader.GetPullRequests(ctx, 1, 1) assert.NoError(t, err) assertPullRequestsEqual(t, []*base.PullRequest{ { @@ -304,7 +304,7 @@ func TestGitlabDownloadRepo(t *testing.T) { }, }, prs) - rvs, err := downloader.GetReviews(&base.PullRequest{Number: 1, ForeignIndex: 1}) + rvs, err := downloader.GetReviews(ctx, &base.PullRequest{Number: 1, ForeignIndex: 1}) assert.NoError(t, err) assertReviewsEqual(t, []*base.Review{ { @@ -323,7 +323,7 @@ func TestGitlabDownloadRepo(t *testing.T) { }, }, rvs) - rvs, err = downloader.GetReviews(&base.PullRequest{Number: 2, ForeignIndex: 2}) + rvs, err = downloader.GetReviews(ctx, &base.PullRequest{Number: 2, ForeignIndex: 2}) assert.NoError(t, err) assertReviewsEqual(t, []*base.Review{ { @@ -423,9 +423,8 @@ func TestGitlabGetReviews(t *testing.T) { defer gitlabClientMockTeardown(server) repoID := 1324 - + ctx := context.Background() downloader := &GitlabDownloader{ - ctx: context.Background(), client: client, repoID: repoID, } @@ -465,7 +464,7 @@ func TestGitlabGetReviews(t *testing.T) { mux.HandleFunc(fmt.Sprintf("/api/v4/projects/%d/merge_requests/%d/approvals", testCase.repoID, testCase.prID), mock) id := int64(testCase.prID) - rvs, err := downloader.GetReviews(&base.Issue{Number: id, ForeignIndex: id}) + rvs, err := downloader.GetReviews(ctx, &base.Issue{Number: id, ForeignIndex: id}) assert.NoError(t, err) assertReviewsEqual(t, []*base.Review{&review}, rvs) } diff --git a/services/migrations/gogs.go b/services/migrations/gogs.go index 72c52d180b..a4f84dbf72 100644 --- a/services/migrations/gogs.go +++ b/services/migrations/gogs.go @@ -13,7 +13,6 @@ import ( "code.gitea.io/gitea/modules/log" base "code.gitea.io/gitea/modules/migration" - "code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/structs" "github.com/gogs/go-gogs-client" @@ -60,16 +59,14 @@ func (f *GogsDownloaderFactory) GitServiceType() structs.GitServiceType { // from gogs via API type GogsDownloader struct { base.NullDownloader - ctx context.Context - client *gogs.Client baseURL string repoOwner string repoName string userName string password string + token string openIssuesFinished bool openIssuesPages int - transport http.RoundTripper } // String implements Stringer @@ -84,53 +81,45 @@ func (g *GogsDownloader) LogString() string { return fmt.Sprintf("", g.baseURL, g.repoOwner, g.repoName) } -// SetContext set context -func (g *GogsDownloader) SetContext(ctx context.Context) { - g.ctx = ctx -} - // NewGogsDownloader creates a gogs Downloader via gogs API -func NewGogsDownloader(ctx context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GogsDownloader { +func NewGogsDownloader(_ context.Context, baseURL, userName, password, token, repoOwner, repoName string) *GogsDownloader { downloader := GogsDownloader{ - ctx: ctx, baseURL: baseURL, userName: userName, password: password, + token: token, repoOwner: repoOwner, repoName: repoName, } - - var client *gogs.Client - if len(token) != 0 { - client = gogs.NewClient(baseURL, token) - downloader.userName = token - } else { - transport := NewMigrationHTTPTransport() - transport.Proxy = func(req *http.Request) (*url.URL, error) { - req.SetBasicAuth(userName, password) - return proxy.Proxy()(req) - } - downloader.transport = transport - - client = gogs.NewClient(baseURL, "") - client.SetHTTPClient(&http.Client{ - Transport: &downloader, - }) - } - - downloader.client = client return &downloader } -// RoundTrip wraps the provided request within this downloader's context and passes it to our internal http.Transport. -// This implements http.RoundTripper and makes the gogs client requests cancellable even though it is not cancellable itself -func (g *GogsDownloader) RoundTrip(req *http.Request) (*http.Response, error) { - return g.transport.RoundTrip(req.WithContext(g.ctx)) +type roundTripperFunc func(req *http.Request) (*http.Response, error) + +func (rt roundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { + return rt(r) +} + +func (g *GogsDownloader) client(ctx context.Context) *gogs.Client { + // Gogs client lacks the context support, so we use a custom transport + // Then each request uses a dedicated client with its own context + httpTransport := NewMigrationHTTPTransport() + gogsClient := gogs.NewClient(g.baseURL, g.token) + gogsClient.SetHTTPClient(&http.Client{ + Transport: roundTripperFunc(func(req *http.Request) (*http.Response, error) { + if g.password != "" { + // Gogs client lacks the support for basic auth, this is the only way to set it + req.SetBasicAuth(g.userName, g.password) + } + return httpTransport.RoundTrip(req.WithContext(ctx)) + }), + }) + return gogsClient } // GetRepoInfo returns a repository information -func (g *GogsDownloader) GetRepoInfo() (*base.Repository, error) { - gr, err := g.client.GetRepo(g.repoOwner, g.repoName) +func (g *GogsDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, error) { + gr, err := g.client(ctx).GetRepo(g.repoOwner, g.repoName) if err != nil { return nil, err } @@ -148,11 +137,11 @@ func (g *GogsDownloader) GetRepoInfo() (*base.Repository, error) { } // GetMilestones returns milestones -func (g *GogsDownloader) GetMilestones() ([]*base.Milestone, error) { +func (g *GogsDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone, error) { perPage := 100 milestones := make([]*base.Milestone, 0, perPage) - ms, err := g.client.ListRepoMilestones(g.repoOwner, g.repoName) + ms, err := g.client(ctx).ListRepoMilestones(g.repoOwner, g.repoName) if err != nil { return nil, err } @@ -171,10 +160,10 @@ func (g *GogsDownloader) GetMilestones() ([]*base.Milestone, error) { } // GetLabels returns labels -func (g *GogsDownloader) GetLabels() ([]*base.Label, error) { +func (g *GogsDownloader) GetLabels(ctx context.Context) ([]*base.Label, error) { perPage := 100 labels := make([]*base.Label, 0, perPage) - ls, err := g.client.ListRepoLabels(g.repoOwner, g.repoName) + ls, err := g.client(ctx).ListRepoLabels(g.repoOwner, g.repoName) if err != nil { return nil, err } @@ -187,7 +176,7 @@ func (g *GogsDownloader) GetLabels() ([]*base.Label, error) { } // GetIssues returns issues according start and limit, perPage is not supported -func (g *GogsDownloader) GetIssues(page, _ int) ([]*base.Issue, bool, error) { +func (g *GogsDownloader) GetIssues(ctx context.Context, page, _ int) ([]*base.Issue, bool, error) { var state string if g.openIssuesFinished { state = string(gogs.STATE_CLOSED) @@ -197,7 +186,7 @@ func (g *GogsDownloader) GetIssues(page, _ int) ([]*base.Issue, bool, error) { g.openIssuesPages = page } - issues, isEnd, err := g.getIssues(page, state) + issues, isEnd, err := g.getIssues(ctx, page, state) if err != nil { return nil, false, err } @@ -212,10 +201,10 @@ func (g *GogsDownloader) GetIssues(page, _ int) ([]*base.Issue, bool, error) { return issues, false, nil } -func (g *GogsDownloader) getIssues(page int, state string) ([]*base.Issue, bool, error) { +func (g *GogsDownloader) getIssues(ctx context.Context, page int, state string) ([]*base.Issue, bool, error) { allIssues := make([]*base.Issue, 0, 10) - issues, err := g.client.ListRepoIssues(g.repoOwner, g.repoName, gogs.ListIssueOption{ + issues, err := g.client(ctx).ListRepoIssues(g.repoOwner, g.repoName, gogs.ListIssueOption{ Page: page, State: state, }) @@ -234,10 +223,10 @@ func (g *GogsDownloader) getIssues(page int, state string) ([]*base.Issue, bool, } // GetComments returns comments according issueNumber -func (g *GogsDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) { +func (g *GogsDownloader) GetComments(ctx context.Context, commentable base.Commentable) ([]*base.Comment, bool, error) { allComments := make([]*base.Comment, 0, 100) - comments, err := g.client.ListIssueComments(g.repoOwner, g.repoName, commentable.GetForeignIndex()) + comments, err := g.client(ctx).ListIssueComments(g.repoOwner, g.repoName, commentable.GetForeignIndex()) if err != nil { return nil, false, fmt.Errorf("error while listing repos: %w", err) } @@ -261,7 +250,7 @@ func (g *GogsDownloader) GetComments(commentable base.Commentable) ([]*base.Comm } // GetTopics return repository topics -func (g *GogsDownloader) GetTopics() ([]string, error) { +func (g *GogsDownloader) GetTopics(_ context.Context) ([]string, error) { return []string{}, nil } diff --git a/services/migrations/gogs_test.go b/services/migrations/gogs_test.go index 610af183de..91c36bdcc6 100644 --- a/services/migrations/gogs_test.go +++ b/services/migrations/gogs_test.go @@ -28,9 +28,9 @@ func TestGogsDownloadRepo(t *testing.T) { t.Skipf("visit test repo failed, ignored") return } - - downloader := NewGogsDownloader(context.Background(), "https://try.gogs.io", "", "", gogsPersonalAccessToken, "lunnytest", "TESTREPO") - repo, err := downloader.GetRepoInfo() + ctx := context.Background() + downloader := NewGogsDownloader(ctx, "https://try.gogs.io", "", "", gogsPersonalAccessToken, "lunnytest", "TESTREPO") + repo, err := downloader.GetRepoInfo(ctx) assert.NoError(t, err) assertRepositoryEqual(t, &base.Repository{ @@ -42,7 +42,7 @@ func TestGogsDownloadRepo(t *testing.T) { DefaultBranch: "master", }, repo) - milestones, err := downloader.GetMilestones() + milestones, err := downloader.GetMilestones(ctx) assert.NoError(t, err) assertMilestonesEqual(t, []*base.Milestone{ { @@ -51,7 +51,7 @@ func TestGogsDownloadRepo(t *testing.T) { }, }, milestones) - labels, err := downloader.GetLabels() + labels, err := downloader.GetLabels(ctx) assert.NoError(t, err) assertLabelsEqual(t, []*base.Label{ { @@ -85,7 +85,7 @@ func TestGogsDownloadRepo(t *testing.T) { }, labels) // downloader.GetIssues() - issues, isEnd, err := downloader.GetIssues(1, 8) + issues, isEnd, err := downloader.GetIssues(ctx, 1, 8) assert.NoError(t, err) assert.False(t, isEnd) assertIssuesEqual(t, []*base.Issue{ @@ -110,7 +110,7 @@ func TestGogsDownloadRepo(t *testing.T) { }, issues) // downloader.GetComments() - comments, _, err := downloader.GetComments(&base.Issue{Number: 1, ForeignIndex: 1}) + comments, _, err := downloader.GetComments(ctx, &base.Issue{Number: 1, ForeignIndex: 1}) assert.NoError(t, err) assertCommentsEqual(t, []*base.Comment{ { @@ -134,6 +134,6 @@ func TestGogsDownloadRepo(t *testing.T) { }, comments) // downloader.GetPullRequests() - _, _, err = downloader.GetPullRequests(1, 3) + _, _, err = downloader.GetPullRequests(ctx, 1, 3) assert.Error(t, err) } diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go index 51b22d6111..8319fd541b 100644 --- a/services/migrations/migrate.go +++ b/services/migrations/migrate.go @@ -176,12 +176,12 @@ func newDownloader(ctx context.Context, ownerName string, opts base.MigrateOptio // migrateRepository will download information and then upload it to Uploader, this is a simple // process for small repository. For a big repository, save all the data to disk // before upload is better -func migrateRepository(_ context.Context, doer *user_model.User, downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions, messenger base.Messenger) error { +func migrateRepository(ctx context.Context, doer *user_model.User, downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions, messenger base.Messenger) error { if messenger == nil { messenger = base.NilMessenger } - repo, err := downloader.GetRepoInfo() + repo, err := downloader.GetRepoInfo(ctx) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -220,14 +220,14 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base log.Trace("migrating git data from %s", repo.CloneURL) messenger("repo.migrate.migrating_git") - if err = uploader.CreateRepo(repo, opts); err != nil { + if err = uploader.CreateRepo(ctx, repo, opts); err != nil { return err } defer uploader.Close() log.Trace("migrating topics") messenger("repo.migrate.migrating_topics") - topics, err := downloader.GetTopics() + topics, err := downloader.GetTopics(ctx) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -235,7 +235,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base log.Warn("migrating topics is not supported, ignored") } if len(topics) != 0 { - if err = uploader.CreateTopics(topics...); err != nil { + if err = uploader.CreateTopics(ctx, topics...); err != nil { return err } } @@ -243,7 +243,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base if opts.Milestones { log.Trace("migrating milestones") messenger("repo.migrate.migrating_milestones") - milestones, err := downloader.GetMilestones() + milestones, err := downloader.GetMilestones(ctx) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -256,7 +256,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base msBatchSize = len(milestones) } - if err := uploader.CreateMilestones(milestones[:msBatchSize]...); err != nil { + if err := uploader.CreateMilestones(ctx, milestones[:msBatchSize]...); err != nil { return err } milestones = milestones[msBatchSize:] @@ -266,7 +266,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base if opts.Labels { log.Trace("migrating labels") messenger("repo.migrate.migrating_labels") - labels, err := downloader.GetLabels() + labels, err := downloader.GetLabels(ctx) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -280,7 +280,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base lbBatchSize = len(labels) } - if err := uploader.CreateLabels(labels[:lbBatchSize]...); err != nil { + if err := uploader.CreateLabels(ctx, labels[:lbBatchSize]...); err != nil { return err } labels = labels[lbBatchSize:] @@ -290,7 +290,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base if opts.Releases { log.Trace("migrating releases") messenger("repo.migrate.migrating_releases") - releases, err := downloader.GetReleases() + releases, err := downloader.GetReleases(ctx) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -304,14 +304,14 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base relBatchSize = len(releases) } - if err = uploader.CreateReleases(releases[:relBatchSize]...); err != nil { + if err = uploader.CreateReleases(ctx, releases[:relBatchSize]...); err != nil { return err } releases = releases[relBatchSize:] } // Once all releases (if any) are inserted, sync any remaining non-release tags - if err = uploader.SyncTags(); err != nil { + if err = uploader.SyncTags(ctx); err != nil { return err } } @@ -329,7 +329,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base issueBatchSize := uploader.MaxBatchInsertSize("issue") for i := 1; ; i++ { - issues, isEnd, err := downloader.GetIssues(i, issueBatchSize) + issues, isEnd, err := downloader.GetIssues(ctx, i, issueBatchSize) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -338,7 +338,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base break } - if err := uploader.CreateIssues(issues...); err != nil { + if err := uploader.CreateIssues(ctx, issues...); err != nil { return err } @@ -346,7 +346,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base allComments := make([]*base.Comment, 0, commentBatchSize) for _, issue := range issues { log.Trace("migrating issue %d's comments", issue.Number) - comments, _, err := downloader.GetComments(issue) + comments, _, err := downloader.GetComments(ctx, issue) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -357,7 +357,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base allComments = append(allComments, comments...) if len(allComments) >= commentBatchSize { - if err = uploader.CreateComments(allComments[:commentBatchSize]...); err != nil { + if err = uploader.CreateComments(ctx, allComments[:commentBatchSize]...); err != nil { return err } @@ -366,7 +366,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base } if len(allComments) > 0 { - if err = uploader.CreateComments(allComments...); err != nil { + if err = uploader.CreateComments(ctx, allComments...); err != nil { return err } } @@ -383,7 +383,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base messenger("repo.migrate.migrating_pulls") prBatchSize := uploader.MaxBatchInsertSize("pullrequest") for i := 1; ; i++ { - prs, isEnd, err := downloader.GetPullRequests(i, prBatchSize) + prs, isEnd, err := downloader.GetPullRequests(ctx, i, prBatchSize) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -392,7 +392,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base break } - if err := uploader.CreatePullRequests(prs...); err != nil { + if err := uploader.CreatePullRequests(ctx, prs...); err != nil { return err } @@ -402,7 +402,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base allComments := make([]*base.Comment, 0, commentBatchSize) for _, pr := range prs { log.Trace("migrating pull request %d's comments", pr.Number) - comments, _, err := downloader.GetComments(pr) + comments, _, err := downloader.GetComments(ctx, pr) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -413,14 +413,14 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base allComments = append(allComments, comments...) if len(allComments) >= commentBatchSize { - if err = uploader.CreateComments(allComments[:commentBatchSize]...); err != nil { + if err = uploader.CreateComments(ctx, allComments[:commentBatchSize]...); err != nil { return err } allComments = allComments[commentBatchSize:] } } if len(allComments) > 0 { - if err = uploader.CreateComments(allComments...); err != nil { + if err = uploader.CreateComments(ctx, allComments...); err != nil { return err } } @@ -429,7 +429,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base // migrate reviews allReviews := make([]*base.Review, 0, reviewBatchSize) for _, pr := range prs { - reviews, err := downloader.GetReviews(pr) + reviews, err := downloader.GetReviews(ctx, pr) if err != nil { if !base.IsErrNotSupported(err) { return err @@ -441,14 +441,14 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base allReviews = append(allReviews, reviews...) if len(allReviews) >= reviewBatchSize { - if err = uploader.CreateReviews(allReviews[:reviewBatchSize]...); err != nil { + if err = uploader.CreateReviews(ctx, allReviews[:reviewBatchSize]...); err != nil { return err } allReviews = allReviews[reviewBatchSize:] } } if len(allReviews) > 0 { - if err = uploader.CreateReviews(allReviews...); err != nil { + if err = uploader.CreateReviews(ctx, allReviews...); err != nil { return err } } @@ -463,12 +463,12 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base if opts.Comments && supportAllComments { log.Trace("migrating comments") for i := 1; ; i++ { - comments, isEnd, err := downloader.GetAllComments(i, commentBatchSize) + comments, isEnd, err := downloader.GetAllComments(ctx, i, commentBatchSize) if err != nil { return err } - if err := uploader.CreateComments(comments...); err != nil { + if err := uploader.CreateComments(ctx, comments...); err != nil { return err } @@ -478,7 +478,7 @@ func migrateRepository(_ context.Context, doer *user_model.User, downloader base } } - return uploader.Finish() + return uploader.Finish(ctx) } // Init migrations service diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go index e2f7b771f3..4ce35dd12e 100644 --- a/services/migrations/onedev.go +++ b/services/migrations/onedev.go @@ -71,7 +71,6 @@ type onedevUser struct { // from OneDev type OneDevDownloader struct { base.NullDownloader - ctx context.Context client *http.Client baseURL *url.URL repoName string @@ -81,15 +80,9 @@ type OneDevDownloader struct { milestoneMap map[int64]string } -// SetContext set context -func (d *OneDevDownloader) SetContext(ctx context.Context) { - d.ctx = ctx -} - // NewOneDevDownloader creates a new downloader -func NewOneDevDownloader(ctx context.Context, baseURL *url.URL, username, password, repoName string) *OneDevDownloader { +func NewOneDevDownloader(_ context.Context, baseURL *url.URL, username, password, repoName string) *OneDevDownloader { downloader := &OneDevDownloader{ - ctx: ctx, baseURL: baseURL, repoName: repoName, client: &http.Client{ @@ -121,7 +114,7 @@ func (d *OneDevDownloader) LogString() string { return fmt.Sprintf("", d.baseURL, d.repoID, d.repoName) } -func (d *OneDevDownloader) callAPI(endpoint string, parameter map[string]string, result any) error { +func (d *OneDevDownloader) callAPI(ctx context.Context, endpoint string, parameter map[string]string, result any) error { u, err := d.baseURL.Parse(endpoint) if err != nil { return err @@ -135,7 +128,7 @@ func (d *OneDevDownloader) callAPI(endpoint string, parameter map[string]string, u.RawQuery = query.Encode() } - req, err := http.NewRequestWithContext(d.ctx, "GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { return err } @@ -151,7 +144,7 @@ func (d *OneDevDownloader) callAPI(endpoint string, parameter map[string]string, } // GetRepoInfo returns repository information -func (d *OneDevDownloader) GetRepoInfo() (*base.Repository, error) { +func (d *OneDevDownloader) GetRepoInfo(ctx context.Context) (*base.Repository, error) { info := make([]struct { ID int64 `json:"id"` Name string `json:"name"` @@ -159,6 +152,7 @@ func (d *OneDevDownloader) GetRepoInfo() (*base.Repository, error) { }, 0, 1) err := d.callAPI( + ctx, "/api/projects", map[string]string{ "query": `"Name" is "` + d.repoName + `"`, @@ -194,7 +188,7 @@ func (d *OneDevDownloader) GetRepoInfo() (*base.Repository, error) { } // GetMilestones returns milestones -func (d *OneDevDownloader) GetMilestones() ([]*base.Milestone, error) { +func (d *OneDevDownloader) GetMilestones(ctx context.Context) ([]*base.Milestone, error) { rawMilestones := make([]struct { ID int64 `json:"id"` Name string `json:"name"` @@ -209,6 +203,7 @@ func (d *OneDevDownloader) GetMilestones() ([]*base.Milestone, error) { offset := 0 for { err := d.callAPI( + ctx, endpoint, map[string]string{ "offset": strconv.Itoa(offset), @@ -243,7 +238,7 @@ func (d *OneDevDownloader) GetMilestones() ([]*base.Milestone, error) { } // GetLabels returns labels -func (d *OneDevDownloader) GetLabels() ([]*base.Label, error) { +func (d *OneDevDownloader) GetLabels(_ context.Context) ([]*base.Label, error) { return []*base.Label{ { Name: "Bug", @@ -277,7 +272,7 @@ type onedevIssueContext struct { } // GetIssues returns issues -func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) { +func (d *OneDevDownloader) GetIssues(ctx context.Context, page, perPage int) ([]*base.Issue, bool, error) { rawIssues := make([]struct { ID int64 `json:"id"` Number int64 `json:"number"` @@ -289,6 +284,7 @@ func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er }, 0, perPage) err := d.callAPI( + ctx, "/api/issues", map[string]string{ "query": `"Project" is "` + d.repoName + `"`, @@ -308,6 +304,7 @@ func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er Value string `json:"value"` }, 0, 10) err := d.callAPI( + ctx, fmt.Sprintf("/api/issues/%d/fields", issue.ID), nil, &fields, @@ -329,6 +326,7 @@ func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er Name string `json:"name"` }, 0, 10) err = d.callAPI( + ctx, fmt.Sprintf("/api/issues/%d/milestones", issue.ID), nil, &milestones, @@ -345,7 +343,7 @@ func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er if state == "released" { state = "closed" } - poster := d.tryGetUser(issue.SubmitterID) + poster := d.tryGetUser(ctx, issue.SubmitterID) issues = append(issues, &base.Issue{ Title: issue.Title, Number: issue.Number, @@ -370,7 +368,7 @@ func (d *OneDevDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er } // GetComments returns comments -func (d *OneDevDownloader) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) { +func (d *OneDevDownloader) GetComments(ctx context.Context, commentable base.Commentable) ([]*base.Comment, bool, error) { context, ok := commentable.GetContext().(onedevIssueContext) if !ok { return nil, false, fmt.Errorf("unexpected context: %+v", commentable.GetContext()) @@ -391,6 +389,7 @@ func (d *OneDevDownloader) GetComments(commentable base.Commentable) ([]*base.Co } err := d.callAPI( + ctx, endpoint, nil, &rawComments, @@ -412,6 +411,7 @@ func (d *OneDevDownloader) GetComments(commentable base.Commentable) ([]*base.Co } err = d.callAPI( + ctx, endpoint, nil, &rawChanges, @@ -425,7 +425,7 @@ func (d *OneDevDownloader) GetComments(commentable base.Commentable) ([]*base.Co if len(comment.Content) == 0 { continue } - poster := d.tryGetUser(comment.UserID) + poster := d.tryGetUser(ctx, comment.UserID) comments = append(comments, &base.Comment{ IssueIndex: commentable.GetLocalIndex(), Index: comment.ID, @@ -450,7 +450,7 @@ func (d *OneDevDownloader) GetComments(commentable base.Commentable) ([]*base.Co continue } - poster := d.tryGetUser(change.UserID) + poster := d.tryGetUser(ctx, change.UserID) comments = append(comments, &base.Comment{ IssueIndex: commentable.GetLocalIndex(), PosterID: poster.ID, @@ -466,7 +466,7 @@ func (d *OneDevDownloader) GetComments(commentable base.Commentable) ([]*base.Co } // GetPullRequests returns pull requests -func (d *OneDevDownloader) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) { +func (d *OneDevDownloader) GetPullRequests(ctx context.Context, page, perPage int) ([]*base.PullRequest, bool, error) { rawPullRequests := make([]struct { ID int64 `json:"id"` Number int64 `json:"number"` @@ -484,6 +484,7 @@ func (d *OneDevDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque }, 0, perPage) err := d.callAPI( + ctx, "/api/pull-requests", map[string]string{ "query": `"Target Project" is "` + d.repoName + `"`, @@ -505,6 +506,7 @@ func (d *OneDevDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque MergeCommitHash string `json:"mergeCommitHash"` } err := d.callAPI( + ctx, fmt.Sprintf("/api/pull-requests/%d/merge-preview", pr.ID), nil, &mergePreview, @@ -525,7 +527,7 @@ func (d *OneDevDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque mergedTime = pr.CloseInfo.Date } } - poster := d.tryGetUser(pr.SubmitterID) + poster := d.tryGetUser(ctx, pr.SubmitterID) number := pr.Number + d.maxIssueIndex pullRequests = append(pullRequests, &base.PullRequest{ @@ -562,7 +564,7 @@ func (d *OneDevDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque } // GetReviews returns pull requests reviews -func (d *OneDevDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) { +func (d *OneDevDownloader) GetReviews(ctx context.Context, reviewable base.Reviewable) ([]*base.Review, error) { rawReviews := make([]struct { ID int64 `json:"id"` UserID int64 `json:"userId"` @@ -574,6 +576,7 @@ func (d *OneDevDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Revie }, 0, 100) err := d.callAPI( + ctx, fmt.Sprintf("/api/pull-requests/%d/reviews", reviewable.GetForeignIndex()), nil, &rawReviews, @@ -596,7 +599,7 @@ func (d *OneDevDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Revie } } - poster := d.tryGetUser(review.UserID) + poster := d.tryGetUser(ctx, review.UserID) reviews = append(reviews, &base.Review{ IssueIndex: reviewable.GetLocalIndex(), ReviewerID: poster.ID, @@ -610,14 +613,15 @@ func (d *OneDevDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Revie } // GetTopics return repository topics -func (d *OneDevDownloader) GetTopics() ([]string, error) { +func (d *OneDevDownloader) GetTopics(_ context.Context) ([]string, error) { return []string{}, nil } -func (d *OneDevDownloader) tryGetUser(userID int64) *onedevUser { +func (d *OneDevDownloader) tryGetUser(ctx context.Context, userID int64) *onedevUser { user, ok := d.userMap[userID] if !ok { err := d.callAPI( + ctx, fmt.Sprintf("/api/users/%d", userID), nil, &user, diff --git a/services/migrations/onedev_test.go b/services/migrations/onedev_test.go index 48412fec64..0a4b05446d 100644 --- a/services/migrations/onedev_test.go +++ b/services/migrations/onedev_test.go @@ -22,11 +22,12 @@ func TestOneDevDownloadRepo(t *testing.T) { } u, _ := url.Parse("https://code.onedev.io") - downloader := NewOneDevDownloader(context.Background(), u, "", "", "go-gitea-test_repo") + ctx := context.Background() + downloader := NewOneDevDownloader(ctx, u, "", "", "go-gitea-test_repo") if err != nil { t.Fatalf("NewOneDevDownloader is nil: %v", err) } - repo, err := downloader.GetRepoInfo() + repo, err := downloader.GetRepoInfo(ctx) assert.NoError(t, err) assertRepositoryEqual(t, &base.Repository{ Name: "go-gitea-test_repo", @@ -36,7 +37,7 @@ func TestOneDevDownloadRepo(t *testing.T) { OriginalURL: "https://code.onedev.io/projects/go-gitea-test_repo", }, repo) - milestones, err := downloader.GetMilestones() + milestones, err := downloader.GetMilestones(ctx) assert.NoError(t, err) deadline := time.Unix(1620086400, 0) assertMilestonesEqual(t, []*base.Milestone{ @@ -51,11 +52,11 @@ func TestOneDevDownloadRepo(t *testing.T) { }, }, milestones) - labels, err := downloader.GetLabels() + labels, err := downloader.GetLabels(ctx) assert.NoError(t, err) assert.Len(t, labels, 6) - issues, isEnd, err := downloader.GetIssues(1, 2) + issues, isEnd, err := downloader.GetIssues(ctx, 1, 2) assert.NoError(t, err) assert.False(t, isEnd) assertIssuesEqual(t, []*base.Issue{ @@ -94,7 +95,7 @@ func TestOneDevDownloadRepo(t *testing.T) { }, }, issues) - comments, _, err := downloader.GetComments(&base.Issue{ + comments, _, err := downloader.GetComments(ctx, &base.Issue{ Number: 4, ForeignIndex: 398, Context: onedevIssueContext{IsPullRequest: false}, @@ -110,7 +111,7 @@ func TestOneDevDownloadRepo(t *testing.T) { }, }, comments) - prs, _, err := downloader.GetPullRequests(1, 1) + prs, _, err := downloader.GetPullRequests(ctx, 1, 1) assert.NoError(t, err) assertPullRequestsEqual(t, []*base.PullRequest{ { @@ -136,7 +137,7 @@ func TestOneDevDownloadRepo(t *testing.T) { }, }, prs) - rvs, err := downloader.GetReviews(&base.PullRequest{Number: 5, ForeignIndex: 186}) + rvs, err := downloader.GetReviews(ctx, &base.PullRequest{Number: 5, ForeignIndex: 186}) assert.NoError(t, err) assertReviewsEqual(t, []*base.Review{ { diff --git a/services/migrations/restore.go b/services/migrations/restore.go index fd337b22c7..5686285935 100644 --- a/services/migrations/restore.go +++ b/services/migrations/restore.go @@ -18,7 +18,6 @@ import ( // RepositoryRestorer implements an Downloader from the local directory type RepositoryRestorer struct { base.NullDownloader - ctx context.Context baseDir string repoOwner string repoName string @@ -26,13 +25,12 @@ type RepositoryRestorer struct { } // NewRepositoryRestorer creates a repository restorer which could restore repository from a dumped folder -func NewRepositoryRestorer(ctx context.Context, baseDir, owner, repoName string, validation bool) (*RepositoryRestorer, error) { +func NewRepositoryRestorer(_ context.Context, baseDir, owner, repoName string, validation bool) (*RepositoryRestorer, error) { baseDir, err := filepath.Abs(baseDir) if err != nil { return nil, err } return &RepositoryRestorer{ - ctx: ctx, baseDir: baseDir, repoOwner: owner, repoName: repoName, @@ -48,11 +46,6 @@ func (r *RepositoryRestorer) reviewDir() string { return filepath.Join(r.baseDir, "reviews") } -// SetContext set context -func (r *RepositoryRestorer) SetContext(ctx context.Context) { - r.ctx = ctx -} - func (r *RepositoryRestorer) getRepoOptions() (map[string]string, error) { p := filepath.Join(r.baseDir, "repo.yml") bs, err := os.ReadFile(p) @@ -69,7 +62,7 @@ func (r *RepositoryRestorer) getRepoOptions() (map[string]string, error) { } // GetRepoInfo returns a repository information -func (r *RepositoryRestorer) GetRepoInfo() (*base.Repository, error) { +func (r *RepositoryRestorer) GetRepoInfo(_ context.Context) (*base.Repository, error) { opts, err := r.getRepoOptions() if err != nil { return nil, err @@ -89,7 +82,7 @@ func (r *RepositoryRestorer) GetRepoInfo() (*base.Repository, error) { } // GetTopics return github topics -func (r *RepositoryRestorer) GetTopics() ([]string, error) { +func (r *RepositoryRestorer) GetTopics(_ context.Context) ([]string, error) { p := filepath.Join(r.baseDir, "topic.yml") topics := struct { @@ -112,7 +105,7 @@ func (r *RepositoryRestorer) GetTopics() ([]string, error) { } // GetMilestones returns milestones -func (r *RepositoryRestorer) GetMilestones() ([]*base.Milestone, error) { +func (r *RepositoryRestorer) GetMilestones(_ context.Context) ([]*base.Milestone, error) { milestones := make([]*base.Milestone, 0, 10) p := filepath.Join(r.baseDir, "milestone.yml") err := base.Load(p, &milestones, r.validation) @@ -127,7 +120,7 @@ func (r *RepositoryRestorer) GetMilestones() ([]*base.Milestone, error) { } // GetReleases returns releases -func (r *RepositoryRestorer) GetReleases() ([]*base.Release, error) { +func (r *RepositoryRestorer) GetReleases(_ context.Context) ([]*base.Release, error) { releases := make([]*base.Release, 0, 10) p := filepath.Join(r.baseDir, "release.yml") _, err := os.Stat(p) @@ -158,7 +151,7 @@ func (r *RepositoryRestorer) GetReleases() ([]*base.Release, error) { } // GetLabels returns labels -func (r *RepositoryRestorer) GetLabels() ([]*base.Label, error) { +func (r *RepositoryRestorer) GetLabels(_ context.Context) ([]*base.Label, error) { labels := make([]*base.Label, 0, 10) p := filepath.Join(r.baseDir, "label.yml") _, err := os.Stat(p) @@ -182,7 +175,7 @@ func (r *RepositoryRestorer) GetLabels() ([]*base.Label, error) { } // GetIssues returns issues according start and limit -func (r *RepositoryRestorer) GetIssues(page, perPage int) ([]*base.Issue, bool, error) { +func (r *RepositoryRestorer) GetIssues(_ context.Context, _, _ int) ([]*base.Issue, bool, error) { issues := make([]*base.Issue, 0, 10) p := filepath.Join(r.baseDir, "issue.yml") err := base.Load(p, &issues, r.validation) @@ -196,7 +189,7 @@ func (r *RepositoryRestorer) GetIssues(page, perPage int) ([]*base.Issue, bool, } // GetComments returns comments according issueNumber -func (r *RepositoryRestorer) GetComments(commentable base.Commentable) ([]*base.Comment, bool, error) { +func (r *RepositoryRestorer) GetComments(_ context.Context, commentable base.Commentable) ([]*base.Comment, bool, error) { comments := make([]*base.Comment, 0, 10) p := filepath.Join(r.commentDir(), fmt.Sprintf("%d.yml", commentable.GetForeignIndex())) _, err := os.Stat(p) @@ -220,7 +213,7 @@ func (r *RepositoryRestorer) GetComments(commentable base.Commentable) ([]*base. } // GetPullRequests returns pull requests according page and perPage -func (r *RepositoryRestorer) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) { +func (r *RepositoryRestorer) GetPullRequests(_ context.Context, page, perPage int) ([]*base.PullRequest, bool, error) { pulls := make([]*base.PullRequest, 0, 10) p := filepath.Join(r.baseDir, "pull_request.yml") _, err := os.Stat(p) @@ -248,7 +241,7 @@ func (r *RepositoryRestorer) GetPullRequests(page, perPage int) ([]*base.PullReq } // GetReviews returns pull requests review -func (r *RepositoryRestorer) GetReviews(reviewable base.Reviewable) ([]*base.Review, error) { +func (r *RepositoryRestorer) GetReviews(ctx context.Context, reviewable base.Reviewable) ([]*base.Review, error) { reviews := make([]*base.Review, 0, 10) p := filepath.Join(r.reviewDir(), fmt.Sprintf("%d.yml", reviewable.GetForeignIndex())) _, err := os.Stat(p) From 063c23e1bcf52fde5bda82d0c1dbe7dd04e2771f Mon Sep 17 00:00:00 2001 From: mscherer Date: Fri, 7 Feb 2025 09:41:55 +0100 Subject: [PATCH 069/655] Add a option "--user-type bot" to admin user create, improve role display (#27885) Partially solve #13044 Fix #33295 --------- Co-authored-by: wxiaoguang --- cmd/admin_user_create.go | 31 +++++++++- cmd/admin_user_create_test.go | 58 +++++++++++++------ models/user/user.go | 16 +++--- models/user/user_system.go | 2 +- routers/api/v1/api.go | 4 +- routers/web/repo/issue_view.go | 81 ++++++++++++--------------- templates/shared/user/authorlink.tmpl | 2 +- 7 files changed, 118 insertions(+), 76 deletions(-) diff --git a/cmd/admin_user_create.go b/cmd/admin_user_create.go index bf8cbc7c4c..5e03d6ca3f 100644 --- a/cmd/admin_user_create.go +++ b/cmd/admin_user_create.go @@ -31,6 +31,11 @@ var microcmdUserCreate = &cli.Command{ Name: "username", Usage: "Username", }, + &cli.StringFlag{ + Name: "user-type", + Usage: "Set user's type: individual or bot", + Value: "individual", + }, &cli.StringFlag{ Name: "password", Usage: "User password", @@ -77,6 +82,22 @@ func runCreateUser(c *cli.Context) error { return err } + userTypes := map[string]user_model.UserType{ + "individual": user_model.UserTypeIndividual, + "bot": user_model.UserTypeBot, + } + userType, ok := userTypes[c.String("user-type")] + if !ok { + return fmt.Errorf("invalid user type: %s", c.String("user-type")) + } + if userType != user_model.UserTypeIndividual { + // Some other commands like "change-password" also only support individual users. + // It needs to clarify the "password" behavior for bot users in the future. + // At the moment, we do not allow setting password for bot users. + if c.IsSet("password") || c.IsSet("random-password") { + return errors.New("password can only be set for individual users") + } + } if c.IsSet("name") && c.IsSet("username") { return errors.New("cannot set both --name and --username flags") } @@ -118,16 +139,19 @@ func runCreateUser(c *cli.Context) error { return err } fmt.Printf("generated random password is '%s'\n", password) - } else { + } else if userType == user_model.UserTypeIndividual { return errors.New("must set either password or random-password flag") } isAdmin := c.Bool("admin") mustChangePassword := true // always default to true if c.IsSet("must-change-password") { + if userType != user_model.UserTypeIndividual { + return errors.New("must-change-password flag can only be set for individual users") + } // if the flag is set, use the value provided by the user mustChangePassword = c.Bool("must-change-password") - } else { + } else if userType == user_model.UserTypeIndividual { // check whether there are users in the database hasUserRecord, err := db.IsTableNotEmpty(&user_model.User{}) if err != nil { @@ -151,8 +175,9 @@ func runCreateUser(c *cli.Context) error { u := &user_model.User{ Name: username, Email: c.String("email"), - Passwd: password, IsAdmin: isAdmin, + Type: userType, + Passwd: password, MustChangePassword: mustChangePassword, Visibility: visibility, } diff --git a/cmd/admin_user_create_test.go b/cmd/admin_user_create_test.go index 83754e97b1..d8044e8de7 100644 --- a/cmd/admin_user_create_test.go +++ b/cmd/admin_user_create_test.go @@ -13,32 +13,54 @@ import ( user_model "code.gitea.io/gitea/models/user" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAdminUserCreate(t *testing.T) { app := NewMainApp(AppVersion{}) reset := func() { - assert.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) - assert.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.EmailAddress{})) + require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) + require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.EmailAddress{})) } - type createCheck struct{ IsAdmin, MustChangePassword bool } - createUser := func(name, args string) createCheck { - assert.NoError(t, app.Run(strings.Fields(fmt.Sprintf("./gitea admin user create --username %s --email %s@gitea.local %s --password foobar", name, name, args)))) - u := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: name}) - return createCheck{u.IsAdmin, u.MustChangePassword} - } - reset() - assert.Equal(t, createCheck{IsAdmin: false, MustChangePassword: false}, createUser("u", ""), "first non-admin user doesn't need to change password") + t.Run("MustChangePassword", func(t *testing.T) { + type check struct { + IsAdmin bool + MustChangePassword bool + } + createCheck := func(name, args string) check { + require.NoError(t, app.Run(strings.Fields(fmt.Sprintf("./gitea admin user create --username %s --email %s@gitea.local %s --password foobar", name, name, args)))) + u := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: name}) + return check{IsAdmin: u.IsAdmin, MustChangePassword: u.MustChangePassword} + } + reset() + assert.Equal(t, check{IsAdmin: false, MustChangePassword: false}, createCheck("u", ""), "first non-admin user doesn't need to change password") - reset() - assert.Equal(t, createCheck{IsAdmin: true, MustChangePassword: false}, createUser("u", "--admin"), "first admin user doesn't need to change password") + reset() + assert.Equal(t, check{IsAdmin: true, MustChangePassword: false}, createCheck("u", "--admin"), "first admin user doesn't need to change password") - reset() - assert.Equal(t, createCheck{IsAdmin: true, MustChangePassword: true}, createUser("u", "--admin --must-change-password")) - assert.Equal(t, createCheck{IsAdmin: true, MustChangePassword: true}, createUser("u2", "--admin")) - assert.Equal(t, createCheck{IsAdmin: true, MustChangePassword: false}, createUser("u3", "--admin --must-change-password=false")) - assert.Equal(t, createCheck{IsAdmin: false, MustChangePassword: true}, createUser("u4", "")) - assert.Equal(t, createCheck{IsAdmin: false, MustChangePassword: false}, createUser("u5", "--must-change-password=false")) + reset() + assert.Equal(t, check{IsAdmin: true, MustChangePassword: true}, createCheck("u", "--admin --must-change-password")) + assert.Equal(t, check{IsAdmin: true, MustChangePassword: true}, createCheck("u2", "--admin")) + assert.Equal(t, check{IsAdmin: true, MustChangePassword: false}, createCheck("u3", "--admin --must-change-password=false")) + assert.Equal(t, check{IsAdmin: false, MustChangePassword: true}, createCheck("u4", "")) + assert.Equal(t, check{IsAdmin: false, MustChangePassword: false}, createCheck("u5", "--must-change-password=false")) + }) + + t.Run("UserType", func(t *testing.T) { + createUser := func(name, args string) error { + return app.Run(strings.Fields(fmt.Sprintf("./gitea admin user create --username %s --email %s@gitea.local %s", name, name, args))) + } + + reset() + assert.ErrorContains(t, createUser("u", "--user-type invalid"), "invalid user type") + assert.ErrorContains(t, createUser("u", "--user-type bot --password 123"), "can only be set for individual users") + assert.ErrorContains(t, createUser("u", "--user-type bot --must-change-password"), "can only be set for individual users") + + assert.NoError(t, createUser("u", "--user-type bot")) + u := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: "u"}) + assert.Equal(t, user_model.UserTypeBot, u.Type) + assert.Equal(t, "", u.Passwd) + }) } diff --git a/models/user/user.go b/models/user/user.go index e13fb6ab3c..293c876957 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -385,11 +385,12 @@ func (u *User) ValidatePassword(passwd string) bool { } // IsPasswordSet checks if the password is set or left empty +// TODO: It's better to clarify the "password" behavior for different types (individual, bot) func (u *User) IsPasswordSet() bool { - return len(u.Passwd) != 0 + return u.Passwd != "" } -// IsOrganization returns true if user is actually a organization. +// IsOrganization returns true if user is actually an organization. func (u *User) IsOrganization() bool { return u.Type == UserTypeOrganization } @@ -399,13 +400,14 @@ func (u *User) IsIndividual() bool { return u.Type == UserTypeIndividual } -func (u *User) IsUser() bool { - return u.Type == UserTypeIndividual || u.Type == UserTypeBot +// IsTypeBot returns whether the user is of type bot +func (u *User) IsTypeBot() bool { + return u.Type == UserTypeBot } -// IsBot returns whether or not the user is of type bot -func (u *User) IsBot() bool { - return u.Type == UserTypeBot +// IsTokenAccessAllowed returns whether the user is an individual or a bot (which allows for token access) +func (u *User) IsTokenAccessAllowed() bool { + return u.Type == UserTypeIndividual || u.Type == UserTypeBot } // DisplayName returns full name if it's not empty, diff --git a/models/user/user_system.go b/models/user/user_system.go index e54973dc8e..6fbfd9e69e 100644 --- a/models/user/user_system.go +++ b/models/user/user_system.go @@ -56,7 +56,7 @@ func NewActionsUser() *User { Email: ActionsUserEmail, KeepEmailPrivate: true, LoginName: ActionsUserName, - Type: UserTypeIndividual, + Type: UserTypeBot, AllowCreateOrganization: true, Visibility: structs.VisibleTypePublic, } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 0aa38b8b6a..2ffd6b129b 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -268,12 +268,12 @@ func checkTokenPublicOnly() func(ctx *context.APIContext) { return } case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryUser): - if ctx.ContextUser != nil && ctx.ContextUser.IsUser() && ctx.ContextUser.Visibility != api.VisibleTypePublic { + if ctx.ContextUser != nil && ctx.ContextUser.IsTokenAccessAllowed() && ctx.ContextUser.Visibility != api.VisibleTypePublic { ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public users") return } case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryActivityPub): - if ctx.ContextUser != nil && ctx.ContextUser.IsUser() && ctx.ContextUser.Visibility != api.VisibleTypePublic { + if ctx.ContextUser != nil && ctx.ContextUser.IsTokenAccessAllowed() && ctx.ContextUser.Visibility != api.VisibleTypePublic { ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public activitypub") return } diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index aa49d2e1e8..aeb2fa52b6 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -4,7 +4,6 @@ package repo import ( - stdCtx "context" "fmt" "math/big" "net/http" @@ -40,86 +39,80 @@ import ( ) // roleDescriptor returns the role descriptor for a comment in/with the given repo, poster and issue -func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, permsCache map[int64]access_model.Permission, issue *issues_model.Issue, hasOriginalAuthor bool) (issues_model.RoleDescriptor, error) { - roleDescriptor := issues_model.RoleDescriptor{} - +func roleDescriptor(ctx *context.Context, repo *repo_model.Repository, poster *user_model.User, permsCache map[int64]access_model.Permission, issue *issues_model.Issue, hasOriginalAuthor bool) (roleDesc issues_model.RoleDescriptor, err error) { if hasOriginalAuthor { - return roleDescriptor, nil + // the poster is a migrated user, so no need to detect the role + return roleDesc, nil } - var perm access_model.Permission - var err error - if permsCache != nil { - var ok bool - perm, ok = permsCache[poster.ID] - if !ok { - perm, err = access_model.GetUserRepoPermission(ctx, repo, poster) - if err != nil { - return roleDescriptor, err - } - } - permsCache[poster.ID] = perm - } else { + if poster.IsGhost() || !poster.IsIndividual() { + return roleDesc, nil + } + + roleDesc.IsPoster = issue.IsPoster(poster.ID) // check whether the comment's poster is the issue's poster + + // Guess the role of the poster in the repo by permission + perm, hasPermCache := permsCache[poster.ID] + if !hasPermCache { perm, err = access_model.GetUserRepoPermission(ctx, repo, poster) if err != nil { - return roleDescriptor, err + return roleDesc, err } } - - // If the poster is the actual poster of the issue, enable Poster role. - roleDescriptor.IsPoster = issue.IsPoster(poster.ID) + if permsCache != nil { + permsCache[poster.ID] = perm + } // Check if the poster is owner of the repo. if perm.IsOwner() { - // If the poster isn't an admin, enable the owner role. + // If the poster isn't a site admin, then is must be the repo's owner if !poster.IsAdmin { - roleDescriptor.RoleInRepo = issues_model.RoleRepoOwner - return roleDescriptor, nil + roleDesc.RoleInRepo = issues_model.RoleRepoOwner + return roleDesc, nil } - - // Otherwise check if poster is the real repo admin. - ok, err := access_model.IsUserRealRepoAdmin(ctx, repo, poster) + // Otherwise (poster is site admin), check if poster is the real repo admin. + isRealRepoAdmin, err := access_model.IsUserRealRepoAdmin(ctx, repo, poster) if err != nil { - return roleDescriptor, err + return roleDesc, err } - if ok { - roleDescriptor.RoleInRepo = issues_model.RoleRepoOwner - return roleDescriptor, nil + if isRealRepoAdmin { + roleDesc.RoleInRepo = issues_model.RoleRepoOwner + return roleDesc, nil } } // If repo is organization, check Member role - if err := repo.LoadOwner(ctx); err != nil { - return roleDescriptor, err + if err = repo.LoadOwner(ctx); err != nil { + return roleDesc, err } if repo.Owner.IsOrganization() { if isMember, err := organization.IsOrganizationMember(ctx, repo.Owner.ID, poster.ID); err != nil { - return roleDescriptor, err + return roleDesc, err } else if isMember { - roleDescriptor.RoleInRepo = issues_model.RoleRepoMember - return roleDescriptor, nil + roleDesc.RoleInRepo = issues_model.RoleRepoMember + return roleDesc, nil } } // If the poster is the collaborator of the repo if isCollaborator, err := repo_model.IsCollaborator(ctx, repo.ID, poster.ID); err != nil { - return roleDescriptor, err + return roleDesc, err } else if isCollaborator { - roleDescriptor.RoleInRepo = issues_model.RoleRepoCollaborator - return roleDescriptor, nil + roleDesc.RoleInRepo = issues_model.RoleRepoCollaborator + return roleDesc, nil } hasMergedPR, err := issues_model.HasMergedPullRequestInRepo(ctx, repo.ID, poster.ID) if err != nil { - return roleDescriptor, err + return roleDesc, err } else if hasMergedPR { - roleDescriptor.RoleInRepo = issues_model.RoleRepoContributor + roleDesc.RoleInRepo = issues_model.RoleRepoContributor } else if issue.IsPull { // only display first time contributor in the first opening pull request - roleDescriptor.RoleInRepo = issues_model.RoleRepoFirstTimeContributor + roleDesc.RoleInRepo = issues_model.RoleRepoFirstTimeContributor } - return roleDescriptor, nil + return roleDesc, nil } func getBranchData(ctx *context.Context, issue *issues_model.Issue) { diff --git a/templates/shared/user/authorlink.tmpl b/templates/shared/user/authorlink.tmpl index abe1ab1ce2..abfee6aae3 100644 --- a/templates/shared/user/authorlink.tmpl +++ b/templates/shared/user/authorlink.tmpl @@ -1 +1 @@ -{{.GetDisplayName}}{{if .IsBot}}bot{{end}} +{{.GetDisplayName}}{{if .IsTypeBot}}bot{{end}} From a52720b5b4da3e324034312f7fe1e29fd22686cc Mon Sep 17 00:00:00 2001 From: Kerwin Bryant Date: Sun, 9 Feb 2025 00:13:41 +0800 Subject: [PATCH 070/655] Add "No data available" display when list is empty (#33517) Add a "No data available" message to be displayed when the list has no data. This improves the user experience by providing clear feedback in an empty state. --------- Co-authored-by: wxiaoguang --- templates/admin/auth/list.tmpl | 2 ++ templates/admin/emails/list.tmpl | 2 ++ templates/admin/notice.tmpl | 2 ++ templates/admin/org/list.tmpl | 2 ++ templates/admin/packages/list.tmpl | 2 ++ templates/admin/repo/list.tmpl | 2 ++ templates/admin/user/list.tmpl | 2 ++ tests/integration/auth_ldap_test.go | 2 +- 8 files changed, 15 insertions(+), 1 deletion(-) diff --git a/templates/admin/auth/list.tmpl b/templates/admin/auth/list.tmpl index 7931014b1a..a1e72b742f 100644 --- a/templates/admin/auth/list.tmpl +++ b/templates/admin/auth/list.tmpl @@ -30,6 +30,8 @@ {{DateUtils.AbsoluteShort .CreatedUnix}} {{svg "octicon-pencil"}} + {{else}} + {{ctx.Locale.Tr "no_results_found"}} {{end}} diff --git a/templates/admin/emails/list.tmpl b/templates/admin/emails/list.tmpl index 0dc1fb9d03..b4335aeeec 100644 --- a/templates/admin/emails/list.tmpl +++ b/templates/admin/emails/list.tmpl @@ -67,6 +67,8 @@ >{{svg "octicon-trash"}} + {{else}} + {{ctx.Locale.Tr "no_results_found"}} {{end}} diff --git a/templates/admin/notice.tmpl b/templates/admin/notice.tmpl index fd475d7157..a4c9dc53fb 100644 --- a/templates/admin/notice.tmpl +++ b/templates/admin/notice.tmpl @@ -24,6 +24,8 @@ {{DateUtils.AbsoluteShort .CreatedUnix}} {{svg "octicon-note" 16}} + {{else}} + {{ctx.Locale.Tr "no_results_found"}} {{end}} {{if .Notices}} diff --git a/templates/admin/org/list.tmpl b/templates/admin/org/list.tmpl index d5e09939c5..137c42b45d 100644 --- a/templates/admin/org/list.tmpl +++ b/templates/admin/org/list.tmpl @@ -66,6 +66,8 @@ {{DateUtils.AbsoluteShort .CreatedUnix}} {{svg "octicon-pencil"}} + {{else}} + {{ctx.Locale.Tr "no_results_found"}} {{end}} diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl index 08c11442bc..0c6889b599 100644 --- a/templates/admin/packages/list.tmpl +++ b/templates/admin/packages/list.tmpl @@ -74,6 +74,8 @@ {{DateUtils.AbsoluteShort .Version.CreatedUnix}} {{svg "octicon-trash"}} + {{else}} + {{ctx.Locale.Tr "no_results_found"}} {{end}} diff --git a/templates/admin/repo/list.tmpl b/templates/admin/repo/list.tmpl index 08fd893e76..762013af47 100644 --- a/templates/admin/repo/list.tmpl +++ b/templates/admin/repo/list.tmpl @@ -86,6 +86,8 @@ {{DateUtils.AbsoluteShort .CreatedUnix}} {{svg "octicon-trash"}} + {{else}} + {{ctx.Locale.Tr "no_results_found"}} {{end}} diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl index 7e4c8854f5..eb3f6cd720 100644 --- a/templates/admin/user/list.tmpl +++ b/templates/admin/user/list.tmpl @@ -109,6 +109,8 @@
+ {{else}} + {{ctx.Locale.Tr "no_results_found"}} {{end}} diff --git a/tests/integration/auth_ldap_test.go b/tests/integration/auth_ldap_test.go index 5c50fd0288..0599c43805 100644 --- a/tests/integration/auth_ldap_test.go +++ b/tests/integration/auth_ldap_test.go @@ -279,7 +279,7 @@ func TestLDAPUserSyncWithEmptyUsernameAttribute(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) - tr := htmlDoc.doc.Find("table.table tbody tr") + tr := htmlDoc.doc.Find("table.table tbody tr:not(.no-results-row)") assert.Equal(t, 0, tr.Length()) } From 06088ec672a053b11a20ca6dd21588380d67f396 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 10 Feb 2025 04:39:54 +0800 Subject: [PATCH 071/655] Remove "class-name" from svg icon (#33540) Only use "class" attribute --- web_src/js/components/ActionRunStatus.vue | 12 ++++++------ web_src/js/components/DashboardRepoList.vue | 18 +++++++++--------- .../js/components/RepoBranchTagSelector.vue | 6 +++--- web_src/js/svg.test.ts | 3 +-- web_src/js/svg.ts | 11 +---------- 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/web_src/js/components/ActionRunStatus.vue b/web_src/js/components/ActionRunStatus.vue index 96c6c441be..487d2460cc 100644 --- a/web_src/js/components/ActionRunStatus.vue +++ b/web_src/js/components/ActionRunStatus.vue @@ -19,12 +19,12 @@ withDefaults(defineProps<{ diff --git a/web_src/js/components/DashboardRepoList.vue b/web_src/js/components/DashboardRepoList.vue index 876292fc94..14b7f0dec8 100644 --- a/web_src/js/components/DashboardRepoList.vue +++ b/web_src/js/components/DashboardRepoList.vue @@ -367,7 +367,7 @@ export default defineComponent({ otherwise if the "input" handles click event for intermediate status, it breaks the internal state-->
@@ -376,7 +376,7 @@ export default defineComponent({
@@ -413,7 +413,7 @@ export default defineComponent({ @@ -432,7 +432,7 @@ export default defineComponent({ class="item navigation tw-py-1" :class="{'disabled': page === 1}" @click="changePage(1)" :title="textFirstPage" > - + - + - +
@@ -471,7 +471,7 @@ export default defineComponent({ diff --git a/web_src/js/components/RepoBranchTagSelector.vue b/web_src/js/components/RepoBranchTagSelector.vue index fa5c75af99..820e69d9ab 100644 --- a/web_src/js/components/RepoBranchTagSelector.vue +++ b/web_src/js/components/RepoBranchTagSelector.vue @@ -226,7 +226,7 @@ export default defineComponent({ {{ currentRefShortName }} - +
{{svg "octicon-download"}} - {{svg "octicon-copy"}} + {{svg "octicon-copy"}} {{if .EnableFeed}} {{svg "octicon-rss"}} diff --git a/web_src/js/features/common-button.ts b/web_src/js/features/common-button.ts index 7aebdd8dd5..003bfbce5d 100644 --- a/web_src/js/features/common-button.ts +++ b/web_src/js/features/common-button.ts @@ -1,5 +1,5 @@ import {POST} from '../modules/fetch.ts'; -import {addDelegatedEventListener, hideElem, queryElems, showElem, toggleElem} from '../utils/dom.ts'; +import {addDelegatedEventListener, hideElem, showElem, toggleElem} from '../utils/dom.ts'; import {fomanticQuery} from '../modules/fomantic/base.ts'; import {camelize} from 'vue'; @@ -74,10 +74,9 @@ export function initGlobalDeleteButton(): void { } } -function onShowPanelClick(e: MouseEvent) { +function onShowPanelClick(el: HTMLElement, e: MouseEvent) { // a '.show-panel' element can show a panel, by `data-panel="selector"` // if it has "toggle" class, it toggles the panel - const el = e.currentTarget as HTMLElement; e.preventDefault(); const sel = el.getAttribute('data-panel'); if (el.classList.contains('toggle')) { @@ -87,9 +86,8 @@ function onShowPanelClick(e: MouseEvent) { } } -function onHidePanelClick(e: MouseEvent) { +function onHidePanelClick(el: HTMLElement, e: MouseEvent) { // a `.hide-panel` element can hide a panel, by `data-panel="selector"` or `data-panel-closest="selector"` - const el = e.currentTarget as HTMLElement; e.preventDefault(); let sel = el.getAttribute('data-panel'); if (sel) { @@ -104,7 +102,7 @@ function onHidePanelClick(e: MouseEvent) { throw new Error('no panel to hide'); // should never happen, otherwise there is a bug in code } -function onShowModalClick(e: MouseEvent) { +function onShowModalClick(el: HTMLElement, e: MouseEvent) { // A ".show-modal" button will show a modal dialog defined by its "data-modal" attribute. // Each "data-modal-{target}" attribute will be filled to target element's value or text-content. // * First, try to query '#target' @@ -112,7 +110,6 @@ function onShowModalClick(e: MouseEvent) { // * Then, try to query '.target' // * Then, try to query 'target' as HTML tag // If there is a ".{attr}" part like "data-modal-form.action", then the form's "action" attribute will be set. - const el = e.currentTarget as HTMLElement; e.preventDefault(); const modalSelector = el.getAttribute('data-modal'); const elModal = document.querySelector(modalSelector); @@ -160,7 +157,15 @@ export function initGlobalButtons(): void { // There are a few cancel buttons in non-modal forms, and there are some dynamically created forms (eg: the "Edit Issue Content") addDelegatedEventListener(document, 'click', 'form button.ui.cancel.button', (_ /* el */, e) => e.preventDefault()); - queryElems(document, '.show-panel', (el) => el.addEventListener('click', onShowPanelClick)); - queryElems(document, '.hide-panel', (el) => el.addEventListener('click', onHidePanelClick)); - queryElems(document, '.show-modal', (el) => el.addEventListener('click', onShowModalClick)); + // Ideally these "button" events should be handled by registerGlobalEventFunc + // Refactoring would involve too many changes, so at the moment, just use the global event listener. + addDelegatedEventListener(document, 'click', '.show-panel, .hide-panel, .show-modal', (el, e: MouseEvent) => { + if (el.classList.contains('show-panel')) { + onShowPanelClick(el, e); + } else if (el.classList.contains('hide-panel')) { + onHidePanelClick(el, e); + } else if (el.classList.contains('show-modal')) { + onShowModalClick(el, e); + } + }); } diff --git a/web_src/js/features/copycontent.ts b/web_src/js/features/copycontent.ts index 4bc9281a35..3961a8d7ac 100644 --- a/web_src/js/features/copycontent.ts +++ b/web_src/js/features/copycontent.ts @@ -2,21 +2,19 @@ import {clippie} from 'clippie'; import {showTemporaryTooltip} from '../modules/tippy.ts'; import {convertImage} from '../utils.ts'; import {GET} from '../modules/fetch.ts'; +import {registerGlobalEventFunc} from '../modules/observer.ts'; const {i18n} = window.config; export function initCopyContent() { - const btn = document.querySelector('#copy-content'); - if (!btn || btn.classList.contains('disabled')) return; - - btn.addEventListener('click', async () => { - if (btn.classList.contains('is-loading')) return; + registerGlobalEventFunc('click', 'onCopyContentButtonClick', async (btn: HTMLInputElement) => { + if (btn.classList.contains('disabled') || btn.classList.contains('is-loading')) return; let content; let isRasterImage = false; const link = btn.getAttribute('data-link'); // when data-link is present, we perform a fetch. this is either because - // the text to copy is not in the DOM or it is an image which should be + // the text to copy is not in the DOM, or it is an image which should be // fetched to copy in full resolution if (link) { btn.classList.add('is-loading', 'loading-icon-2px'); @@ -40,7 +38,7 @@ export function initCopyContent() { content = Array.from(lineEls, (el) => el.textContent).join(''); } - // try copy original first, if that fails and it's an image, convert it to png + // try copy original first, if that fails, and it's an image, convert it to png const success = await clippie(content); if (success) { showTemporaryTooltip(btn, i18n.copy_success); diff --git a/web_src/js/features/repo-commit.ts b/web_src/js/features/repo-commit.ts index 8994a57f4a..e6d1112778 100644 --- a/web_src/js/features/repo-commit.ts +++ b/web_src/js/features/repo-commit.ts @@ -1,15 +1,14 @@ import {createTippy} from '../modules/tippy.ts'; import {toggleElem} from '../utils/dom.ts'; +import {registerGlobalEventFunc} from '../modules/observer.ts'; export function initRepoEllipsisButton() { - for (const button of document.querySelectorAll('.js-toggle-commit-body')) { - button.addEventListener('click', function (e) { - e.preventDefault(); - const expanded = this.getAttribute('aria-expanded') === 'true'; - toggleElem(this.parentElement.querySelector('.commit-body')); - this.setAttribute('aria-expanded', String(!expanded)); - }); - } + registerGlobalEventFunc('click', 'onRepoEllipsisButtonClick', async (el: HTMLInputElement, e: Event) => { + e.preventDefault(); + const expanded = el.getAttribute('aria-expanded') === 'true'; + toggleElem(el.parentElement.querySelector('.commit-body')); + el.setAttribute('aria-expanded', String(!expanded)); + }); } export function initCommitStatuses() { From 14be462646af7f8c4fd60b1212d27cc165c966dd Mon Sep 17 00:00:00 2001 From: Kerwin Bryant Date: Tue, 4 Mar 2025 04:58:19 +0800 Subject: [PATCH 170/655] Refactor initRepoBranchTagSelector to use new init framework (#33776) Make "initRepoBranchTagSelector" to use new init framework and fix the abused "js-branch-tag-selector" styles --------- Co-authored-by: wxiaoguang --- templates/repo/branch_dropdown.tmpl | 3 ++- templates/repo/release/list.tmpl | 1 + web_src/css/repo/release-tag.css | 2 +- web_src/js/features/repo-legacy.ts | 9 +++++---- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl index 6efed3427f..f679b8744b 100644 --- a/templates/repo/branch_dropdown.tmpl +++ b/templates/repo/branch_dropdown.tmpl @@ -14,7 +14,8 @@ Search "repo/branch_dropdown" in the template directory to find all occurrences. */}} -
{ createApp(RepoBranchTagSelector, {elRoot}).mount(elRoot); - } + }); } export function initBranchSelectorTabs() { @@ -42,7 +43,7 @@ export function initRepository() { const pageContent = document.querySelector('.page-content.repository'); if (!pageContent) return; - initRepoBranchTagSelector('.js-branch-tag-selector'); + initRepoBranchTagSelector(); initRepoCommentFormAndSidebar(); // Labels From ffb276578fce488285eb01eea87237cda4c2b658 Mon Sep 17 00:00:00 2001 From: Denys Konovalov Date: Mon, 3 Mar 2025 22:23:42 +0100 Subject: [PATCH 171/655] Adjust appearence of commit status webhook (#33778) Some visual improvement for the commit status webhook message introduced by #33320 - use short commit SHA as already done in e. g. commit webhook - fix spacing, link text - do not set user link for internal gitea-actions user Before: ![grafik](https://github.com/user-attachments/assets/9c460846-c350-444c-89b5-8a0d5e26cb86) After: ![grafik](https://github.com/user-attachments/assets/05519cd8-6d8f-432b-bd9d-082de558a55a) --- services/webhook/general.go | 12 +++++++++--- services/webhook/matrix.go | 5 +++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/services/webhook/general.go b/services/webhook/general.go index 91bf68600f..c3e2ded204 100644 --- a/services/webhook/general.go +++ b/services/webhook/general.go @@ -9,7 +9,9 @@ import ( "net/url" "strings" + user_model "code.gitea.io/gitea/models/user" webhook_model "code.gitea.io/gitea/models/webhook" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" @@ -308,12 +310,16 @@ func getPackagePayloadInfo(p *api.PackagePayload, linkFormatter linkFormatter, w } func getStatusPayloadInfo(p *api.CommitStatusPayload, linkFormatter linkFormatter, withSender bool) (text string, color int) { - refLink := linkFormatter(p.TargetURL, p.Context+"["+p.SHA+"]:"+p.Description) + refLink := linkFormatter(p.TargetURL, fmt.Sprintf("%s [%s]", p.Context, base.ShortSha(p.SHA))) - text = fmt.Sprintf("Commit Status changed: %s", refLink) + text = fmt.Sprintf("Commit Status changed: %s - %s", refLink, p.Description) color = greenColor if withSender { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + if user_model.IsGiteaActionsUserName(p.Sender.UserName) { + text += fmt.Sprintf(" by %s", p.Sender.FullName) + } else { + text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + } } return text, color diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go index fb602f3860..034c0caf96 100644 --- a/services/webhook/matrix.go +++ b/services/webhook/matrix.go @@ -15,6 +15,7 @@ import ( "strings" webhook_model "code.gitea.io/gitea/models/webhook" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -245,8 +246,8 @@ func (m matrixConvertor) Package(p *api.PackagePayload) (MatrixPayload, error) { } func (m matrixConvertor) Status(p *api.CommitStatusPayload) (MatrixPayload, error) { - refLink := htmlLinkFormatter(p.TargetURL, p.Context+"["+p.SHA+"]:"+p.Description) - text := fmt.Sprintf("Commit Status changed: %s", refLink) + refLink := htmlLinkFormatter(p.TargetURL, fmt.Sprintf("%s [%s]", p.Context, base.ShortSha(p.SHA))) + text := fmt.Sprintf("Commit Status changed: %s - %s", refLink, p.Description) return m.newPayload(text) } From 163bbca0eb5d4091f96c187c031bc9af886660ab Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 4 Mar 2025 23:42:07 +0800 Subject: [PATCH 172/655] Refactor admin/common.ts (#33788) Only remove jQuery --- web_src/js/features/admin/common.ts | 203 ++++++++++++++++------------ 1 file changed, 114 insertions(+), 89 deletions(-) diff --git a/web_src/js/features/admin/common.ts b/web_src/js/features/admin/common.ts index 14a49af81e..3652ea7d39 100644 --- a/web_src/js/features/admin/common.ts +++ b/web_src/js/features/admin/common.ts @@ -1,8 +1,8 @@ -import $ from 'jquery'; import {checkAppUrl} from '../common-page.ts'; import {hideElem, queryElems, showElem, toggleElem} from '../../utils/dom.ts'; import {POST} from '../../modules/fetch.ts'; import {initAvatarUploaderWithCropper} from '../comp/Cropper.ts'; +import {fomanticQuery} from '../../modules/fomantic/base.ts'; const {appSubUrl} = window.config; @@ -20,32 +20,49 @@ export function initAdminCommon(): void { // check whether appUrl(ROOT_URL) is correct, if not, show an error message checkAppUrl(); - // New user - if ($('.admin.new.user').length > 0 || $('.admin.edit.user').length > 0) { - document.querySelector('#login_type')?.addEventListener('change', function () { - if (this.value?.startsWith('0')) { - document.querySelector('#user_name')?.removeAttribute('disabled'); - document.querySelector('#login_name')?.removeAttribute('required'); - hideElem('.non-local'); - showElem('.local'); - document.querySelector('#user_name')?.focus(); + initAdminUser(); + initAdminAuthentication(); + initAdminNotice(); - if (this.getAttribute('data-password') === 'required') { - document.querySelector('#password')?.setAttribute('required', 'required'); - } - } else { - if (document.querySelector('.admin.edit.user')) { - document.querySelector('#user_name')?.setAttribute('disabled', 'disabled'); - } - document.querySelector('#login_name')?.setAttribute('required', 'required'); - showElem('.non-local'); - hideElem('.local'); - document.querySelector('#login_name')?.focus(); + queryElems(document, '.avatar-file-with-cropper', initAvatarUploaderWithCropper); +} - document.querySelector('#password')?.removeAttribute('required'); +function initAdminUser() { + const pageContent = document.querySelector('.page-content.admin.edit.user, .page-content.admin.new.user'); + if (!pageContent) return; + + document.querySelector('#login_type')?.addEventListener('change', function () { + if (this.value?.startsWith('0')) { + document.querySelector('#user_name')?.removeAttribute('disabled'); + document.querySelector('#login_name')?.removeAttribute('required'); + hideElem('.non-local'); + showElem('.local'); + document.querySelector('#user_name')?.focus(); + + if (this.getAttribute('data-password') === 'required') { + document.querySelector('#password')?.setAttribute('required', 'required'); } - }); - } + } else { + if (document.querySelector('.admin.edit.user')) { + document.querySelector('#user_name')?.setAttribute('disabled', 'disabled'); + } + document.querySelector('#login_name')?.setAttribute('required', 'required'); + showElem('.non-local'); + hideElem('.local'); + document.querySelector('#login_name')?.focus(); + + document.querySelector('#password')?.removeAttribute('required'); + } + }); +} + +function initAdminAuthentication() { + const pageContent = document.querySelector('.page-content.admin.authentication'); + if (!pageContent) return; + + const isNewPage = pageContent.classList.contains('new'); + const isEditPage = pageContent.classList.contains('edit'); + if (!isNewPage && !isEditPage) return; function onUsePagedSearchChange() { const searchPageSizeElements = document.querySelectorAll('.search-page-size'); @@ -120,9 +137,11 @@ export function initAdminCommon(): void { toggleElem(document.querySelector('#ldap-group-options'), checked); } + const elAuthType = document.querySelector('#auth_type'); + // New authentication - if (document.querySelector('.admin.new.authentication')) { - document.querySelector('#auth_type')?.addEventListener('change', function () { + if (isNewPage) { + const onAuthTypeChange = function () { hideElem('.ldap, .dldap, .smtp, .pam, .oauth2, .has-tls, .search-page-size, .sspi'); for (const input of document.querySelectorAll('.ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required], .sspi input[required]')) { @@ -131,7 +150,7 @@ export function initAdminCommon(): void { document.querySelector('.binddnrequired')?.classList.remove('required'); - const authType = this.value; + const authType = elAuthType.value; switch (authType) { case '2': // LDAP showElem('.ldap'); @@ -180,20 +199,23 @@ export function initAdminCommon(): void { if (authType === '2') { onUsePagedSearchChange(); } - }); - $('#auth_type').trigger('change'); + }; + elAuthType.addEventListener('change', onAuthTypeChange); + onAuthTypeChange(); + document.querySelector('#security_protocol')?.addEventListener('change', onSecurityProtocolChange); document.querySelector('#use_paged_search')?.addEventListener('change', onUsePagedSearchChange); document.querySelector('#oauth2_provider')?.addEventListener('change', () => onOAuth2Change(true)); document.querySelector('#oauth2_use_custom_url')?.addEventListener('change', () => onOAuth2UseCustomURLChange(true)); - $('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange); + + document.querySelector('.js-ldap-group-toggle').addEventListener('change', onEnableLdapGroupsChange); } // Edit authentication - if (document.querySelector('.admin.edit.authentication')) { - const authType = document.querySelector('#auth_type')?.value; + if (isEditPage) { + const authType = elAuthType.value; if (authType === '2' || authType === '5') { document.querySelector('#security_protocol')?.addEventListener('change', onSecurityProtocolChange); - $('.js-ldap-group-toggle').on('change', onEnableLdapGroupsChange); + document.querySelector('.js-ldap-group-toggle').addEventListener('change', onEnableLdapGroupsChange); onEnableLdapGroupsChange(); if (authType === '2') { document.querySelector('#use_paged_search')?.addEventListener('change', onUsePagedSearchChange); @@ -205,60 +227,63 @@ export function initAdminCommon(): void { } } - if (document.querySelector('.admin.authentication')) { - $('#auth_name').on('input', function () { - // appSubUrl is either empty or is a path that starts with `/` and doesn't have a trailing slash. - document.querySelector('#oauth2-callback-url').textContent = `${window.location.origin}${appSubUrl}/user/oauth2/${encodeURIComponent((this as HTMLInputElement).value)}/callback`; - }).trigger('input'); - } - - // Notice - if (document.querySelector('.admin.notice')) { - const detailModal = document.querySelector('#detail-modal'); - - // Attach view detail modals - $('.view-detail').on('click', function () { - const description = this.closest('tr').querySelector('.notice-description').textContent; - detailModal.querySelector('.content pre').textContent = description; - $(detailModal).modal('show'); - return false; - }); - - // Select actions - const checkboxes = document.querySelectorAll('.select.table .ui.checkbox input'); - - $('.select.action').on('click', function () { - switch ($(this).data('action')) { - case 'select-all': - for (const checkbox of checkboxes) { - checkbox.checked = true; - } - break; - case 'deselect-all': - for (const checkbox of checkboxes) { - checkbox.checked = false; - } - break; - case 'inverse': - for (const checkbox of checkboxes) { - checkbox.checked = !checkbox.checked; - } - break; - } - }); - document.querySelector('#delete-selection')?.addEventListener('click', async function (e) { - e.preventDefault(); - this.classList.add('is-loading', 'disabled'); - const data = new FormData(); - for (const checkbox of checkboxes) { - if (checkbox.checked) { - data.append('ids[]', checkbox.closest('.ui.checkbox').getAttribute('data-id')); - } - } - await POST(this.getAttribute('data-link'), {data}); - window.location.href = this.getAttribute('data-redirect'); - }); - } - - queryElems(document, '.avatar-file-with-cropper', initAvatarUploaderWithCropper); + const elAuthName = document.querySelector('#auth_name'); + const onAuthNameChange = function () { + // appSubUrl is either empty or is a path that starts with `/` and doesn't have a trailing slash. + document.querySelector('#oauth2-callback-url').textContent = `${window.location.origin}${appSubUrl}/user/oauth2/${encodeURIComponent(elAuthName.value)}/callback`; + }; + elAuthName.addEventListener('input', onAuthNameChange); + onAuthNameChange(); +} + +function initAdminNotice() { + const pageContent = document.querySelector('.page-content.admin.notice'); + if (!pageContent) return; + + const detailModal = document.querySelector('#detail-modal'); + + // Attach view detail modals + queryElems(pageContent, '.view-detail', (el) => el.addEventListener('click', (e) => { + e.preventDefault(); + const elNoticeDesc = el.closest('tr').querySelector('.notice-description'); + const elModalDesc = detailModal.querySelector('.content pre'); + elModalDesc.textContent = elNoticeDesc.textContent; + fomanticQuery(detailModal).modal('show'); + })); + + // Select actions + const checkboxes = document.querySelectorAll('.select.table .ui.checkbox input'); + + queryElems(pageContent, '.select.action', (el) => el.addEventListener('click', () => { + switch (el.getAttribute('data-action')) { + case 'select-all': + for (const checkbox of checkboxes) { + checkbox.checked = true; + } + break; + case 'deselect-all': + for (const checkbox of checkboxes) { + checkbox.checked = false; + } + break; + case 'inverse': + for (const checkbox of checkboxes) { + checkbox.checked = !checkbox.checked; + } + break; + } + })); + + document.querySelector('#delete-selection')?.addEventListener('click', async function (e) { + e.preventDefault(); + this.classList.add('is-loading', 'disabled'); + const data = new FormData(); + for (const checkbox of checkboxes) { + if (checkbox.checked) { + data.append('ids[]', checkbox.closest('.ui.checkbox').getAttribute('data-id')); + } + } + await POST(this.getAttribute('data-link'), {data}); + window.location.href = this.getAttribute('data-redirect'); + }); } From ca0ce003ab33b58a692ceaab71e728c7aef8c216 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 5 Mar 2025 01:19:03 +0800 Subject: [PATCH 173/655] Refactor repo-settings.ts (#33785) and remove jQuery --- web_src/js/features/repo-settings.ts | 78 ++++++++++++++-------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/web_src/js/features/repo-settings.ts b/web_src/js/features/repo-settings.ts index 7e890a43e0..80f897069e 100644 --- a/web_src/js/features/repo-settings.ts +++ b/web_src/js/features/repo-settings.ts @@ -1,10 +1,10 @@ -import $ from 'jquery'; import {minimatch} from 'minimatch'; import {createMonaco} from './codeeditor.ts'; import {onInputDebounce, queryElems, toggleElem} from '../utils/dom.ts'; import {POST} from '../modules/fetch.ts'; import {initAvatarUploaderWithCropper} from './comp/Cropper.ts'; import {initRepoSettingsBranchesDrag} from './repo-settings-branches.ts'; +import {fomanticQuery} from '../modules/fomantic/base.ts'; const {appSubUrl, csrfToken} = window.config; @@ -12,11 +12,12 @@ function initRepoSettingsCollaboration() { // Change collaborator access mode for (const dropdownEl of queryElems(document, '.page-content.repository .ui.dropdown.access-mode')) { const textEl = dropdownEl.querySelector(':scope > .text'); - $(dropdownEl).dropdown({ + const $dropdown = fomanticQuery(dropdownEl); + $dropdown.dropdown({ async action(text: string, value: string) { dropdownEl.classList.add('is-loading', 'loading-icon-2px'); const lastValue = dropdownEl.getAttribute('data-last-value'); - $(dropdownEl).dropdown('hide'); + $dropdown.dropdown('hide'); try { const uid = dropdownEl.getAttribute('data-uid'); await POST(dropdownEl.getAttribute('data-url'), {data: new URLSearchParams({uid, 'mode': value})}); @@ -33,9 +34,9 @@ function initRepoSettingsCollaboration() { // set to the really selected value, defer to next tick to make sure `action` has finished // its work because the calling order might be onHide -> action setTimeout(() => { - const $item = $(dropdownEl).dropdown('get item', dropdownEl.getAttribute('data-last-value')); + const $item = $dropdown.dropdown('get item', dropdownEl.getAttribute('data-last-value')); if ($item) { - $(dropdownEl).dropdown('set selected', dropdownEl.getAttribute('data-last-value')); + $dropdown.dropdown('set selected', dropdownEl.getAttribute('data-last-value')); } else { textEl.textContent = '(none)'; // prevent from misleading users when the access mode is undefined } @@ -49,32 +50,32 @@ function initRepoSettingsSearchTeamBox() { const searchTeamBox = document.querySelector('#search-team-box'); if (!searchTeamBox) return; - $(searchTeamBox).search({ + fomanticQuery(searchTeamBox).search({ minCharacters: 2, + searchFields: ['name', 'description'], + showNoResults: false, + rawResponse: true, apiSettings: { url: `${appSubUrl}/org/${searchTeamBox.getAttribute('data-org-name')}/teams/-/search?q={query}`, headers: {'X-Csrf-Token': csrfToken}, onResponse(response: any) { const items: Array> = []; - $.each(response.data, (_i, item) => { + for (const item of response.data) { items.push({ title: item.name, description: `${item.permission} access`, // TODO: translate this string }); - }); - + } return {results: items}; }, }, - searchFields: ['name', 'description'], - showNoResults: false, }); } function initRepoSettingsGitHook() { - if (!$('.edit.githook').length) return; + if (!document.querySelector('.page-content.repository.settings.edit.githook')) return; const filename = document.querySelector('.hook-filename').textContent; - createMonaco($('#content')[0] as HTMLTextAreaElement, filename, {language: 'shell'}); + createMonaco(document.querySelector('#content'), filename, {language: 'shell'}); } function initRepoSettingsBranches() { @@ -121,32 +122,31 @@ function initRepoSettingsBranches() { } function initRepoSettingsOptions() { - if ($('.repository.settings.options').length > 0) { - // Enable or select internal/external wiki system and issue tracker. - $('.enable-system').on('change', function (this: HTMLInputElement) { // eslint-disable-line @typescript-eslint/no-deprecated - if (this.checked) { - $($(this).data('target')).removeClass('disabled'); - if (!$(this).data('context')) $($(this).data('context')).addClass('disabled'); - } else { - $($(this).data('target')).addClass('disabled'); - if (!$(this).data('context')) $($(this).data('context')).removeClass('disabled'); - } - }); - $('.enable-system-radio').on('change', function (this: HTMLInputElement) { // eslint-disable-line @typescript-eslint/no-deprecated - if (this.value === 'false') { - $($(this).data('target')).addClass('disabled'); - if ($(this).data('context') !== undefined) $($(this).data('context')).removeClass('disabled'); - } else if (this.value === 'true') { - $($(this).data('target')).removeClass('disabled'); - if ($(this).data('context') !== undefined) $($(this).data('context')).addClass('disabled'); - } - }); - const $trackerIssueStyleRadios = $('.js-tracker-issue-style'); - $trackerIssueStyleRadios.on('change input', () => { - const checkedVal = $trackerIssueStyleRadios.filter(':checked').val(); - $('#tracker-issue-style-regex-box').toggleClass('disabled', checkedVal !== 'regexp'); - }); - } + const pageContent = document.querySelector('.page-content.repository.settings.options'); + if (!pageContent) return; + + const toggleClass = (elems: NodeListOf, className: string, value: boolean) => { + for (const el of elems) el.classList.toggle(className, value); + }; + + // Enable or select internal/external wiki system and issue tracker. + queryElems(pageContent, '.enable-system', (el) => el.addEventListener('change', () => { + const elTargets = document.querySelectorAll(el.getAttribute('data-target')); + const elContexts = document.querySelectorAll(el.getAttribute('data-context')); + toggleClass(elTargets, 'disabled', !el.checked); + toggleClass(elContexts, 'disabled', el.checked); + })); + queryElems(pageContent, '.enable-system-radio', (el) => el.addEventListener('change', () => { + const elTargets = document.querySelectorAll(el.getAttribute('data-target')); + const elContexts = document.querySelectorAll(el.getAttribute('data-context')); + toggleClass(elTargets, 'disabled', el.value === 'false'); + toggleClass(elContexts, 'disabled', el.value === 'true'); + })); + + queryElems(pageContent, '.js-tracker-issue-style', (el) => el.addEventListener('change', () => { + const checkedVal = el.value; + pageContent.querySelector('#tracker-issue-style-regex-box').classList.toggle('disabled', checkedVal !== 'regexp'); + })); } export function initRepoSettings() { From 75e85c25c1674627ef750bf7114d3b0b7c0d15aa Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 5 Mar 2025 01:58:17 +0800 Subject: [PATCH 174/655] Refactor repo-issue.ts (#33784) And remove jQuery --- .github/workflows/pull-db-tests.yml | 6 +- options/locale/locale_en-US.ini | 2 +- .../issue/sidebar/issue_dependencies.tmpl | 47 ++-- templates/repo/issue/sidebar/wip_switch.tmpl | 8 +- templates/repo/issue/view_content/pull.tmpl | 4 +- .../view_content/pull_merge_instruction.tmpl | 98 +++---- .../view_content/update_branch_by_merge.tmpl | 2 +- web_src/js/features/repo-issue.ts | 243 ++++++++---------- web_src/js/features/repo-legacy.ts | 6 +- web_src/js/index.ts | 14 +- 10 files changed, 194 insertions(+), 236 deletions(-) diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml index 0b23de0a66..6e879053d3 100644 --- a/.github/workflows/pull-db-tests.yml +++ b/.github/workflows/pull-db-tests.yml @@ -202,12 +202,10 @@ jobs: test-mssql: if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.actions == 'true' needs: files-changed - # specifying the version of ubuntu in use as mssql fails on newer kernels - # pending resolution from vendor - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest services: mssql: - image: mcr.microsoft.com/mssql/server:2017-latest + image: mcr.microsoft.com/mssql/server:2019-latest env: ACCEPT_EULA: Y MSSQL_PID: Standard diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1da2fb61ad..4f1db5da6a 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1938,7 +1938,7 @@ pulls.outdated_with_base_branch = This branch is out-of-date with the base branc pulls.close = Close Pull Request pulls.closed_at = `closed this pull request %[2]s` pulls.reopened_at = `reopened this pull request %[2]s` -pulls.cmd_instruction_hint = `View command line instructions.` +pulls.cmd_instruction_hint = View command line instructions pulls.cmd_instruction_checkout_title = Checkout pulls.cmd_instruction_checkout_desc = From your project repository, check out a new branch and test the changes. pulls.cmd_instruction_merge_title = Merge diff --git a/templates/repo/issue/sidebar/issue_dependencies.tmpl b/templates/repo/issue/sidebar/issue_dependencies.tmpl index 17e9738c6f..bbae011958 100644 --- a/templates/repo/issue/sidebar/issue_dependencies.tmpl +++ b/templates/repo/issue/sidebar/issue_dependencies.tmpl @@ -31,7 +31,9 @@
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - + {{svg "octicon-trash" 16}} {{end}} @@ -63,7 +65,9 @@
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - + {{svg "octicon-trash" 16}} {{end}} @@ -86,7 +90,9 @@
{{if and $.CanCreateIssueDependencies (not $.Repository.IsArchived)}} - + {{svg "octicon-trash" 16}} {{end}} @@ -106,7 +112,7 @@ {{$.CsrfTokenHtml}}
- {{else if .IsPullWorkInProgress}} -
+
{{svg "octicon-x"}} {{ctx.Locale.Tr "repo.pulls.cannot_merge_work_in_progress"}}
{{if or .HasIssuesOrPullsWritePermission .IsIssuePoster}} - {{end}} diff --git a/templates/repo/issue/view_content/pull_merge_instruction.tmpl b/templates/repo/issue/view_content/pull_merge_instruction.tmpl index 9a3e2cb7d7..a1cff41a3a 100644 --- a/templates/repo/issue/view_content/pull_merge_instruction.tmpl +++ b/templates/repo/issue/view_content/pull_merge_instruction.tmpl @@ -1,55 +1,57 @@
-
{{ctx.Locale.Tr "repo.pulls.cmd_instruction_hint"}}
-
-

{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_title"}}

{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_desc"}}
- {{$localBranch := .PullRequest.HeadBranch}} - {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}} - {{$localBranch = print .PullRequest.HeadRepo.OwnerName "-" .PullRequest.HeadBranch}} - {{end}} -
- {{if eq .PullRequest.Flow 0}} -
git fetch -u {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}{{else}}origin{{end}} {{.PullRequest.HeadBranch}}:{{$localBranch}}
- {{else}} -
git fetch -u origin {{.PullRequest.GetGitRefName}}:{{$localBranch}}
+
+ {{ctx.Locale.Tr "repo.pulls.cmd_instruction_hint"}} +
+

{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_title"}}

{{ctx.Locale.Tr "repo.pulls.cmd_instruction_checkout_desc"}}
+ {{$localBranch := .PullRequest.HeadBranch}} + {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}} + {{$localBranch = print .PullRequest.HeadRepo.OwnerName "-" .PullRequest.HeadBranch}} {{end}} -
git checkout {{$localBranch}}
-
- {{if .ShowMergeInstructions}} -
-

{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}

- {{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}} - {{if not .AutodetectManualMerge}} -
{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_warning"}}
- {{end}} -
-
-
-
git checkout {{.PullRequest.BaseBranch}}
-
git merge --no-ff {{$localBranch}}
-
-
-
git checkout {{.PullRequest.BaseBranch}}
-
git merge --ff-only {{$localBranch}}
-
-
+
+ {{if eq .PullRequest.Flow 0}} +
git fetch -u {{if ne .PullRequest.HeadRepo.ID .PullRequest.BaseRepo.ID}}{{else}}origin{{end}} {{.PullRequest.HeadBranch}}:{{$localBranch}}
+ {{else}} +
git fetch -u origin {{.PullRequest.GetGitRefName}}:{{$localBranch}}
+ {{end}}
git checkout {{$localBranch}}
-
git rebase {{.PullRequest.BaseBranch}}
-
git checkout {{.PullRequest.BaseBranch}}
-
git merge --no-ff {{$localBranch}}
-
-
git checkout {{.PullRequest.BaseBranch}}
-
git merge --squash {{$localBranch}}
+ {{if .ShowMergeInstructions}} +
+

{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_title"}}

+ {{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_desc"}} + {{if not .AutodetectManualMerge}} +
{{ctx.Locale.Tr "repo.pulls.cmd_instruction_merge_warning"}}
+ {{end}}
-
-
git checkout {{.PullRequest.BaseBranch}}
-
git merge --ff-only {{$localBranch}}
+
+
+
git checkout {{.PullRequest.BaseBranch}}
+
git merge --no-ff {{$localBranch}}
+
+
+
git checkout {{.PullRequest.BaseBranch}}
+
git merge --ff-only {{$localBranch}}
+
+
+
git checkout {{$localBranch}}
+
git rebase {{.PullRequest.BaseBranch}}
+
git checkout {{.PullRequest.BaseBranch}}
+
git merge --no-ff {{$localBranch}}
+
+
+
git checkout {{.PullRequest.BaseBranch}}
+
git merge --squash {{$localBranch}}
+
+
+
git checkout {{.PullRequest.BaseBranch}}
+
git merge --ff-only {{$localBranch}}
+
+
+
git checkout {{.PullRequest.BaseBranch}}
+
git merge {{$localBranch}}
+
+
git push origin {{.PullRequest.BaseBranch}}
-
-
git checkout {{.PullRequest.BaseBranch}}
-
git merge {{$localBranch}}
-
-
git push origin {{.PullRequest.BaseBranch}}
+ {{end}}
- {{end}} -
+
diff --git a/templates/repo/issue/view_content/update_branch_by_merge.tmpl b/templates/repo/issue/view_content/update_branch_by_merge.tmpl index adce052dee..e0ed262f17 100644 --- a/templates/repo/issue/view_content/update_branch_by_merge.tmpl +++ b/templates/repo/issue/view_content/update_branch_by_merge.tmpl @@ -8,7 +8,7 @@
{{if and $.UpdateAllowed $.UpdateByRebaseAllowed}}
-
+
-
-
- {{.CsrfTokenHtml}} - - -
- -
- -
-
-
- - -
-
- - -
-
-
+
+ {{.CsrfTokenHtml}} + + +
+ + +
+
+ + +
+
+ + +
+
From 5d65b9060b24e507fa530a1cfd6171b6d799f5e8 Mon Sep 17 00:00:00 2001 From: TheFox0x7 Date: Fri, 14 Mar 2025 01:28:57 +0100 Subject: [PATCH 214/655] remove context from retry downloader (#33871) follow up to https://github.com/go-gitea/gitea/pull/33399 as I apparently missed this one. --- modules/migration/retry_downloader.go | 30 +++++++++++++-------------- services/migrations/migrate.go | 2 +- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/modules/migration/retry_downloader.go b/modules/migration/retry_downloader.go index 2926c40df7..69804b7767 100644 --- a/modules/migration/retry_downloader.go +++ b/modules/migration/retry_downloader.go @@ -13,36 +13,34 @@ var _ Downloader = &RetryDownloader{} // RetryDownloader retry the downloads type RetryDownloader struct { Downloader - ctx context.Context RetryTimes int // the total execute times RetryDelay int // time to delay seconds } // NewRetryDownloader creates a retry downloader -func NewRetryDownloader(ctx context.Context, downloader Downloader, retryTimes, retryDelay int) *RetryDownloader { +func NewRetryDownloader(downloader Downloader, retryTimes, retryDelay int) *RetryDownloader { return &RetryDownloader{ Downloader: downloader, - ctx: ctx, RetryTimes: retryTimes, RetryDelay: retryDelay, } } -func (d *RetryDownloader) retry(work func() error) error { +func (d *RetryDownloader) retry(ctx context.Context, work func(context.Context) error) error { var ( times = d.RetryTimes err error ) for ; times > 0; times-- { - if err = work(); err == nil { + if err = work(ctx); err == nil { return nil } if IsErrNotSupported(err) { return err } select { - case <-d.ctx.Done(): - return d.ctx.Err() + case <-ctx.Done(): + return ctx.Err() case <-time.After(time.Second * time.Duration(d.RetryDelay)): } } @@ -56,7 +54,7 @@ func (d *RetryDownloader) GetRepoInfo(ctx context.Context) (*Repository, error) err error ) - err = d.retry(func() error { + err = d.retry(ctx, func(ctx context.Context) error { repo, err = d.Downloader.GetRepoInfo(ctx) return err }) @@ -71,7 +69,7 @@ func (d *RetryDownloader) GetTopics(ctx context.Context) ([]string, error) { err error ) - err = d.retry(func() error { + err = d.retry(ctx, func(ctx context.Context) error { topics, err = d.Downloader.GetTopics(ctx) return err }) @@ -86,7 +84,7 @@ func (d *RetryDownloader) GetMilestones(ctx context.Context) ([]*Milestone, erro err error ) - err = d.retry(func() error { + err = d.retry(ctx, func(ctx context.Context) error { milestones, err = d.Downloader.GetMilestones(ctx) return err }) @@ -101,7 +99,7 @@ func (d *RetryDownloader) GetReleases(ctx context.Context) ([]*Release, error) { err error ) - err = d.retry(func() error { + err = d.retry(ctx, func(ctx context.Context) error { releases, err = d.Downloader.GetReleases(ctx) return err }) @@ -116,7 +114,7 @@ func (d *RetryDownloader) GetLabels(ctx context.Context) ([]*Label, error) { err error ) - err = d.retry(func() error { + err = d.retry(ctx, func(ctx context.Context) error { labels, err = d.Downloader.GetLabels(ctx) return err }) @@ -132,7 +130,7 @@ func (d *RetryDownloader) GetIssues(ctx context.Context, page, perPage int) ([]* err error ) - err = d.retry(func() error { + err = d.retry(ctx, func(ctx context.Context) error { issues, isEnd, err = d.Downloader.GetIssues(ctx, page, perPage) return err }) @@ -148,7 +146,7 @@ func (d *RetryDownloader) GetComments(ctx context.Context, commentable Commentab err error ) - err = d.retry(func() error { + err = d.retry(ctx, func(context.Context) error { comments, isEnd, err = d.Downloader.GetComments(ctx, commentable) return err }) @@ -164,7 +162,7 @@ func (d *RetryDownloader) GetPullRequests(ctx context.Context, page, perPage int isEnd bool ) - err = d.retry(func() error { + err = d.retry(ctx, func(ctx context.Context) error { prs, isEnd, err = d.Downloader.GetPullRequests(ctx, page, perPage) return err }) @@ -178,7 +176,7 @@ func (d *RetryDownloader) GetReviews(ctx context.Context, reviewable Reviewable) reviews []*Review err error ) - err = d.retry(func() error { + err = d.retry(ctx, func(ctx context.Context) error { reviews, err = d.Downloader.GetReviews(ctx, reviewable) return err }) diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go index 8319fd541b..5dda12286f 100644 --- a/services/migrations/migrate.go +++ b/services/migrations/migrate.go @@ -168,7 +168,7 @@ func newDownloader(ctx context.Context, ownerName string, opts base.MigrateOptio } if setting.Migrations.MaxAttempts > 1 { - downloader = base.NewRetryDownloader(ctx, downloader, setting.Migrations.MaxAttempts, setting.Migrations.RetryBackoff) + downloader = base.NewRetryDownloader(downloader, setting.Migrations.MaxAttempts, setting.Migrations.RetryBackoff) } return downloader, nil } From de2d472d90b1c563a432e27621cb455378b700f8 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Fri, 14 Mar 2025 00:33:05 +0000 Subject: [PATCH 215/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_fr-FR.ini | 10 ++++++++-- options/locale/locale_ga-IE.ini | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 9bcb4e585c..11a7960bc9 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -1463,6 +1463,8 @@ issues.filter_milestones=Filtrer le jalon issues.filter_projects=Filtrer par projet issues.filter_labels=Filtrer par labels issues.filter_reviewers=Filtrer par évaluateur +issues.filter_no_results=Aucun résultat +issues.filter_no_results_placeholder=Essayez d’ajuster vos filtres de recherche. issues.new=Nouveau ticket issues.new.title_empty=Le titre ne peut pas être vide issues.new.labels=Labels @@ -1935,6 +1937,7 @@ pulls.outdated_with_base_branch=Cette branche est désynchronisée avec la branc pulls.close=Fermer la demande d’ajout pulls.closed_at=`a fermé cette demande d'ajout %[2]s.` pulls.reopened_at=`a rouvert cette demande d'ajout %[2]s.` +pulls.cmd_instruction_hint=Voir les instructions en ligne de commande pulls.cmd_instruction_checkout_title=Basculer pulls.cmd_instruction_checkout_desc=Depuis votre dépôt, basculer sur une nouvelle branche et tester des modifications. pulls.cmd_instruction_merge_title=Fusionner @@ -2376,6 +2379,9 @@ settings.event_pull_request_review_request=Demande d’évaluation settings.event_pull_request_review_request_desc=Création ou suppresion de demandes d’évaluation. settings.event_pull_request_approvals=Approbations de demande d'ajout settings.event_pull_request_merge=Fusion de demande d'ajout +settings.event_header_workflow=Événements du flux de travail +settings.event_workflow_job=Tâches du flux de travail +settings.event_workflow_job_desc=Tâche du flux de travail Gitea Actions en file d’attente, en attente, en cours ou terminée. settings.event_package=Paquet settings.event_package_desc=Paquet créé ou supprimé. settings.branch_filter=Filtre de branche @@ -2454,7 +2460,7 @@ settings.protect_whitelist_teams=Équipes autorisées à pousser : settings.protect_force_push_allowlist_users=Utilisateurs autorisés à pousser en force : settings.protect_force_push_allowlist_teams=Équipes autorisées à pousser en force : settings.protect_force_push_allowlist_deploy_keys=Clés de déploiement pouvant pousser autorisées à pousser en force. -settings.protect_merge_whitelist_committers=Activer la liste d’autorisés pour la fusion +settings.protect_merge_whitelist_committers=Fusion sur autorisation uniquement settings.protect_merge_whitelist_committers_desc=N’autoriser que les utilisateurs et les équipes listés à appliquer les demandes de fusion sur cette branche. settings.protect_merge_whitelist_users=Utilisateurs autorisés à fusionner : settings.protect_merge_whitelist_teams=Équipes autorisées à fusionner : @@ -2468,7 +2474,7 @@ settings.protect_invalid_status_check_pattern=Motif de vérification des statuts settings.protect_no_valid_status_check_patterns=Aucun motif de vérification des statuts valide. settings.protect_required_approvals=Minimum d'approbations requis : settings.protect_required_approvals_desc=Permet de fusionner les demandes d’ajout lorsque suffisamment d’évaluation sont positives. -settings.protect_approvals_whitelist_enabled=Restreindre les approbations aux utilisateurs ou aux équipes sur liste d’autorisés +settings.protect_approvals_whitelist_enabled=Restreindre les approbations sur autorisation uniquement settings.protect_approvals_whitelist_enabled_desc=Seuls les évaluations des utilisateurs ou des équipes suivantes compteront dans les approbations requises. Si laissé vide, les évaluations de toute personne ayant un accès en écriture seront comptabilisées à la place. settings.protect_approvals_whitelist_users=Évaluateurs autorisés : settings.protect_approvals_whitelist_teams=Équipes d’évaluateurs autorisés : diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index 09980d9747..2371e807e2 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -2379,6 +2379,9 @@ settings.event_pull_request_review_request=Iarratas ar Athbhreithniú Tarraingth settings.event_pull_request_review_request_desc=Tarraing athbhreithniú iarratais iarrtha nó baineadh iarratas athbhreithnithe. settings.event_pull_request_approvals=Ceaduithe Iarratais Tarraing settings.event_pull_request_merge=Cumaisc Iarratas Tarraing +settings.event_header_workflow=Imeachtaí Sreabhadh Oibre +settings.event_workflow_job=Poist Sreabhadh Oibre +settings.event_workflow_job_desc=Gitea Actions Sreabhadh oibre post ciúáilte, ag fanacht, ar siúl, nó críochnaithe. settings.event_package=Pacáiste settings.event_package_desc=Pacáiste a cruthaíodh nó a scriosadh i stóras. settings.branch_filter=Scagaire brainse From 1e7248047ce66c235faf53cd79b6513fb3aa1c50 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 13 Mar 2025 19:36:14 -0700 Subject: [PATCH 216/655] Pull request updates will also trigger code owners review requests (#33744) Fix #33490 It will only read the changed file on the pushed commits but not all the files of this PR. --------- Co-authored-by: wxiaoguang --- routers/web/repo/view_file.go | 3 +- services/issue/issue.go | 6 ++- services/issue/pull.go | 42 ++++++++++++++----- services/pull/merge.go | 10 ++++- services/pull/pull.go | 59 +++++++++++++++++++-------- services/pull/update.go | 20 ++++++++- services/repository/push.go | 12 +++++- tests/integration/pull_review_test.go | 42 +++++++++++++++++-- 8 files changed, 157 insertions(+), 37 deletions(-) diff --git a/routers/web/repo/view_file.go b/routers/web/repo/view_file.go index 5784297918..4ce7a8e3a4 100644 --- a/routers/web/repo/view_file.go +++ b/routers/web/repo/view_file.go @@ -9,7 +9,6 @@ import ( "image" "io" "path" - "slices" "strings" git_model "code.gitea.io/gitea/models/git" @@ -79,7 +78,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) { if workFlowErr != nil { ctx.Data["FileError"] = ctx.Locale.Tr("actions.runs.invalid_workflow_helper", workFlowErr.Error()) } - } else if slices.Contains([]string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"}, ctx.Repo.TreePath) { + } else if issue_service.IsCodeOwnerFile(ctx.Repo.TreePath) { if data, err := blob.GetBlobContent(setting.UI.MaxDisplayFileSize); err == nil { _, warnings := issue_model.GetCodeOwnersFromContent(ctx, data) if len(warnings) > 0 { diff --git a/services/issue/issue.go b/services/issue/issue.go index 586b6031c8..455a1ec297 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -92,8 +92,12 @@ func ChangeTitle(ctx context.Context, issue *issues_model.Issue, doer *user_mode var reviewNotifiers []*ReviewRequestNotifier if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issues_model.HasWorkInProgressPrefix(title) { + if err := issue.LoadPullRequest(ctx); err != nil { + return err + } + var err error - reviewNotifiers, err = PullRequestCodeOwnersReview(ctx, issue, issue.PullRequest) + reviewNotifiers, err = PullRequestCodeOwnersReview(ctx, issue.PullRequest) if err != nil { log.Error("PullRequestCodeOwnersReview: %v", err) } diff --git a/services/issue/pull.go b/services/issue/pull.go index 896802108d..bd19c25436 100644 --- a/services/issue/pull.go +++ b/services/issue/pull.go @@ -6,6 +6,7 @@ package issue import ( "context" "fmt" + "slices" "time" issues_model "code.gitea.io/gitea/models/issues" @@ -40,20 +41,31 @@ type ReviewRequestNotifier struct { ReviewTeam *org_model.Team } -func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue, pr *issues_model.PullRequest) ([]*ReviewRequestNotifier, error) { - files := []string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"} +var codeOwnerFiles = []string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"} +func IsCodeOwnerFile(f string) bool { + return slices.Contains(codeOwnerFiles, f) +} + +func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullRequest) ([]*ReviewRequestNotifier, error) { + return PullRequestCodeOwnersReviewSpecialCommits(ctx, pr, "", "") // no commit is provided, then it uses PR's base&head branch +} + +func PullRequestCodeOwnersReviewSpecialCommits(ctx context.Context, pr *issues_model.PullRequest, startCommitID, endCommitID string) ([]*ReviewRequestNotifier, error) { + if err := pr.LoadIssue(ctx); err != nil { + return nil, err + } + issue := pr.Issue if pr.IsWorkInProgress(ctx) { return nil, nil } - if err := pr.LoadHeadRepo(ctx); err != nil { return nil, err } - if err := pr.LoadBaseRepo(ctx); err != nil { return nil, err } + pr.Issue.Repo = pr.BaseRepo if pr.BaseRepo.IsFork { return nil, nil @@ -71,7 +83,7 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue, } var data string - for _, file := range files { + for _, file := range codeOwnerFiles { if blob, err := commit.GetBlobByPath(file); err == nil { data, err = blob.GetBlobContent(setting.UI.MaxDisplayFileSize) if err == nil { @@ -79,18 +91,28 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue, } } } + if data == "" { + return nil, nil + } rules, _ := issues_model.GetCodeOwnersFromContent(ctx, data) + if len(rules) == 0 { + return nil, nil + } - // get the mergebase - mergeBase, err := getMergeBase(repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName()) - if err != nil { - return nil, err + if startCommitID == "" && endCommitID == "" { + // get the mergebase + mergeBase, err := getMergeBase(repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName()) + if err != nil { + return nil, err + } + startCommitID = mergeBase + endCommitID = pr.GetGitRefName() } // https://github.com/go-gitea/gitea/issues/29763, we need to get the files changed // between the merge base and the head commit but not the base branch and the head commit - changedFiles, err := repo.GetFilesChangedBetween(mergeBase, pr.GetGitRefName()) + changedFiles, err := repo.GetFilesChangedBetween(startCommitID, endCommitID) if err != nil { return nil, err } diff --git a/services/pull/merge.go b/services/pull/merge.go index 665909e99a..1e1ca55bc1 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -211,7 +211,15 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U } defer releaser() defer func() { - go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false, "", "") + go AddTestPullRequestTask(TestPullRequestOptions{ + RepoID: pr.BaseRepo.ID, + Doer: doer, + Branch: pr.BaseBranch, + IsSync: false, + IsForcePush: false, + OldCommitID: "", + NewCommitID: "", + }) }() _, err = doMergeAndPush(ctx, pr, doer, mergeStyle, expectedHeadCommitID, message, repo_module.PushTriggerPRMergeToBase) diff --git a/services/pull/pull.go b/services/pull/pull.go index 1f06d6b182..21f31e16cf 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -176,7 +176,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error { } if !pr.IsWorkInProgress(ctx) { - reviewNotifiers, err = issue_service.PullRequestCodeOwnersReview(ctx, issue, pr) + reviewNotifiers, err = issue_service.PullRequestCodeOwnersReview(ctx, pr) if err != nil { return err } @@ -372,19 +372,29 @@ func checkForInvalidation(ctx context.Context, requests issues_model.PullRequest return nil } +type TestPullRequestOptions struct { + RepoID int64 + Doer *user_model.User + Branch string + IsSync bool // True means it's a pull request synchronization, false means it's triggered for pull request merging or updating + IsForcePush bool + OldCommitID string + NewCommitID string +} + // AddTestPullRequestTask adds new test tasks by given head/base repository and head/base branch, // and generate new patch for testing as needed. -func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, isSync bool, oldCommitID, newCommitID string) { - log.Trace("AddTestPullRequestTask [head_repo_id: %d, head_branch: %s]: finding pull requests", repoID, branch) +func AddTestPullRequestTask(opts TestPullRequestOptions) { + log.Trace("AddTestPullRequestTask [head_repo_id: %d, head_branch: %s]: finding pull requests", opts.RepoID, opts.Branch) graceful.GetManager().RunWithShutdownContext(func(ctx context.Context) { // There is no sensible way to shut this down ":-(" // If you don't let it run all the way then you will lose data // TODO: graceful: AddTestPullRequestTask needs to become a queue! // GetUnmergedPullRequestsByHeadInfo() only return open and unmerged PR. - prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(ctx, repoID, branch) + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(ctx, opts.RepoID, opts.Branch) if err != nil { - log.Error("Find pull requests [head_repo_id: %d, head_branch: %s]: %v", repoID, branch, err) + log.Error("Find pull requests [head_repo_id: %d, head_branch: %s]: %v", opts.RepoID, opts.Branch, err) return } @@ -400,24 +410,24 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, } AddToTaskQueue(ctx, pr) - comment, err := CreatePushPullComment(ctx, doer, pr, oldCommitID, newCommitID) + comment, err := CreatePushPullComment(ctx, opts.Doer, pr, opts.OldCommitID, opts.NewCommitID) if err == nil && comment != nil { - notify_service.PullRequestPushCommits(ctx, doer, pr, comment) + notify_service.PullRequestPushCommits(ctx, opts.Doer, pr, comment) } } - if isSync { + if opts.IsSync { if err = prs.LoadAttributes(ctx); err != nil { log.Error("PullRequestList.LoadAttributes: %v", err) } - if invalidationErr := checkForInvalidation(ctx, prs, repoID, doer, branch); invalidationErr != nil { + if invalidationErr := checkForInvalidation(ctx, prs, opts.RepoID, opts.Doer, opts.Branch); invalidationErr != nil { log.Error("checkForInvalidation: %v", invalidationErr) } if err == nil { for _, pr := range prs { objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName) - if newCommitID != "" && newCommitID != objectFormat.EmptyObjectID().String() { - changed, err := checkIfPRContentChanged(ctx, pr, oldCommitID, newCommitID) + if opts.NewCommitID != "" && opts.NewCommitID != objectFormat.EmptyObjectID().String() { + changed, err := checkIfPRContentChanged(ctx, pr, opts.OldCommitID, opts.NewCommitID) if err != nil { log.Error("checkIfPRContentChanged: %v", err) } @@ -433,12 +443,12 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, log.Error("GetFirstMatchProtectedBranchRule: %v", err) } if pb != nil && pb.DismissStaleApprovals { - if err := DismissApprovalReviews(ctx, doer, pr); err != nil { + if err := DismissApprovalReviews(ctx, opts.Doer, pr); err != nil { log.Error("DismissApprovalReviews: %v", err) } } } - if err := issues_model.MarkReviewsAsNotStale(ctx, pr.IssueID, newCommitID); err != nil { + if err := issues_model.MarkReviewsAsNotStale(ctx, pr.IssueID, opts.NewCommitID); err != nil { log.Error("MarkReviewsAsNotStale: %v", err) } divergence, err := GetDiverging(ctx, pr) @@ -452,15 +462,30 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, } } - notify_service.PullRequestSynchronized(ctx, doer, pr) + if !pr.IsWorkInProgress(ctx) { + var reviewNotifiers []*issue_service.ReviewRequestNotifier + if opts.IsForcePush { + reviewNotifiers, err = issue_service.PullRequestCodeOwnersReview(ctx, pr) + } else { + reviewNotifiers, err = issue_service.PullRequestCodeOwnersReviewSpecialCommits(ctx, pr, opts.OldCommitID, opts.NewCommitID) + } + if err != nil { + log.Error("PullRequestCodeOwnersReview: %v", err) + } + if len(reviewNotifiers) > 0 { + issue_service.ReviewRequestNotify(ctx, pr.Issue, opts.Doer, reviewNotifiers) + } + } + + notify_service.PullRequestSynchronized(ctx, opts.Doer, pr) } } } - log.Trace("AddTestPullRequestTask [base_repo_id: %d, base_branch: %s]: finding pull requests", repoID, branch) - prs, err = issues_model.GetUnmergedPullRequestsByBaseInfo(ctx, repoID, branch) + log.Trace("AddTestPullRequestTask [base_repo_id: %d, base_branch: %s]: finding pull requests", opts.RepoID, opts.Branch) + prs, err = issues_model.GetUnmergedPullRequestsByBaseInfo(ctx, opts.RepoID, opts.Branch) if err != nil { - log.Error("Find pull requests [base_repo_id: %d, base_branch: %s]: %v", repoID, branch, err) + log.Error("Find pull requests [base_repo_id: %d, base_branch: %s]: %v", opts.RepoID, opts.Branch, err) return } for _, pr := range prs { diff --git a/services/pull/update.go b/services/pull/update.go index abf7ad4509..3e00dd4e65 100644 --- a/services/pull/update.go +++ b/services/pull/update.go @@ -42,7 +42,15 @@ func Update(ctx context.Context, pr *issues_model.PullRequest, doer *user_model. if rebase { defer func() { - go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false, "", "") + go AddTestPullRequestTask(TestPullRequestOptions{ + RepoID: pr.BaseRepo.ID, + Doer: doer, + Branch: pr.BaseBranch, + IsSync: false, + IsForcePush: false, + OldCommitID: "", + NewCommitID: "", + }) }() return updateHeadByRebaseOnToBase(ctx, pr, doer) @@ -83,7 +91,15 @@ func Update(ctx context.Context, pr *issues_model.PullRequest, doer *user_model. _, err = doMergeAndPush(ctx, reversePR, doer, repo_model.MergeStyleMerge, "", message, repository.PushTriggerPRUpdateWithBase) defer func() { - go AddTestPullRequestTask(doer, reversePR.HeadRepo.ID, reversePR.HeadBranch, false, "", "") + go AddTestPullRequestTask(TestPullRequestOptions{ + RepoID: reversePR.HeadRepo.ID, + Doer: doer, + Branch: reversePR.HeadBranch, + IsSync: false, + IsForcePush: false, + OldCommitID: "", + NewCommitID: "", + }) }() return err diff --git a/services/repository/push.go b/services/repository/push.go index 0ea51f9c07..00d4fb11af 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -166,7 +166,6 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { branch := opts.RefFullName.BranchName() if !opts.IsDelRef() { log.Trace("TriggerTask '%s/%s' by %s", repo.Name, branch, pusher.Name) - go pull_service.AddTestPullRequestTask(pusher, repo.ID, branch, true, opts.OldCommitID, opts.NewCommitID) newCommit, err := gitRepo.GetCommit(opts.NewCommitID) if err != nil { @@ -208,6 +207,17 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { log.Error("IsForcePush %s:%s failed: %v", repo.FullName(), branch, err) } + // only update branch can trigger pull request task because the pull request hasn't been created yet when creaing a branch + go pull_service.AddTestPullRequestTask(pull_service.TestPullRequestOptions{ + RepoID: repo.ID, + Doer: pusher, + Branch: branch, + IsSync: true, + IsForcePush: isForcePush, + OldCommitID: opts.OldCommitID, + NewCommitID: opts.NewCommitID, + }) + if isForcePush { log.Trace("Push %s is a force push", opts.NewCommitID) diff --git a/tests/integration/pull_review_test.go b/tests/integration/pull_review_test.go index 68de421413..cd354e1b6c 100644 --- a/tests/integration/pull_review_test.go +++ b/tests/integration/pull_review_test.go @@ -8,6 +8,7 @@ import ( "net/http/httptest" "net/url" "path" + "sort" "strings" "testing" @@ -67,7 +68,7 @@ func TestPullView_CodeOwner(t *testing.T) { { Operation: "create", TreePath: "CODEOWNERS", - ContentReader: strings.NewReader("README.md @user5\n"), + ContentReader: strings.NewReader("README.md @user5\nuser8-file.md @user8\n"), }, }, }) @@ -75,7 +76,7 @@ func TestPullView_CodeOwner(t *testing.T) { t.Run("First Pull Request", func(t *testing.T) { // create a new branch to prepare for pull request - _, err = files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ + resp1, err := files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ NewBranch: "codeowner-basebranch", Files: []*files_service.ChangeRepoFile{ { @@ -95,7 +96,37 @@ func TestPullView_CodeOwner(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.Review{IssueID: pr.IssueID, Type: issues_model.ReviewTypeRequest, ReviewerID: 5}) assert.NoError(t, pr.LoadIssue(db.DefaultContext)) - err := issue_service.ChangeTitle(db.DefaultContext, pr.Issue, user2, "[WIP] Test Pull Request") + reviewNotifiers, err := issue_service.PullRequestCodeOwnersReview(db.DefaultContext, pr) + assert.NoError(t, err) + assert.Len(t, reviewNotifiers, 1) + assert.EqualValues(t, 5, reviewNotifiers[0].Reviewer.ID) + + // update the file on the pr branch + resp2, err := files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ + OldBranch: "codeowner-basebranch", + Files: []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: "user8-file.md", + ContentReader: strings.NewReader("# This is a new project2\n"), + }, + }, + }) + assert.NoError(t, err) + + reviewNotifiers, err = issue_service.PullRequestCodeOwnersReview(db.DefaultContext, pr) + assert.NoError(t, err) + assert.Len(t, reviewNotifiers, 2) + reviewerIDs := []int64{reviewNotifiers[0].Reviewer.ID, reviewNotifiers[1].Reviewer.ID} + sort.Slice(reviewerIDs, func(i, j int) bool { return reviewerIDs[i] < reviewerIDs[j] }) + assert.EqualValues(t, []int64{5, 8}, reviewerIDs) + + reviewNotifiers, err = issue_service.PullRequestCodeOwnersReviewSpecialCommits(db.DefaultContext, pr, resp1.Commit.SHA, resp2.Commit.SHA) + assert.NoError(t, err) + assert.Len(t, reviewNotifiers, 1) + assert.EqualValues(t, 8, reviewNotifiers[0].Reviewer.ID) + + err = issue_service.ChangeTitle(db.DefaultContext, pr.Issue, user2, "[WIP] Test Pull Request") assert.NoError(t, err) prUpdated1 := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) assert.NoError(t, prUpdated1.LoadIssue(db.DefaultContext)) @@ -140,6 +171,11 @@ func TestPullView_CodeOwner(t *testing.T) { pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{BaseRepoID: repo.ID, HeadBranch: "codeowner-basebranch2"}) unittest.AssertExistsAndLoadBean(t, &issues_model.Review{IssueID: pr.IssueID, Type: issues_model.ReviewTypeRequest, ReviewerID: 8}) + + reviewNotifiers, err := issue_service.PullRequestCodeOwnersReview(db.DefaultContext, pr) + assert.NoError(t, err) + assert.Len(t, reviewNotifiers, 1) + assert.EqualValues(t, 8, reviewNotifiers[0].Reviewer.ID) }) t.Run("Forked Repo Pull Request", func(t *testing.T) { From 9c673d066c2018e70e3eb0532af630fff2fc5b7a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 13 Mar 2025 20:00:56 -0700 Subject: [PATCH 217/655] Add abstraction layer to check if the repository exists on disk (#33874) Extract from #28966 This PR uses `gitrepo.IsRepositoryExist` instead of `util.IsExist` to detect whether the repository exist in disk. This will move `RepoPath` detail behind of package `gitrepo` to make it easier to do possible changes where storing the repositories. No code change --- modules/gitrepo/gitrepo.go | 5 +++++ modules/repository/init.go | 16 ++++++++-------- services/repository/adopt.go | 20 +++++++++---------- services/repository/create.go | 34 ++++++++++++++++----------------- services/repository/fork.go | 6 ++---- services/repository/generate.go | 11 +++++------ 6 files changed, 45 insertions(+), 47 deletions(-) diff --git a/modules/gitrepo/gitrepo.go b/modules/gitrepo/gitrepo.go index 540b724489..c3b412fd83 100644 --- a/modules/gitrepo/gitrepo.go +++ b/modules/gitrepo/gitrepo.go @@ -69,3 +69,8 @@ func RepositoryFromRequestContextOrOpen(ctx reqctx.RequestContext, repo Reposito ctx.SetContextValue(ck, gitRepo) return gitRepo, nil } + +// IsRepositoryExist returns true if the repository directory exists in the disk +func IsRepositoryExist(ctx context.Context, repo Repository) (bool, error) { + return util.IsExist(repoPath(repo)) +} diff --git a/modules/repository/init.go b/modules/repository/init.go index 24602ae090..772ae3efe3 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -13,6 +13,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/gitrepo" "code.gitea.io/gitea/modules/label" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/options" @@ -120,25 +121,24 @@ func LoadRepoConfig() error { return nil } -func CheckInitRepository(ctx context.Context, owner, name, objectFormatName string) (err error) { +func CheckInitRepository(ctx context.Context, repo *repo_model.Repository) (err error) { // Somehow the directory could exist. - repoPath := repo_model.RepoPath(owner, name) - isExist, err := util.IsExist(repoPath) + isExist, err := gitrepo.IsRepositoryExist(ctx, repo) if err != nil { - log.Error("Unable to check if %s exists. Error: %v", repoPath, err) + log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) return err } if isExist { return repo_model.ErrRepoFilesAlreadyExist{ - Uname: owner, - Name: name, + Uname: repo.OwnerName, + Name: repo.Name, } } // Init git bare new repository. - if err = git.InitRepository(ctx, repoPath, true, objectFormatName); err != nil { + if err = git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormatName); err != nil { return fmt.Errorf("git.InitRepository: %w", err) - } else if err = CreateDelegateHooks(repoPath); err != nil { + } else if err = CreateDelegateHooks(repo.RepoPath()); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) } return nil diff --git a/services/repository/adopt.go b/services/repository/adopt.go index 40a1327e5e..729441c9f1 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -52,12 +52,10 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR IsEmpty: !opts.AutoInit, } - repoPath := repo_model.RepoPath(u.Name, repo.Name) - if err := db.WithTx(ctx, func(ctx context.Context) error { - isExist, err := util.IsExist(repoPath) + isExist, err := gitrepo.IsRepositoryExist(ctx, repo) if err != nil { - log.Error("Unable to check if %s exists. Error: %v", repoPath, err) + log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) return err } if !isExist { @@ -82,7 +80,7 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR } if err := func() error { - if err := adoptRepository(ctx, repoPath, repo, opts.DefaultBranch); err != nil { + if err := adoptRepository(ctx, repo, opts.DefaultBranch); err != nil { return fmt.Errorf("adoptRepository: %w", err) } @@ -91,7 +89,7 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR } if stdout, _, err := git.NewCommand("update-server-info"). - RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { + RunStdString(ctx, &git.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) } @@ -107,17 +105,17 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts CreateR return repo, nil } -func adoptRepository(ctx context.Context, repoPath string, repo *repo_model.Repository, defaultBranch string) (err error) { - isExist, err := util.IsExist(repoPath) +func adoptRepository(ctx context.Context, repo *repo_model.Repository, defaultBranch string) (err error) { + isExist, err := gitrepo.IsRepositoryExist(ctx, repo) if err != nil { - log.Error("Unable to check if %s exists. Error: %v", repoPath, err) + log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) return err } if !isExist { - return fmt.Errorf("adoptRepository: path does not already exist: %s", repoPath) + return fmt.Errorf("adoptRepository: path does not already exist: %s", repo.FullName()) } - if err := repo_module.CreateDelegateHooks(repoPath); err != nil { + if err := repo_module.CreateDelegateHooks(repo.RepoPath()); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) } diff --git a/services/repository/create.go b/services/repository/create.go index aa4c3905d4..62b5931fd9 100644 --- a/services/repository/create.go +++ b/services/repository/create.go @@ -52,7 +52,7 @@ type CreateRepoOptions struct { ObjectFormatName string } -func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { +func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir string, opts CreateRepoOptions) error { commitTimeStr := time.Now().Format(time.RFC3339) authorSig := repo.Owner.NewGitSig() @@ -67,7 +67,7 @@ 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(repoPath, tmpDir). + if stdout, _, err := git.NewCommand("clone").AddDynamicArguments(repo.RepoPath(), tmpDir). RunStdString(ctx, &git.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) @@ -139,8 +139,8 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, } // InitRepository initializes README and .gitignore if needed. -func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { - if err = repo_module.CheckInitRepository(ctx, repo.OwnerName, repo.Name, opts.ObjectFormatName); err != nil { +func initRepository(ctx context.Context, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { + if err = repo_module.CheckInitRepository(ctx, repo); err != nil { return err } @@ -148,7 +148,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re if opts.AutoInit { tmpDir, err := os.MkdirTemp(os.TempDir(), "gitea-"+repo.Name) if err != nil { - return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.RepoPath(), err) + return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.FullName(), err) } defer func() { if err := util.RemoveAll(tmpDir); err != nil { @@ -156,7 +156,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re } }() - if err = prepareRepoCommit(ctx, repo, tmpDir, repoPath, opts); err != nil { + if err = prepareRepoCommit(ctx, repo, tmpDir, opts); err != nil { return fmt.Errorf("prepareRepoCommit: %w", err) } @@ -256,10 +256,9 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt return nil } - repoPath := repo_model.RepoPath(u.Name, repo.Name) - isExist, err := util.IsExist(repoPath) + isExist, err := gitrepo.IsRepositoryExist(ctx, repo) if err != nil { - log.Error("Unable to check if %s exists. Error: %v", repoPath, err) + log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) return err } if isExist { @@ -270,15 +269,15 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt // // Previously Gitea would just delete and start afresh - this was naughty. // So we will now fail and delegate to other functionality to adopt or delete - log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) + log.Error("Files already exist in %s and we are not going to adopt or delete.", repo.FullName()) return repo_model.ErrRepoFilesAlreadyExist{ Uname: u.Name, Name: repo.Name, } } - if err = initRepository(ctx, repoPath, doer, repo, opts); err != nil { - if err2 := util.RemoveAll(repoPath); err2 != nil { + if err = initRepository(ctx, doer, repo, opts); err != nil { + if err2 := util.RemoveAll(repo.RepoPath()); err2 != nil { log.Error("initRepository: %v", err) return fmt.Errorf( "delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2) @@ -300,7 +299,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt } if stdout, _, err := git.NewCommand("update-server-info"). - RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { + RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}); err != nil { log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) rollbackRepo = repo rollbackRepo.OwnerID = u.ID @@ -312,7 +311,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt if len(opts.License) > 0 { licenses = append(licenses, opts.License) - stdout, _, err := git.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repoPath}) + stdout, _, err := git.NewCommand("rev-parse", "HEAD").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()}) if err != nil { log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err) rollbackRepo = repo @@ -353,14 +352,13 @@ func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, re } } - repoPath := repo_model.RepoPath(u.Name, repo.Name) - isExist, err := util.IsExist(repoPath) + isExist, err := gitrepo.IsRepositoryExist(ctx, repo) if err != nil { - log.Error("Unable to check if %s exists. Error: %v", repoPath, err) + log.Error("Unable to check if %s exists. Error: %v", repo.FullName(), err) return err } if !overwriteOrAdopt && isExist { - log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) + log.Error("Files already exist in %s and we are not going to adopt or delete.", repo.FullName()) return repo_model.ErrRepoFilesAlreadyExist{ Uname: u.Name, Name: repo.Name, diff --git a/services/repository/fork.go b/services/repository/fork.go index a79dc62ef1..1bd4d4a13b 100644 --- a/services/repository/fork.go +++ b/services/repository/fork.go @@ -110,15 +110,13 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork return } - repoPath := repo_model.RepoPath(owner.Name, repo.Name) - - if exists, _ := util.IsExist(repoPath); !exists { + if exists, _ := gitrepo.IsRepositoryExist(ctx, repo); !exists { return } // As the transaction will be failed and hence database changes will be destroyed we only need // to delete the related repository on the filesystem - if errDelete := util.RemoveAll(repoPath); errDelete != nil { + if errDelete := util.RemoveAll(repo.RepoPath()); errDelete != nil { log.Error("Failed to remove fork repo") } } diff --git a/services/repository/generate.go b/services/repository/generate.go index a47ab7db53..9d2bbb1f7f 100644 --- a/services/repository/generate.go +++ b/services/repository/generate.go @@ -258,7 +258,7 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository) (err error) { tmpDir, err := os.MkdirTemp(os.TempDir(), "gitea-"+repo.Name) if err != nil { - return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.RepoPath(), err) + return fmt.Errorf("Failed to create temp dir for repository %s: %w", repo.FullName(), err) } defer func() { @@ -350,10 +350,9 @@ func generateRepository(ctx context.Context, doer, owner *user_model.User, templ return nil, err } - repoPath := generateRepo.RepoPath() - isExist, err := util.IsExist(repoPath) + isExist, err := gitrepo.IsRepositoryExist(ctx, generateRepo) if err != nil { - log.Error("Unable to check if %s exists. Error: %v", repoPath, err) + log.Error("Unable to check if %s exists. Error: %v", generateRepo.FullName(), err) return nil, err } if isExist { @@ -363,7 +362,7 @@ func generateRepository(ctx context.Context, doer, owner *user_model.User, templ } } - if err = repo_module.CheckInitRepository(ctx, owner.Name, generateRepo.Name, generateRepo.ObjectFormatName); err != nil { + if err = repo_module.CheckInitRepository(ctx, generateRepo); err != nil { return generateRepo, err } @@ -372,7 +371,7 @@ func generateRepository(ctx context.Context, doer, owner *user_model.User, templ } if stdout, _, err := git.NewCommand("update-server-info"). - RunStdString(ctx, &git.RunOpts{Dir: repoPath}); err != nil { + RunStdString(ctx, &git.RunOpts{Dir: generateRepo.RepoPath()}); err != nil { log.Error("GenerateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", generateRepo, stdout, err) return generateRepo, fmt.Errorf("error in GenerateRepository(git update-server-info): %w", err) } From b094f9b75d000aa9a78194b2c14e04318d498ff2 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 14 Mar 2025 15:45:11 +0800 Subject: [PATCH 218/655] Improve repo commit view (#33877) Fix #24623 Major changes: 1. Redirect `/owner/repo/blob/*` requests to `/owner/repo/src/commit/*` (like GitHub) 2. Add a "view file diff" link (see screenshot below) 3. Refactor "AssertHTMLElement" to generic, now we can accurately assert existence or number. 4. Add more tests --------- Co-authored-by: silverwind Co-authored-by: delvh --- options/locale/locale_en-US.ini | 1 + routers/web/repo/view_home.go | 11 ++++++ routers/web/web.go | 3 +- templates/repo/commits_list.tmpl | 15 ++++++-- tests/integration/html_helper.go | 13 +++---- tests/integration/links_test.go | 1 + tests/integration/oauth_test.go | 2 +- tests/integration/signin_test.go | 18 ++++++---- tests/integration/timetracking_test.go | 8 ++--- tests/integration/user_settings_test.go | 48 ++++++++++++------------- tests/integration/user_test.go | 2 +- tests/integration/view_test.go | 40 +++++++++++++++++++++ 12 files changed, 116 insertions(+), 46 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 036f8e5389..f1ce4b244f 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1407,6 +1407,7 @@ commits.signed_by_untrusted_user_unmatched = Signed by untrusted user who does n commits.gpg_key_id = GPG Key ID commits.ssh_key_fingerprint = SSH Key Fingerprint commits.view_path=View at this point in history +commits.view_file_diff = View changes to this file in this commit commit.operations = Operations commit.revert = Revert diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index e7255cde0a..1da89686ad 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -429,3 +429,14 @@ func RedirectRepoTreeToSrc(ctx *context.Context) { } ctx.Redirect(redirect) } + +func RedirectRepoBlobToCommit(ctx *context.Context) { + // redirect "/owner/repo/blob/*" requests to "/owner/repo/src/commit/*" + // just like GitHub: browse files of a commit by "https://github/owner/repo/blob/{CommitID}" + // TODO: maybe we could guess more types to redirect to the related pages in the future + redirect := ctx.Repo.RepoLink + "/src/commit/" + ctx.PathParamRaw("*") + if ctx.Req.URL.RawQuery != "" { + redirect += "?" + ctx.Req.URL.RawQuery + } + ctx.Redirect(redirect) +} diff --git a/routers/web/web.go b/routers/web/web.go index 3144cb26b2..1223d56c92 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1595,7 +1595,8 @@ func registerRoutes(m *web.Router) { m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.Home) m.Get("/*", context.RepoRefByType(""), repo.Home) // "/*" route is deprecated, and kept for backward compatibility }, repo.SetEditorconfigIfExists) - m.Get("/tree/*", repo.RedirectRepoTreeToSrc) // redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*" + m.Get("/tree/*", repo.RedirectRepoTreeToSrc) // redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*" + m.Get("/blob/*", repo.RedirectRepoBlobToCommit) // redirect "/owner/repo/blob/*" requests to "/owner/repo/src/commit/*" m.Get("/forks", context.RepoRef(), repo.Forks) m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff) diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index c8405ca748..dc800d9911 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -66,11 +66,20 @@ {{DateUtils.TimeSince .Author.When}} {{end}} - - {{if not $.PageIsWiki}}{{/* at the moment, wiki doesn't support "view at history point*/}} + + {{/* at the moment, wiki doesn't support these "view" links like "view at history point" */}} + {{if not $.PageIsWiki}} + {{/* view single file diff */}} + {{if $.FileName}} + {{svg "octicon-file-diff"}} + {{end}} + + {{/* view at history point */}} {{$viewCommitLink := printf "%s/src/commit/%s" $commitRepoLink (PathEscape .ID.String)}} {{if $.FileName}}{{$viewCommitLink = printf "%s/%s" $viewCommitLink (PathEscapeSegments $.FileName)}}{{end}} - {{svg "octicon-file-code"}} + {{svg "octicon-file-code"}} {{end}} diff --git a/tests/integration/html_helper.go b/tests/integration/html_helper.go index 2217ddec2e..874fc32228 100644 --- a/tests/integration/html_helper.go +++ b/tests/integration/html_helper.go @@ -42,12 +42,13 @@ func (doc *HTMLDoc) GetCSRF() string { return doc.GetInputValueByName("_csrf") } -// AssertElement check if element by selector exists or does not exist depending on checkExists -func (doc *HTMLDoc) AssertElement(t testing.TB, selector string, checkExists bool) { +// AssertHTMLElement check if element by selector exists or does not exist depending on checkExists +func AssertHTMLElement[T int | bool](t testing.TB, doc *HTMLDoc, selector string, checkExists T) { sel := doc.doc.Find(selector) - if checkExists { - assert.Equal(t, 1, sel.Length()) - } else { - assert.Equal(t, 0, sel.Length()) + switch v := any(checkExists).(type) { + case bool: + assert.Equal(t, v, sel.Length() > 0) + case int: + assert.Equal(t, v, sel.Length()) } } diff --git a/tests/integration/links_test.go b/tests/integration/links_test.go index 1bfb3b83d2..6573a47ccc 100644 --- a/tests/integration/links_test.go +++ b/tests/integration/links_test.go @@ -55,6 +55,7 @@ func TestRedirectsNoLogin(t *testing.T) { {"/user2/repo1/src/master/a%2fb.txt", "/user2/repo1/src/branch/master/a%2fb.txt"}, {"/user2/repo1/src/master/directory/file.txt?a=1", "/user2/repo1/src/branch/master/directory/file.txt?a=1"}, {"/user2/repo1/tree/a%2fb?a=1", "/user2/repo1/src/a%2fb?a=1"}, + {"/user2/repo1/blob/123456/%20?a=1", "/user2/repo1/src/commit/123456/%20?a=1"}, {"/user/avatar/GhosT/-1", "/assets/img/avatar_default.png"}, {"/user/avatar/Gitea-ActionS/0", "/assets/img/avatar_default.png"}, {"/api/v1/swagger", "/api/swagger"}, diff --git a/tests/integration/oauth_test.go b/tests/integration/oauth_test.go index 0766a9fc8a..d7ef103506 100644 --- a/tests/integration/oauth_test.go +++ b/tests/integration/oauth_test.go @@ -77,7 +77,7 @@ func TestAuthorizeShow(t *testing.T) { resp := ctx.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) - htmlDoc.AssertElement(t, "#authorize-app", true) + AssertHTMLElement(t, htmlDoc, "#authorize-app", true) htmlDoc.GetCSRF() } diff --git a/tests/integration/signin_test.go b/tests/integration/signin_test.go index 6738d998d7..5c7555286e 100644 --- a/tests/integration/signin_test.go +++ b/tests/integration/signin_test.go @@ -112,7 +112,8 @@ func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) { req := NewRequest(t, "GET", "/user/login") resp := MakeRequest(t, req, http.StatusOK) - NewHTMLParser(t, resp.Body).AssertElement(t, "form[action='/user/login']", false) + doc := NewHTMLParser(t, resp.Body) + AssertHTMLElement(t, doc, "form[action='/user/login']", false) req = NewRequest(t, "POST", "/user/login") MakeRequest(t, req, http.StatusForbidden) @@ -121,7 +122,8 @@ func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) { defer web.RouteMockReset() web.RouteMock(web.MockAfterMiddlewares, mockLinkAccount) resp = MakeRequest(t, req, http.StatusOK) - NewHTMLParser(t, resp.Body).AssertElement(t, "form[action='/user/link_account_signin']", false) + doc = NewHTMLParser(t, resp.Body) + AssertHTMLElement(t, doc, "form[action='/user/link_account_signin']", false) }) t.Run("EnablePasswordSignInForm=true", func(t *testing.T) { @@ -130,7 +132,8 @@ func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) { req := NewRequest(t, "GET", "/user/login") resp := MakeRequest(t, req, http.StatusOK) - NewHTMLParser(t, resp.Body).AssertElement(t, "form[action='/user/login']", true) + doc := NewHTMLParser(t, resp.Body) + AssertHTMLElement(t, doc, "form[action='/user/login']", true) req = NewRequest(t, "POST", "/user/login") MakeRequest(t, req, http.StatusOK) @@ -139,7 +142,8 @@ func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) { defer web.RouteMockReset() web.RouteMock(web.MockAfterMiddlewares, mockLinkAccount) resp = MakeRequest(t, req, http.StatusOK) - NewHTMLParser(t, resp.Body).AssertElement(t, "form[action='/user/link_account_signin']", true) + doc = NewHTMLParser(t, resp.Body) + AssertHTMLElement(t, doc, "form[action='/user/link_account_signin']", true) }) t.Run("EnablePasskeyAuth=false", func(t *testing.T) { @@ -148,7 +152,8 @@ func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) { req := NewRequest(t, "GET", "/user/login") resp := MakeRequest(t, req, http.StatusOK) - NewHTMLParser(t, resp.Body).AssertElement(t, ".signin-passkey", false) + doc := NewHTMLParser(t, resp.Body) + AssertHTMLElement(t, doc, ".signin-passkey", false) }) t.Run("EnablePasskeyAuth=true", func(t *testing.T) { @@ -157,6 +162,7 @@ func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) { req := NewRequest(t, "GET", "/user/login") resp := MakeRequest(t, req, http.StatusOK) - NewHTMLParser(t, resp.Body).AssertElement(t, ".signin-passkey", true) + doc := NewHTMLParser(t, resp.Body) + AssertHTMLElement(t, doc, ".signin-passkey", true) }) } diff --git a/tests/integration/timetracking_test.go b/tests/integration/timetracking_test.go index d459de5df6..8985dfdbce 100644 --- a/tests/integration/timetracking_test.go +++ b/tests/integration/timetracking_test.go @@ -42,8 +42,8 @@ func testViewTimetrackingControls(t *testing.T, session *TestSession, user, repo htmlDoc := NewHTMLParser(t, resp.Body) - htmlDoc.AssertElement(t, ".issue-start-time", canTrackTime) - htmlDoc.AssertElement(t, ".issue-add-time", canTrackTime) + AssertHTMLElement(t, htmlDoc, ".issue-start-time", canTrackTime) + AssertHTMLElement(t, htmlDoc, ".issue-add-time", canTrackTime) issueLink := path.Join(user, repo, "issues", issue) req = NewRequestWithValues(t, "POST", path.Join(issueLink, "times", "stopwatch", "toggle"), map[string]string{ @@ -59,8 +59,8 @@ func testViewTimetrackingControls(t *testing.T, session *TestSession, user, repo events := htmlDoc.doc.Find(".event > span.text") assert.Contains(t, events.Last().Text(), "started working") - htmlDoc.AssertElement(t, ".issue-stop-time", true) - htmlDoc.AssertElement(t, ".issue-cancel-time", true) + AssertHTMLElement(t, htmlDoc, ".issue-stop-time", true) + AssertHTMLElement(t, htmlDoc, ".issue-cancel-time", true) // Sleep for 1 second to not get wrong order for stopping timer time.Sleep(time.Second) diff --git a/tests/integration/user_settings_test.go b/tests/integration/user_settings_test.go index d8402eb25f..eab1a72ed5 100644 --- a/tests/integration/user_settings_test.go +++ b/tests/integration/user_settings_test.go @@ -19,21 +19,21 @@ import ( func assertNavbar(t *testing.T, doc *HTMLDoc) { // Only show the account page if users can change their email notifications, delete themselves, or manage credentials if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureDeletion, setting.UserFeatureManageCredentials) && !setting.Service.EnableNotifyMail { - doc.AssertElement(t, ".menu a[href='/user/settings/account']", false) + AssertHTMLElement(t, doc, ".menu a[href='/user/settings/account']", false) } else { - doc.AssertElement(t, ".menu a[href='/user/settings/account']", true) + AssertHTMLElement(t, doc, ".menu a[href='/user/settings/account']", true) } if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageMFA, setting.UserFeatureManageCredentials) { - doc.AssertElement(t, ".menu a[href='/user/settings/security']", false) + AssertHTMLElement(t, doc, ".menu a[href='/user/settings/security']", false) } else { - doc.AssertElement(t, ".menu a[href='/user/settings/security']", true) + AssertHTMLElement(t, doc, ".menu a[href='/user/settings/security']", true) } if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys, setting.UserFeatureManageGPGKeys) { - doc.AssertElement(t, ".menu a[href='/user/settings/keys']", false) + AssertHTMLElement(t, doc, ".menu a[href='/user/settings/keys']", false) } else { - doc.AssertElement(t, ".menu a[href='/user/settings/keys']", true) + AssertHTMLElement(t, doc, ".menu a[href='/user/settings/keys']", true) } } @@ -64,11 +64,11 @@ func TestUserSettingsAccount(t *testing.T) { doc := NewHTMLParser(t, resp.Body) // account navbar should display - doc.AssertElement(t, ".menu a[href='/user/settings/account']", true) + AssertHTMLElement(t, doc, ".menu a[href='/user/settings/account']", true) - doc.AssertElement(t, "#password", true) - doc.AssertElement(t, "#email", true) - doc.AssertElement(t, "#delete-form", true) + AssertHTMLElement(t, doc, "#password", true) + AssertHTMLElement(t, doc, "#email", true) + AssertHTMLElement(t, doc, "#delete-form", true) }) t.Run("credentials disabled", func(t *testing.T) { @@ -83,9 +83,9 @@ func TestUserSettingsAccount(t *testing.T) { assertNavbar(t, doc) - doc.AssertElement(t, "#password", false) - doc.AssertElement(t, "#email", false) - doc.AssertElement(t, "#delete-form", true) + AssertHTMLElement(t, doc, "#password", false) + AssertHTMLElement(t, doc, "#email", false) + AssertHTMLElement(t, doc, "#delete-form", true) }) t.Run("deletion disabled", func(t *testing.T) { @@ -100,9 +100,9 @@ func TestUserSettingsAccount(t *testing.T) { assertNavbar(t, doc) - doc.AssertElement(t, "#password", true) - doc.AssertElement(t, "#email", true) - doc.AssertElement(t, "#delete-form", false) + AssertHTMLElement(t, doc, "#password", true) + AssertHTMLElement(t, doc, "#email", true) + AssertHTMLElement(t, doc, "#delete-form", false) }) t.Run("deletion, credentials and email notifications are disabled", func(t *testing.T) { @@ -249,7 +249,7 @@ func TestUserSettingsSecurity(t *testing.T) { assertNavbar(t, doc) - doc.AssertElement(t, "#register-webauthn", true) + AssertHTMLElement(t, doc, "#register-webauthn", true) }) t.Run("mfa disabled", func(t *testing.T) { @@ -263,7 +263,7 @@ func TestUserSettingsSecurity(t *testing.T) { assertNavbar(t, doc) - doc.AssertElement(t, "#register-webauthn", false) + AssertHTMLElement(t, doc, "#register-webauthn", false) }) t.Run("credentials and mfa disabled", func(t *testing.T) { @@ -356,8 +356,8 @@ func TestUserSettingsKeys(t *testing.T) { assertNavbar(t, doc) - doc.AssertElement(t, "#add-ssh-button", true) - doc.AssertElement(t, "#add-gpg-key-panel", true) + AssertHTMLElement(t, doc, "#add-ssh-button", true) + AssertHTMLElement(t, doc, "#add-gpg-key-panel", true) }) t.Run("ssh keys disabled", func(t *testing.T) { @@ -372,8 +372,8 @@ func TestUserSettingsKeys(t *testing.T) { assertNavbar(t, doc) - doc.AssertElement(t, "#add-ssh-button", false) - doc.AssertElement(t, "#add-gpg-key-panel", true) + AssertHTMLElement(t, doc, "#add-ssh-button", false) + AssertHTMLElement(t, doc, "#add-gpg-key-panel", true) }) t.Run("gpg keys disabled", func(t *testing.T) { @@ -388,8 +388,8 @@ func TestUserSettingsKeys(t *testing.T) { assertNavbar(t, doc) - doc.AssertElement(t, "#add-ssh-button", true) - doc.AssertElement(t, "#add-gpg-key-panel", false) + AssertHTMLElement(t, doc, "#add-ssh-button", true) + AssertHTMLElement(t, doc, "#add-gpg-key-panel", false) }) t.Run("ssh & gpg keys disabled", func(t *testing.T) { diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index bf248a4dde..fd7996bf8b 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -273,5 +273,5 @@ func TestUserLocationMapLink(t *testing.T) { req = NewRequest(t, "GET", "/user2/") resp := session.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) - htmlDoc.AssertElement(t, `a[href="https://example/foo/A%2Fb"]`, true) + AssertHTMLElement(t, htmlDoc, `a[href="https://example/foo/A%2Fb"]`, true) } diff --git a/tests/integration/view_test.go b/tests/integration/view_test.go index f434446801..9ed3e30857 100644 --- a/tests/integration/view_test.go +++ b/tests/integration/view_test.go @@ -25,3 +25,43 @@ func TestRenderFileSVGIsInImgTag(t *testing.T) { assert.True(t, exists, "The SVG image should be in an tag so that scripts in the SVG are not run") assert.Equal(t, "/user2/repo2/raw/branch/master/line.svg", src) } + +func TestCommitListActions(t *testing.T) { + defer tests.PrepareTestEnv(t)() + session := loginUser(t, "user2") + + t.Run("WikiRevisionList", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/user2/repo1/wiki/Home?action=_revision") + resp := session.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + AssertHTMLElement(t, htmlDoc, ".commit-list .copy-commit-id", true) + AssertHTMLElement(t, htmlDoc, `.commit-list .view-single-diff`, false) + AssertHTMLElement(t, htmlDoc, `.commit-list .view-commit-path`, false) + }) + + t.Run("RepoCommitList", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master") + resp := session.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + + AssertHTMLElement(t, htmlDoc, `.commit-list .copy-commit-id`, true) + AssertHTMLElement(t, htmlDoc, `.commit-list .view-single-diff`, false) + AssertHTMLElement(t, htmlDoc, `.commit-list .view-commit-path`, true) + }) + + t.Run("RepoFileHistory", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master/README.md") + resp := session.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + + AssertHTMLElement(t, htmlDoc, `.commit-list .copy-commit-id`, true) + AssertHTMLElement(t, htmlDoc, `.commit-list .view-single-diff`, true) + AssertHTMLElement(t, htmlDoc, `.commit-list .view-commit-path`, true) + }) +} From cb6b33c9cd1efa619351a458e2bce8ad1e6cd623 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 14 Mar 2025 16:36:39 +0800 Subject: [PATCH 219/655] Ignore trivial errors when updating push data (#33864) Fix #23213 --- services/gitdiff/gitdiff.go | 2 -- services/repository/push.go | 36 ++++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 53f50a018d..7208e1fb96 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -1443,10 +1443,8 @@ func GetWhitespaceFlag(whitespaceBehavior string) git.TrustedCmdArgs { "ignore-eol": {"--ignore-space-at-eol"}, "show-all": nil, } - if flag, ok := whitespaceFlags[whitespaceBehavior]; ok { return flag } - log.Warn("unknown whitespace behavior: %q, default to 'show-all'", whitespaceBehavior) return nil } diff --git a/services/repository/push.go b/services/repository/push.go index 00d4fb11af..c40333f0a8 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -23,6 +23,7 @@ import ( repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" issue_service "code.gitea.io/gitea/services/issue" notify_service "code.gitea.io/gitea/services/notify" pull_service "code.gitea.io/gitea/services/pull" @@ -133,23 +134,26 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } else { // is new tag newCommit, err := gitRepo.GetCommit(opts.NewCommitID) if err != nil { - return fmt.Errorf("gitRepo.GetCommit(%s) in %s/%s[%d]: %w", opts.NewCommitID, repo.OwnerName, repo.Name, repo.ID, err) + // in case there is dirty data, for example, the "github.com/git/git" repository has tags pointing to non-existing commits + if !errors.Is(err, util.ErrNotExist) { + log.Error("Unable to get tag commit: gitRepo.GetCommit(%s) in %s/%s[%d]: %v", opts.NewCommitID, repo.OwnerName, repo.Name, repo.ID, err) + } + } else { + commits := repo_module.NewPushCommits() + commits.HeadCommit = repo_module.CommitToPushCommit(newCommit) + commits.CompareURL = repo.ComposeCompareURL(objectFormat.EmptyObjectID().String(), opts.NewCommitID) + + notify_service.PushCommits( + ctx, pusher, repo, + &repo_module.PushUpdateOptions{ + RefFullName: opts.RefFullName, + OldCommitID: objectFormat.EmptyObjectID().String(), + NewCommitID: opts.NewCommitID, + }, commits) + + addTags = append(addTags, tagName) + notify_service.CreateRef(ctx, pusher, repo, opts.RefFullName, opts.NewCommitID) } - - commits := repo_module.NewPushCommits() - commits.HeadCommit = repo_module.CommitToPushCommit(newCommit) - commits.CompareURL = repo.ComposeCompareURL(objectFormat.EmptyObjectID().String(), opts.NewCommitID) - - notify_service.PushCommits( - ctx, pusher, repo, - &repo_module.PushUpdateOptions{ - RefFullName: opts.RefFullName, - OldCommitID: objectFormat.EmptyObjectID().String(), - NewCommitID: opts.NewCommitID, - }, commits) - - addTags = append(addTags, tagName) - notify_service.CreateRef(ctx, pusher, repo, opts.RefFullName, opts.NewCommitID) } } else if opts.RefFullName.IsBranch() { if pusher == nil || pusher.ID != opts.PusherID { From 0dfa94edc8476c4227d46557ed81825388fd37fb Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 14 Mar 2025 23:11:29 +0800 Subject: [PATCH 220/655] Add old svg class name to git entry icon (#33884) Fix https://github.com/go-gitea/gitea/pull/33837#discussion_r1995521288 --- modules/fileicon/material.go | 20 +++++++++++++++----- web_src/css/modules/svg.css | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/fileicon/material.go b/modules/fileicon/material.go index adea625c06..aa31cd8d7c 100644 --- a/modules/fileicon/material.go +++ b/modules/fileicon/material.go @@ -62,7 +62,7 @@ func (m *MaterialIconProvider) loadData() { log.Debug("Loaded material icon rules and SVG images") } -func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name, svg string) template.HTML { +func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name, svg, extraClass string) template.HTML { data := ctx.GetData() renderedSVGs, _ := data["_RenderedSVGs"].(map[string]bool) if renderedSVGs == nil { @@ -75,7 +75,7 @@ func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name panic("Invalid SVG icon") } svgID := "svg-mfi-" + name - svgCommonAttrs := `class="svg fileicon" width="16" height="16" aria-hidden="true"` + svgCommonAttrs := `class="svg git-entry-icon ` + extraClass + `" width="16" height="16" aria-hidden="true"` posOuterBefore := strings.IndexByte(svg, '>') if renderedSVGs[svgID] && posOuterBefore != -1 { return template.HTML(``) @@ -92,7 +92,8 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr if entry.IsLink() { if te, err := entry.FollowLink(); err == nil && te.IsDir() { - return svg.RenderHTML("material-folder-symlink") + // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work + return svg.RenderHTML("material-folder-symlink", 16, "octicon-file-directory-symlink") } return svg.RenderHTML("octicon-file-symlink-file") // TODO: find some better icons for them } @@ -100,10 +101,19 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr name := m.findIconNameByGit(entry) if name == "folder" { // the material icon pack's "folder" icon doesn't look good, so use our built-in one - return svg.RenderHTML("material-folder-generic") + // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work + return svg.RenderHTML("material-folder-generic", 16, "octicon-file-directory-fill") } if iconSVG, ok := m.svgs[name]; ok && iconSVG != "" { - return m.renderFileIconSVG(ctx, name, iconSVG) + // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work + extraClass := "octicon-file" + switch { + case entry.IsDir(): + extraClass = "octicon-file-directory-fill" + case entry.IsSubModule(): + extraClass = "octicon-file-submodule" + } + return m.renderFileIconSVG(ctx, name, iconSVG, extraClass) } return svg.RenderHTML("octicon-file") } diff --git a/web_src/css/modules/svg.css b/web_src/css/modules/svg.css index 432a321d59..738ec22cd3 100644 --- a/web_src/css/modules/svg.css +++ b/web_src/css/modules/svg.css @@ -4,7 +4,7 @@ fill: currentcolor; } -.svg.fileicon { +.svg.git-entry-icon { fill: transparent; /* some material icons have dark background fill, so need to reset */ } From 45c4139134cfdb23fbeb85bb5c78811605f37dd5 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 15 Mar 2025 01:35:40 +0800 Subject: [PATCH 221/655] Fix maven panic when no package exists (#33888) Fix #33886 Restore the old logic from #16510, which was incorrectly removed by #33678 --- routers/api/packages/maven/maven.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index 4f9ced25b4..9089c2eccf 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -98,6 +98,11 @@ func serveMavenMetadata(ctx *context.Context, params parameters) { } pvs = append(pvsLegacy, pvs...) + if len(pvs) == 0 { + apiError(ctx, http.StatusNotFound, packages_model.ErrPackageNotExist) + return + } + pds, err := packages_model.GetPackageDescriptors(ctx, pvs) if err != nil { apiError(ctx, http.StatusInternalServerError, err) From a0e0a30d23e0890538bbe8e9edc3c07ae5242bb1 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 15 Mar 2025 02:06:31 +0800 Subject: [PATCH 222/655] Make SearchMode have default value and add comments (#33863) * Make `SearchMode` have default value if it is empty * Add some comments for the "match" queries * Fix a copy-paste mistake in `buildMatchQuery` (`db.go`) * Add missing `q.Analyzer = repoIndexerAnalyzer`, it is in old code, although I do not see real difference .... --- modules/indexer/code/bleve/bleve.go | 9 +++++++-- modules/indexer/code/elasticsearch/elasticsearch.go | 5 ++++- modules/indexer/code/indexer_test.go | 3 ++- modules/indexer/issues/bleve/bleve.go | 6 ++++-- modules/indexer/issues/db/db.go | 11 ++++++----- modules/indexer/issues/elasticsearch/elasticsearch.go | 4 +++- modules/indexer/issues/indexer.go | 7 +++---- modules/indexer/issues/indexer_test.go | 8 +++++--- 8 files changed, 34 insertions(+), 19 deletions(-) diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index 52a934d4ff..e1a381f992 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/typesniffer" + "code.gitea.io/gitea/modules/util" "github.com/blevesearch/bleve/v2" analyzer_custom "github.com/blevesearch/bleve/v2/analysis/analyzer/custom" @@ -272,14 +273,18 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int pathQuery.FieldVal = "Filename" pathQuery.SetBoost(10) - if opts.SearchMode == indexer.SearchModeExact { + searchMode := util.IfZero(opts.SearchMode, b.SupportedSearchModes()[0].ModeValue) + if searchMode == indexer.SearchModeExact { + // 1.21 used NewPrefixQuery, but it seems not working well, and later releases changed to NewMatchPhraseQuery q := bleve.NewMatchPhraseQuery(opts.Keyword) + q.Analyzer = repoIndexerAnalyzer q.FieldVal = "Content" contentQuery = q } else /* words */ { q := bleve.NewMatchQuery(opts.Keyword) q.FieldVal = "Content" - if opts.SearchMode == indexer.SearchModeFuzzy { + q.Analyzer = repoIndexerAnalyzer + if searchMode == indexer.SearchModeFuzzy { // this logic doesn't seem right, it is only used to pass the test-case `Keyword: "dESCRIPTION"`, which doesn't seem to be a real-life use-case. q.Fuzziness = inner_bleve.GuessFuzzinessByKeyword(opts.Keyword) } else { diff --git a/modules/indexer/code/elasticsearch/elasticsearch.go b/modules/indexer/code/elasticsearch/elasticsearch.go index 354a8334fb..be8efad5fd 100644 --- a/modules/indexer/code/elasticsearch/elasticsearch.go +++ b/modules/indexer/code/elasticsearch/elasticsearch.go @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/typesniffer" + "code.gitea.io/gitea/modules/util" "github.com/go-enry/go-enry/v2" "github.com/olivere/elastic/v7" @@ -365,7 +366,9 @@ func extractAggs(searchResult *elastic.SearchResult) []*internal.SearchResultLan // Search searches for codes and language stats by given conditions. func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int64, []*internal.SearchResult, []*internal.SearchResultLanguages, error) { var contentQuery elastic.Query - if opts.SearchMode == indexer.SearchModeExact { + searchMode := util.IfZero(opts.SearchMode, b.SupportedSearchModes()[0].ModeValue) + if searchMode == indexer.SearchModeExact { + // 1.21 used NewMultiMatchQuery().Type(esMultiMatchTypePhrasePrefix), but later releases changed to NewMatchPhraseQuery contentQuery = elastic.NewMatchPhraseQuery("content", opts.Keyword) } else /* words */ { contentQuery = elastic.NewMultiMatchQuery("content", opts.Keyword).Type(esMultiMatchTypeBestFields).Operator("and") diff --git a/modules/indexer/code/indexer_test.go b/modules/indexer/code/indexer_test.go index 96516166a0..1d9bf99d40 100644 --- a/modules/indexer/code/indexer_test.go +++ b/modules/indexer/code/indexer_test.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/modules/indexer/code/internal" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/modules/util" _ "code.gitea.io/gitea/models" _ "code.gitea.io/gitea/models/actions" @@ -240,7 +241,7 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) { total, res, langs, err := indexer.Search(t.Context(), &internal.SearchOptions{ RepoIDs: kw.RepoIDs, Keyword: kw.Keyword, - SearchMode: kw.SearchMode, + SearchMode: util.IfZero(kw.SearchMode, indexer_module.SearchModeWords), Paginator: &db.ListOptions{ Page: 1, PageSize: 10, diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index e778df86c1..9534b0b750 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -10,6 +10,7 @@ import ( indexer_internal "code.gitea.io/gitea/modules/indexer/internal" inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve" "code.gitea.io/gitea/modules/indexer/issues/internal" + "code.gitea.io/gitea/modules/util" "github.com/blevesearch/bleve/v2" "github.com/blevesearch/bleve/v2/analysis/analyzer/custom" @@ -162,9 +163,10 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( var queries []query.Query if options.Keyword != "" { - if options.SearchMode == indexer.SearchModeWords || options.SearchMode == indexer.SearchModeFuzzy { + searchMode := util.IfZero(options.SearchMode, b.SupportedSearchModes()[0].ModeValue) + if searchMode == indexer.SearchModeWords || searchMode == indexer.SearchModeFuzzy { fuzziness := 0 - if options.SearchMode == indexer.SearchModeFuzzy { + if searchMode == indexer.SearchModeFuzzy { fuzziness = inner_bleve.GuessFuzzinessByKeyword(options.Keyword) } queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ diff --git a/modules/indexer/issues/db/db.go b/modules/indexer/issues/db/db.go index 493f6dd0b0..6124ad2515 100644 --- a/modules/indexer/issues/db/db.go +++ b/modules/indexer/issues/db/db.go @@ -13,6 +13,7 @@ import ( indexer_internal "code.gitea.io/gitea/modules/indexer/internal" inner_db "code.gitea.io/gitea/modules/indexer/internal/db" "code.gitea.io/gitea/modules/indexer/issues/internal" + "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -46,7 +47,7 @@ func (i *Indexer) Delete(_ context.Context, _ ...int64) error { func buildMatchQuery(mode indexer.SearchModeType, colName, keyword string) builder.Cond { if mode == indexer.SearchModeExact { - return db.BuildCaseInsensitiveLike("issue.name", keyword) + return db.BuildCaseInsensitiveLike(colName, keyword) } // match words @@ -84,16 +85,16 @@ func (i *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( repoCond = builder.Eq{"repo_id": options.RepoIDs[0]} } subQuery := builder.Select("id").From("issue").Where(repoCond) - + searchMode := util.IfZero(options.SearchMode, i.SupportedSearchModes()[0].ModeValue) cond = builder.Or( - buildMatchQuery(options.SearchMode, "issue.name", options.Keyword), - buildMatchQuery(options.SearchMode, "issue.content", options.Keyword), + buildMatchQuery(searchMode, "issue.name", options.Keyword), + buildMatchQuery(searchMode, "issue.content", options.Keyword), builder.In("issue.id", builder.Select("issue_id"). From("comment"). Where(builder.And( builder.Eq{"type": issue_model.CommentTypeComment}, builder.In("issue_id", subQuery), - buildMatchQuery(options.SearchMode, "content", options.Keyword), + buildMatchQuery(searchMode, "content", options.Keyword), )), ), ) diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index 2e4e172540..464c0028f2 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -14,6 +14,7 @@ import ( indexer_internal "code.gitea.io/gitea/modules/indexer/internal" inner_elasticsearch "code.gitea.io/gitea/modules/indexer/internal/elasticsearch" "code.gitea.io/gitea/modules/indexer/issues/internal" + "code.gitea.io/gitea/modules/util" "github.com/olivere/elastic/v7" ) @@ -152,7 +153,8 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( query := elastic.NewBoolQuery() if options.Keyword != "" { - if options.SearchMode == indexer.SearchModeExact { + searchMode := util.IfZero(options.SearchMode, b.SupportedSearchModes()[0].ModeValue) + if searchMode == indexer.SearchModeExact { query.Must(elastic.NewMultiMatchQuery(options.Keyword, "title", "content", "comments").Type(esMultiMatchTypePhrasePrefix)) } else /* words */ { query.Must(elastic.NewMultiMatchQuery(options.Keyword, "title", "content", "comments").Type(esMultiMatchTypeBestFields).Operator("and")) diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go index a712efbc8b..4741235d47 100644 --- a/modules/indexer/issues/indexer.go +++ b/modules/indexer/issues/indexer.go @@ -282,7 +282,7 @@ const ( // SearchIssues search issues by options. func SearchIssues(ctx context.Context, opts *SearchOptions) ([]int64, int64, error) { - indexer := *globalIndexer.Load() + ix := *globalIndexer.Load() if opts.Keyword == "" || opts.IsKeywordNumeric() { // This is a conservative shortcut. @@ -291,10 +291,9 @@ func SearchIssues(ctx context.Context, opts *SearchOptions) ([]int64, int64, err // So if the user creates an issue and list issues immediately, the issue may not be listed because the indexer needs time to index the issue. // Even worse, the external indexer like elastic search may not be available for a while, // and the user may not be able to list issues completely until it is available again. - indexer = db.NewIndexer() + ix = db.NewIndexer() } - - result, err := indexer.Search(ctx, opts) + result, err := ix.Search(ctx, opts) if err != nil { return nil, 0, err } diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 7def2a2c6e..14dd6ba101 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -82,9 +82,11 @@ func searchIssueWithKeyword(t *testing.T) { } for _, test := range tests { - issueIDs, _, err := SearchIssues(t.Context(), &test.opts) - require.NoError(t, err) - assert.Equal(t, test.expectedIDs, issueIDs) + t.Run(test.opts.Keyword, func(t *testing.T) { + issueIDs, _, err := SearchIssues(t.Context(), &test.opts) + require.NoError(t, err) + assert.Equal(t, test.expectedIDs, issueIDs) + }) } } From 55cc649d3d293a13eee7a56ca1744577c08b4e6c Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 14 Mar 2025 11:38:55 -0700 Subject: [PATCH 223/655] Add abstraction layer to delete repository from disk (#33879) Extract from #28966 Follow #33874 --- modules/gitrepo/gitrepo.go | 21 ++++++++++++++++++++- routers/web/repo/blame.go | 9 +++++---- services/repository/create.go | 2 +- services/repository/delete.go | 10 ++++++++-- services/repository/fork.go | 2 +- services/repository/transfer.go | 4 ++-- 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/modules/gitrepo/gitrepo.go b/modules/gitrepo/gitrepo.go index c3b412fd83..5e2ec9ed1e 100644 --- a/modules/gitrepo/gitrepo.go +++ b/modules/gitrepo/gitrepo.go @@ -5,6 +5,7 @@ package gitrepo import ( "context" + "fmt" "io" "path/filepath" "strings" @@ -20,8 +21,12 @@ type Repository interface { GetOwnerName() string } +func absPath(owner, name string) string { + return filepath.Join(setting.RepoRootPath, strings.ToLower(owner), strings.ToLower(name)+".git") +} + func repoPath(repo Repository) string { - return filepath.Join(setting.RepoRootPath, strings.ToLower(repo.GetOwnerName()), strings.ToLower(repo.GetName())+".git") + return absPath(repo.GetOwnerName(), repo.GetName()) } func wikiPath(repo Repository) string { @@ -74,3 +79,17 @@ func RepositoryFromRequestContextOrOpen(ctx reqctx.RequestContext, repo Reposito func IsRepositoryExist(ctx context.Context, repo Repository) (bool, error) { return util.IsExist(repoPath(repo)) } + +// DeleteRepository deletes the repository directory from the disk +func DeleteRepository(ctx context.Context, repo Repository) error { + return util.RemoveAll(repoPath(repo)) +} + +// RenameRepository renames a repository's name on disk +func RenameRepository(ctx context.Context, repo Repository, newName string) error { + newRepoPath := absPath(repo.GetOwnerName(), newName) + if err := util.Rename(repoPath(repo), newRepoPath); err != nil { + return fmt.Errorf("rename repository directory: %w", err) + } + return nil +} diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index e79029a55e..2da5acd299 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git" @@ -105,7 +106,7 @@ func RefBlame(ctx *context.Context) { bypassBlameIgnore, _ := strconv.ParseBool(ctx.FormString("bypass-blame-ignore")) - result, err := performBlame(ctx, ctx.Repo.Repository.RepoPath(), ctx.Repo.Commit, fileName, bypassBlameIgnore) + result, err := performBlame(ctx, ctx.Repo.Repository, ctx.Repo.Commit, fileName, bypassBlameIgnore) if err != nil { ctx.NotFound(err) return @@ -130,10 +131,10 @@ type blameResult struct { FaultyIgnoreRevsFile bool } -func performBlame(ctx *context.Context, repoPath string, commit *git.Commit, file string, bypassBlameIgnore bool) (*blameResult, error) { +func performBlame(ctx *context.Context, repo *repo_model.Repository, commit *git.Commit, file string, bypassBlameIgnore bool) (*blameResult, error) { objectFormat := ctx.Repo.GetObjectFormat() - blameReader, err := git.CreateBlameReader(ctx, objectFormat, repoPath, commit, file, bypassBlameIgnore) + blameReader, err := git.CreateBlameReader(ctx, objectFormat, repo.RepoPath(), commit, file, bypassBlameIgnore) if err != nil { return nil, err } @@ -149,7 +150,7 @@ func performBlame(ctx *context.Context, repoPath string, commit *git.Commit, fil if len(r.Parts) == 0 && r.UsesIgnoreRevs { // try again without ignored revs - blameReader, err = git.CreateBlameReader(ctx, objectFormat, repoPath, commit, file, true) + blameReader, err = git.CreateBlameReader(ctx, objectFormat, repo.RepoPath(), commit, file, true) if err != nil { return nil, err } diff --git a/services/repository/create.go b/services/repository/create.go index 62b5931fd9..1a6a68b35a 100644 --- a/services/repository/create.go +++ b/services/repository/create.go @@ -277,7 +277,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt } if err = initRepository(ctx, doer, repo, opts); err != nil { - if err2 := util.RemoveAll(repo.RepoPath()); err2 != nil { + if err2 := gitrepo.DeleteRepository(ctx, repo); err2 != nil { log.Error("initRepository: %v", err) return fmt.Errorf( "delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2) diff --git a/services/repository/delete.go b/services/repository/delete.go index 3b953d3ec7..ff74a20817 100644 --- a/services/repository/delete.go +++ b/services/repository/delete.go @@ -23,6 +23,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" actions_module "code.gitea.io/gitea/modules/actions" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/storage" @@ -289,8 +290,13 @@ func DeleteRepositoryDirectly(ctx context.Context, doer *user_model.User, repoID // we delete the file but the database rollback, the repository will be broken. // Remove repository files. - repoPath := repo.RepoPath() - system_model.RemoveAllWithNotice(ctx, "Delete repository files", repoPath) + if err := gitrepo.DeleteRepository(ctx, repo); err != nil { + desc := fmt.Sprintf("Delete repository files [%s]: %v", repo.FullName(), err) + // Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled + if err = system_model.CreateNotice(db.DefaultContext, system_model.NoticeRepository, desc); err != nil { + log.Error("CreateRepositoryNotice: %v", err) + } + } // Remove wiki files if repo.HasWiki() { diff --git a/services/repository/fork.go b/services/repository/fork.go index 1bd4d4a13b..ec6ba56ddf 100644 --- a/services/repository/fork.go +++ b/services/repository/fork.go @@ -116,7 +116,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork // As the transaction will be failed and hence database changes will be destroyed we only need // to delete the related repository on the filesystem - if errDelete := util.RemoveAll(repo.RepoPath()); errDelete != nil { + if errDelete := gitrepo.DeleteRepository(ctx, repo); errDelete != nil { log.Error("Failed to remove fork repo") } } diff --git a/services/repository/transfer.go b/services/repository/transfer.go index bd3bf326b4..3940b2a142 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -17,6 +17,7 @@ import ( project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/globallock" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" @@ -335,8 +336,7 @@ func changeRepositoryName(ctx context.Context, repo *repo_model.Repository, newR } } - newRepoPath := repo_model.RepoPath(repo.Owner.Name, newRepoName) - if err = util.Rename(repo.RepoPath(), newRepoPath); err != nil { + if err = gitrepo.RenameRepository(ctx, repo, newRepoName); err != nil { return fmt.Errorf("rename repository directory: %w", err) } From 65e2411394cfebf117d29f1bea47b93dd1c22b19 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Fri, 14 Mar 2025 20:27:24 +0100 Subject: [PATCH 224/655] Feature: Ephemeral action runners (#33570) * This includes a runner mock test for hardend PickTask behavior like described in my proposal * Runner register ephemeral flag introduced in https://gitea.com/gitea/act_runner/pulls/649 Closes #32461 --- models/actions/runner.go | 2 + models/migrations/migrations.go | 1 + models/migrations/v1_24/v315.go | 16 +++ routers/api/actions/runner/runner.go | 14 +- services/actions/cleanup.go | 27 +++- services/actions/task.go | 20 +++ tests/integration/actions_job_test.go | 158 ++++++++++++++++++++++- tests/integration/actions_log_test.go | 2 +- tests/integration/actions_runner_test.go | 15 ++- tests/integration/repo_webhook_test.go | 2 +- 10 files changed, 238 insertions(+), 19 deletions(-) create mode 100644 models/migrations/v1_24/v315.go diff --git a/models/actions/runner.go b/models/actions/runner.go index 97db0ca7ea..9ddf346aa6 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -57,6 +57,8 @@ type ActionRunner struct { // Store labels defined in state file (default: .runner file) of `act_runner` AgentLabels []string `xorm:"TEXT"` + // Store if this is a runner that only ever get one single job assigned + Ephemeral bool `xorm:"ephemeral NOT NULL DEFAULT false"` Created timeutil.TimeStamp `xorm:"created"` Updated timeutil.TimeStamp `xorm:"updated"` diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 5f79a873f1..f9ab993abf 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -375,6 +375,7 @@ func prepareMigrationTasks() []*migration { newMigration(312, "Add DeleteBranchAfterMerge to AutoMerge", v1_24.AddDeleteBranchAfterMergeForAutoMerge), newMigration(313, "Move PinOrder from issue table to a new table issue_pin", v1_24.MovePinOrderToTableIssuePin), newMigration(314, "Update OwnerID as zero for repository level action tables", v1_24.UpdateOwnerIDOfRepoLevelActionsTables), + newMigration(315, "Add Ephemeral to ActionRunner", v1_24.AddEphemeralToActionRunner), } return preparedMigrations } diff --git a/models/migrations/v1_24/v315.go b/models/migrations/v1_24/v315.go new file mode 100644 index 0000000000..aefb872d0f --- /dev/null +++ b/models/migrations/v1_24/v315.go @@ -0,0 +1,16 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_24 //nolint + +import ( + "xorm.io/xorm" +) + +func AddEphemeralToActionRunner(x *xorm.Engine) error { + type ActionRunner struct { + Ephemeral bool `xorm:"ephemeral NOT NULL DEFAULT false"` + } + + return x.Sync(new(ActionRunner)) +} diff --git a/routers/api/actions/runner/runner.go b/routers/api/actions/runner/runner.go index 27a0317942..ce8137592d 100644 --- a/routers/api/actions/runner/runner.go +++ b/routers/api/actions/runner/runner.go @@ -78,6 +78,7 @@ func (s *Service) Register( RepoID: runnerToken.RepoID, Version: req.Msg.Version, AgentLabels: labels, + Ephemeral: req.Msg.Ephemeral, } if err := runner.GenerateToken(); err != nil { return nil, errors.New("can't generate token") @@ -96,12 +97,13 @@ func (s *Service) Register( res := connect.NewResponse(&runnerv1.RegisterResponse{ Runner: &runnerv1.Runner{ - Id: runner.ID, - Uuid: runner.UUID, - Token: runner.Token, - Name: runner.Name, - Version: runner.Version, - Labels: runner.AgentLabels, + Id: runner.ID, + Uuid: runner.UUID, + Token: runner.Token, + Name: runner.Name, + Version: runner.Version, + Labels: runner.AgentLabels, + Ephemeral: runner.Ephemeral, }, }) diff --git a/services/actions/cleanup.go b/services/actions/cleanup.go index ee1d167713..23d6e3a49d 100644 --- a/services/actions/cleanup.go +++ b/services/actions/cleanup.go @@ -9,14 +9,17 @@ import ( "time" actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/models/db" actions_module "code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/builder" ) -// Cleanup removes expired actions logs, data and artifacts +// Cleanup removes expired actions logs, data, artifacts and used ephemeral runners func Cleanup(ctx context.Context) error { // clean up expired artifacts if err := CleanupArtifacts(ctx); err != nil { @@ -28,6 +31,11 @@ func Cleanup(ctx context.Context) error { return fmt.Errorf("cleanup logs: %w", err) } + // clean up old ephemeral runners + if err := CleanupEphemeralRunners(ctx); err != nil { + return fmt.Errorf("cleanup old ephemeral runners: %w", err) + } + return nil } @@ -123,3 +131,20 @@ func CleanupLogs(ctx context.Context) error { log.Info("Removed %d logs", count) return nil } + +// CleanupEphemeralRunners removes used ephemeral runners which are no longer able to process jobs +func CleanupEphemeralRunners(ctx context.Context) error { + subQuery := builder.Select("`action_runner`.id"). + From(builder.Select("*").From("`action_runner`"), "`action_runner`"). // mysql needs this redundant subquery + Join("INNER", "`action_task`", "`action_task`.`runner_id` = `action_runner`.`id`"). + Where(builder.Eq{"`action_runner`.`ephemeral`": true}). + And(builder.NotIn("`action_task`.`status`", actions_model.StatusWaiting, actions_model.StatusRunning, actions_model.StatusBlocked)) + b := builder.Delete(builder.In("id", subQuery)).From("`action_runner`") + res, err := db.GetEngine(ctx).Exec(b) + if err != nil { + return fmt.Errorf("find runners: %w", err) + } + affected, _ := res.RowsAffected() + log.Info("Removed %d runners", affected) + return nil +} diff --git a/services/actions/task.go b/services/actions/task.go index 1feeb67a80..9c8198206a 100644 --- a/services/actions/task.go +++ b/services/actions/task.go @@ -23,6 +23,26 @@ func PickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv actionTask *actions_model.ActionTask ) + if runner.Ephemeral { + var task actions_model.ActionTask + has, err := db.GetEngine(ctx).Where("runner_id = ?", runner.ID).Get(&task) + // Let the runner retry the request, do not allow to proceed + if err != nil { + return nil, false, err + } + if has { + if task.Status == actions_model.StatusWaiting || task.Status == actions_model.StatusRunning || task.Status == actions_model.StatusBlocked { + return nil, false, nil + } + // task has been finished, remove it + _, err = db.DeleteByID[actions_model.ActionRunner](ctx, runner.ID) + if err != nil { + return nil, false, err + } + return nil, false, fmt.Errorf("runner has been removed") + } + } + if err := db.WithTx(ctx, func(ctx context.Context) error { t, ok, err := actions_model.CreateTaskForRunner(ctx, runner) if err != nil { diff --git a/tests/integration/actions_job_test.go b/tests/integration/actions_job_test.go index a967adb417..caab215cee 100644 --- a/tests/integration/actions_job_test.go +++ b/tests/integration/actions_job_test.go @@ -21,8 +21,10 @@ import ( "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + actions_service "code.gitea.io/gitea/services/actions" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" + "connectrpc.com/connect" "github.com/stretchr/testify/assert" ) @@ -132,7 +134,7 @@ jobs: apiRepo := createActionsTestRepo(t, token, "actions-jobs-with-needs", false) runner := newMockRunner() - runner.registerAsRepoRunner(t, user2.Name, apiRepo.Name, "mock-runner", []string{"ubuntu-latest"}) + runner.registerAsRepoRunner(t, user2.Name, apiRepo.Name, "mock-runner", []string{"ubuntu-latest"}, false) for _, tc := range testCases { t.Run(fmt.Sprintf("test %s", tc.treePath), func(t *testing.T) { @@ -318,7 +320,7 @@ jobs: apiRepo := createActionsTestRepo(t, token, "actions-jobs-outputs-with-matrix", false) runner := newMockRunner() - runner.registerAsRepoRunner(t, user2.Name, apiRepo.Name, "mock-runner", []string{"ubuntu-latest"}) + runner.registerAsRepoRunner(t, user2.Name, apiRepo.Name, "mock-runner", []string{"ubuntu-latest"}, false) for _, tc := range testCases { t.Run(fmt.Sprintf("test %s", tc.treePath), func(t *testing.T) { @@ -363,7 +365,7 @@ func TestActionsGiteaContext(t *testing.T) { user2APICtx := NewAPITestContext(t, baseRepo.OwnerName, baseRepo.Name, auth_model.AccessTokenScopeWriteRepository) runner := newMockRunner() - runner.registerAsRepoRunner(t, baseRepo.OwnerName, baseRepo.Name, "mock-runner", []string{"ubuntu-latest"}) + runner.registerAsRepoRunner(t, baseRepo.OwnerName, baseRepo.Name, "mock-runner", []string{"ubuntu-latest"}, false) // init the workflow wfTreePath := ".gitea/workflows/pull.yml" @@ -437,6 +439,156 @@ jobs: }) } +// Ephemeral +func TestActionsGiteaContextEphemeral(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user2Session := loginUser(t, user2.Name) + user2Token := getTokenForLoggedInUser(t, user2Session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) + + apiBaseRepo := createActionsTestRepo(t, user2Token, "actions-gitea-context", false) + baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiBaseRepo.ID}) + user2APICtx := NewAPITestContext(t, baseRepo.OwnerName, baseRepo.Name, auth_model.AccessTokenScopeWriteRepository) + + runner := newMockRunner() + runner.registerAsRepoRunner(t, baseRepo.OwnerName, baseRepo.Name, "mock-runner", []string{"ubuntu-latest"}, true) + + // verify CleanupEphemeralRunners does not remove this runner + err := actions_service.CleanupEphemeralRunners(t.Context()) + assert.NoError(t, err) + + // init the workflow + wfTreePath := ".gitea/workflows/pull.yml" + wfFileContent := `name: Pull Request +on: pull_request +jobs: + wf1-job: + runs-on: ubuntu-latest + steps: + - run: echo 'test the pull' + wf2-job: + runs-on: ubuntu-latest + steps: + - run: echo 'test the pull' +` + opts := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, fmt.Sprintf("create %s", wfTreePath), wfFileContent) + createWorkflowFile(t, user2Token, baseRepo.OwnerName, baseRepo.Name, wfTreePath, opts) + // user2 creates a pull request + doAPICreateFile(user2APICtx, "user2-patch.txt", &api.CreateFileOptions{ + FileOptions: api.FileOptions{ + NewBranchName: "user2/patch-1", + Message: "create user2-patch.txt", + Author: api.Identity{ + Name: user2.Name, + Email: user2.Email, + }, + Committer: api.Identity{ + Name: user2.Name, + Email: user2.Email, + }, + Dates: api.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }, + ContentBase64: base64.StdEncoding.EncodeToString([]byte("user2-fix")), + })(t) + apiPull, err := doAPICreatePullRequest(user2APICtx, baseRepo.OwnerName, baseRepo.Name, baseRepo.DefaultBranch, "user2/patch-1")(t) + assert.NoError(t, err) + task := runner.fetchTask(t) + gtCtx := task.Context.GetFields() + actionTask := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: task.Id}) + actionRunJob := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: actionTask.JobID}) + actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: actionRunJob.RunID}) + assert.NoError(t, actionRun.LoadAttributes(t.Context())) + + assert.Equal(t, user2.Name, gtCtx["actor"].GetStringValue()) + assert.Equal(t, setting.AppURL+"api/v1", gtCtx["api_url"].GetStringValue()) + assert.Equal(t, apiPull.Base.Ref, gtCtx["base_ref"].GetStringValue()) + runEvent := map[string]any{} + assert.NoError(t, json.Unmarshal([]byte(actionRun.EventPayload), &runEvent)) + assert.True(t, reflect.DeepEqual(gtCtx["event"].GetStructValue().AsMap(), runEvent)) + assert.Equal(t, actionRun.TriggerEvent, gtCtx["event_name"].GetStringValue()) + assert.Equal(t, apiPull.Head.Ref, gtCtx["head_ref"].GetStringValue()) + assert.Equal(t, actionRunJob.JobID, gtCtx["job"].GetStringValue()) + assert.Equal(t, actionRun.Ref, gtCtx["ref"].GetStringValue()) + assert.Equal(t, (git.RefName(actionRun.Ref)).ShortName(), gtCtx["ref_name"].GetStringValue()) + assert.False(t, gtCtx["ref_protected"].GetBoolValue()) + assert.Equal(t, string((git.RefName(actionRun.Ref)).RefType()), gtCtx["ref_type"].GetStringValue()) + assert.Equal(t, actionRun.Repo.OwnerName+"/"+actionRun.Repo.Name, gtCtx["repository"].GetStringValue()) + assert.Equal(t, actionRun.Repo.OwnerName, gtCtx["repository_owner"].GetStringValue()) + assert.Equal(t, actionRun.Repo.HTMLURL(), gtCtx["repositoryUrl"].GetStringValue()) + assert.Equal(t, fmt.Sprint(actionRunJob.RunID), gtCtx["run_id"].GetStringValue()) + assert.Equal(t, fmt.Sprint(actionRun.Index), gtCtx["run_number"].GetStringValue()) + assert.Equal(t, fmt.Sprint(actionRunJob.Attempt), gtCtx["run_attempt"].GetStringValue()) + assert.Equal(t, "Actions", gtCtx["secret_source"].GetStringValue()) + assert.Equal(t, setting.AppURL, gtCtx["server_url"].GetStringValue()) + assert.Equal(t, actionRun.CommitSHA, gtCtx["sha"].GetStringValue()) + assert.Equal(t, actionRun.WorkflowID, gtCtx["workflow"].GetStringValue()) + assert.Equal(t, setting.Actions.DefaultActionsURL.URL(), gtCtx["gitea_default_actions_url"].GetStringValue()) + token := gtCtx["token"].GetStringValue() + assert.Equal(t, actionTask.TokenLastEight, token[len(token)-8:]) + + // verify CleanupEphemeralRunners does not remove this runner + err = actions_service.CleanupEphemeralRunners(t.Context()) + assert.NoError(t, err) + + resp, err := runner.client.runnerServiceClient.FetchTask(t.Context(), connect.NewRequest(&runnerv1.FetchTaskRequest{ + TasksVersion: 0, + })) + assert.NoError(t, err) + assert.Nil(t, resp.Msg.Task) + + // verify CleanupEphemeralRunners does not remove this runner + err = actions_service.CleanupEphemeralRunners(t.Context()) + assert.NoError(t, err) + + runner.client.runnerServiceClient.UpdateTask(t.Context(), connect.NewRequest(&runnerv1.UpdateTaskRequest{ + State: &runnerv1.TaskState{ + Id: actionTask.ID, + Result: runnerv1.Result_RESULT_SUCCESS, + }, + })) + resp, err = runner.client.runnerServiceClient.FetchTask(t.Context(), connect.NewRequest(&runnerv1.FetchTaskRequest{ + TasksVersion: 0, + })) + assert.Error(t, err) + assert.Nil(t, resp) + + resp, err = runner.client.runnerServiceClient.FetchTask(t.Context(), connect.NewRequest(&runnerv1.FetchTaskRequest{ + TasksVersion: 0, + })) + assert.Error(t, err) + assert.Nil(t, resp) + + // create an runner that picks a job and get force cancelled + runnerToBeRemoved := newMockRunner() + runnerToBeRemoved.registerAsRepoRunner(t, baseRepo.OwnerName, baseRepo.Name, "mock-runner-to-be-removed", []string{"ubuntu-latest"}, true) + + taskToStopAPIObj := runnerToBeRemoved.fetchTask(t) + + taskToStop := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: taskToStopAPIObj.Id}) + + // verify CleanupEphemeralRunners does not remove the custom crafted runner + err = actions_service.CleanupEphemeralRunners(t.Context()) + assert.NoError(t, err) + + runnerToRemove := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: taskToStop.RunnerID}) + + err = actions_model.StopTask(t.Context(), taskToStop.ID, actions_model.StatusFailure) + assert.NoError(t, err) + + // verify CleanupEphemeralRunners does remove the custom crafted runner + err = actions_service.CleanupEphemeralRunners(t.Context()) + assert.NoError(t, err) + + unittest.AssertNotExistsBean(t, &actions_model.ActionRunner{ID: runnerToRemove.ID}) + + // this cleanup is required to allow further tests to pass + doAPIDeleteRepository(user2APICtx)(t) + }) +} + func createActionsTestRepo(t *testing.T, authToken, repoName string, isPrivate bool) *api.Repository { req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos", &api.CreateRepoOption{ Name: repoName, diff --git a/tests/integration/actions_log_test.go b/tests/integration/actions_log_test.go index fd055fc4c4..8f10226721 100644 --- a/tests/integration/actions_log_test.go +++ b/tests/integration/actions_log_test.go @@ -105,7 +105,7 @@ jobs: apiRepo := createActionsTestRepo(t, token, "actions-download-task-logs", false) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}) runner := newMockRunner() - runner.registerAsRepoRunner(t, user2.Name, repo.Name, "mock-runner", []string{"ubuntu-latest"}) + runner.registerAsRepoRunner(t, user2.Name, repo.Name, "mock-runner", []string{"ubuntu-latest"}, false) for _, tc := range testCases { t.Run(fmt.Sprintf("test %s", tc.treePath), func(t *testing.T) { diff --git a/tests/integration/actions_runner_test.go b/tests/integration/actions_runner_test.go index da51e1c04e..ee92032e9f 100644 --- a/tests/integration/actions_runner_test.go +++ b/tests/integration/actions_runner_test.go @@ -67,19 +67,20 @@ func (r *mockRunner) doPing(t *testing.T) { assert.Equal(t, "Hello, mock-runner!", resp.Msg.Data) } -func (r *mockRunner) doRegister(t *testing.T, name, token string, labels []string) { +func (r *mockRunner) doRegister(t *testing.T, name, token string, labels []string, ephemeral bool) { r.doPing(t) resp, err := r.client.runnerServiceClient.Register(t.Context(), connect.NewRequest(&runnerv1.RegisterRequest{ - Name: name, - Token: token, - Version: "mock-runner-version", - Labels: labels, + Name: name, + Token: token, + Version: "mock-runner-version", + Labels: labels, + Ephemeral: ephemeral, })) assert.NoError(t, err) r.client = newMockRunnerClient(resp.Msg.Runner.Uuid, resp.Msg.Runner.Token) } -func (r *mockRunner) registerAsRepoRunner(t *testing.T, ownerName, repoName, runnerName string, labels []string) { +func (r *mockRunner) registerAsRepoRunner(t *testing.T, ownerName, repoName, runnerName string, labels []string, ephemeral bool) { session := loginUser(t, ownerName) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/actions/runners/registration-token", ownerName, repoName)).AddTokenAuth(token) @@ -88,7 +89,7 @@ func (r *mockRunner) registerAsRepoRunner(t *testing.T, ownerName, repoName, run Token string `json:"token"` } DecodeJSON(t, resp, ®istrationToken) - r.doRegister(t, runnerName, registrationToken.Token, labels) + r.doRegister(t, runnerName, registrationToken.Token, labels, ephemeral) } func (r *mockRunner) fetchTask(t *testing.T, timeout ...time.Duration) *runnerv1.Task { diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go index effeff111d..7e85c10d4b 100644 --- a/tests/integration/repo_webhook_test.go +++ b/tests/integration/repo_webhook_test.go @@ -639,7 +639,7 @@ func Test_WebhookWorkflowJob(t *testing.T) { assert.NoError(t, err) runner := newMockRunner() - runner.registerAsRepoRunner(t, "user2", "repo1", "mock-runner", []string{"ubuntu-latest"}) + runner.registerAsRepoRunner(t, "user2", "repo1", "mock-runner", []string{"ubuntu-latest"}, false) // 2. trigger the webhooks From 926f0a19bec2fa075ee547dd8b405489caa9923e Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 15 Mar 2025 00:33:24 +0000 Subject: [PATCH 225/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_pt-PT.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index e03b741ad2..bcb420b5ea 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -169,6 +169,10 @@ search=Pesquisar... type_tooltip=Tipo de pesquisa fuzzy=Aproximada fuzzy_tooltip=Incluir também os resultados que estejam próximos do termo de pesquisa +words=Palavras +words_tooltip=Incluir apenas os resultados que correspondam às palavras do termo de pesquisa +regexp=Regexp +regexp_tooltip=Incluir apenas os resultados que correspondam ao termo de pesquisa com expressões regulares exact=Fiel exact_tooltip=Incluir somente os resultados que correspondam rigorosamente ao termo de pesquisa repo_kind=Pesquisar repositórios... From 92f997ce6b2535c0c71a33ade290378a744c7224 Mon Sep 17 00:00:00 2001 From: Kerwin Bryant Date: Sat, 15 Mar 2025 16:26:49 +0800 Subject: [PATCH 226/655] Add file tree to file view page (#32721) Resolve #29328 This pull request introduces a file tree on the left side when reviewing files of a repository. --------- Co-authored-by: Lunny Xiao Co-authored-by: wxiaoguang --- models/user/setting_keys.go | 3 + modules/git/parse_nogogit.go | 2 +- modules/git/tree_blob_gogit.go | 1 + routers/web/repo/blame.go | 60 +++----- routers/web/repo/treelist.go | 10 ++ routers/web/repo/view.go | 14 +- routers/web/repo/view_home.go | 25 +++- routers/web/user/setting/settings.go | 26 ++++ routers/web/web.go | 6 + services/contexttest/context_tests.go | 26 ++-- services/repository/files/tree.go | 99 +++++++++++++ services/repository/files/tree_test.go | 49 +++++++ templates/repo/home.tmpl | 108 +------------- templates/repo/view.tmpl | 29 ++++ templates/repo/view_content.tmpl | 111 +++++++++++++++ templates/repo/view_file_tree.tmpl | 15 ++ web_src/css/repo/home.css | 15 ++ web_src/js/components/ViewFileTree.vue | 62 ++++++++ web_src/js/components/ViewFileTreeItem.vue | 156 +++++++++++++++++++++ web_src/js/features/repo-view-file-tree.ts | 37 +++++ web_src/js/index.ts | 2 + web_src/js/svg.ts | 2 + 22 files changed, 696 insertions(+), 162 deletions(-) create mode 100644 routers/web/user/setting/settings.go create mode 100644 templates/repo/view.tmpl create mode 100644 templates/repo/view_content.tmpl create mode 100644 templates/repo/view_file_tree.tmpl create mode 100644 web_src/js/components/ViewFileTree.vue create mode 100644 web_src/js/components/ViewFileTreeItem.vue create mode 100644 web_src/js/features/repo-view-file-tree.ts diff --git a/models/user/setting_keys.go b/models/user/setting_keys.go index 3149aae18b..2c2ed078be 100644 --- a/models/user/setting_keys.go +++ b/models/user/setting_keys.go @@ -10,6 +10,7 @@ const ( SettingsKeyDiffWhitespaceBehavior = "diff.whitespace_behaviour" // SettingsKeyShowOutdatedComments is the setting key wether or not to show outdated comments in PRs SettingsKeyShowOutdatedComments = "comment_code.show_outdated" + // UserActivityPubPrivPem is user's private key UserActivityPubPrivPem = "activitypub.priv_pem" // UserActivityPubPubPem is user's public key @@ -18,4 +19,6 @@ const ( SignupIP = "signup.ip" // SignupUserAgent is the user agent that the user signed up with SignupUserAgent = "signup.user_agent" + + SettingsKeyCodeViewShowFileTree = "code_view.show_file_tree" ) diff --git a/modules/git/parse_nogogit.go b/modules/git/parse_nogogit.go index 676bb3c76c..78a0162889 100644 --- a/modules/git/parse_nogogit.go +++ b/modules/git/parse_nogogit.go @@ -19,7 +19,7 @@ func ParseTreeEntries(data []byte) ([]*TreeEntry, error) { return parseTreeEntries(data, nil) } -// parseTreeEntries FIXME this function's design is not right, it should make the caller read all data into memory +// parseTreeEntries FIXME this function's design is not right, it should not make the caller read all data into memory func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) { entries := make([]*TreeEntry, 0, bytes.Count(data, []byte{'\n'})+1) for pos := 0; pos < len(data); { diff --git a/modules/git/tree_blob_gogit.go b/modules/git/tree_blob_gogit.go index 92c25cb92c..f29e8f8b9e 100644 --- a/modules/git/tree_blob_gogit.go +++ b/modules/git/tree_blob_gogit.go @@ -21,6 +21,7 @@ func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) { return &TreeEntry{ ID: t.ID, // Type: ObjectTree, + ptree: t, gogitTreeEntry: &object.TreeEntry{ Name: "", Mode: filemode.Dir, diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index 2da5acd299..efd85b9452 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -41,60 +41,45 @@ type blameRow struct { // RefBlame render blame page func RefBlame(ctx *context.Context) { - fileName := ctx.Repo.TreePath - if len(fileName) == 0 { + ctx.Data["PageIsViewCode"] = true + ctx.Data["IsBlame"] = true + + // Get current entry user currently looking at. + if ctx.Repo.TreePath == "" { ctx.NotFound(nil) return } - - branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() - treeLink := branchLink - rawLink := ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() - - if len(ctx.Repo.TreePath) > 0 { - treeLink += "/" + util.PathEscapeSegments(ctx.Repo.TreePath) - } - - var treeNames []string - paths := make([]string, 0, 5) - if len(ctx.Repo.TreePath) > 0 { - treeNames = strings.Split(ctx.Repo.TreePath, "/") - for i := range treeNames { - paths = append(paths, strings.Join(treeNames[:i+1], "/")) - } - - ctx.Data["HasParentPath"] = true - if len(paths)-2 >= 0 { - ctx.Data["ParentPath"] = "/" + paths[len(paths)-1] - } - } - - // Get current entry user currently looking at. entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) if err != nil { HandleGitError(ctx, "Repo.Commit.GetTreeEntryByPath", err) return } - blob := entry.Blob() + treeNames := strings.Split(ctx.Repo.TreePath, "/") + var paths []string + for i := range treeNames { + paths = append(paths, strings.Join(treeNames[:i+1], "/")) + } ctx.Data["Paths"] = paths - ctx.Data["TreeLink"] = treeLink ctx.Data["TreeNames"] = treeNames - ctx.Data["BranchLink"] = branchLink - - ctx.Data["RawFileLink"] = rawLink + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) - ctx.Data["PageIsViewCode"] = true - - ctx.Data["IsBlame"] = true + ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() + ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) + blob := entry.Blob() fileSize := blob.Size() ctx.Data["FileSize"] = fileSize ctx.Data["FileName"] = blob.Name() + tplName := tplRepoViewContent + if !ctx.FormBool("only_content") { + prepareHomeTreeSideBarSwitch(ctx) + tplName = tplRepoView + } + if fileSize >= setting.UI.MaxDisplayFileSize { ctx.Data["IsFileTooLarge"] = true - ctx.HTML(http.StatusOK, tplRepoHome) + ctx.HTML(http.StatusOK, tplName) return } @@ -105,8 +90,7 @@ func RefBlame(ctx *context.Context) { } bypassBlameIgnore, _ := strconv.ParseBool(ctx.FormString("bypass-blame-ignore")) - - result, err := performBlame(ctx, ctx.Repo.Repository, ctx.Repo.Commit, fileName, bypassBlameIgnore) + result, err := performBlame(ctx, ctx.Repo.Repository, ctx.Repo.Commit, ctx.Repo.TreePath, bypassBlameIgnore) if err != nil { ctx.NotFound(err) return @@ -122,7 +106,7 @@ func RefBlame(ctx *context.Context) { renderBlame(ctx, result.Parts, commitNames) - ctx.HTML(http.StatusOK, tplRepoHome) + ctx.HTML(http.StatusOK, tplName) } type blameResult struct { diff --git a/routers/web/repo/treelist.go b/routers/web/repo/treelist.go index 9ce9f8424d..ab74741e61 100644 --- a/routers/web/repo/treelist.go +++ b/routers/web/repo/treelist.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/gitdiff" + files_service "code.gitea.io/gitea/services/repository/files" "github.com/go-enry/go-enry/v2" ) @@ -84,3 +85,12 @@ func transformDiffTreeForUI(diffTree *gitdiff.DiffTree, filesViewedState map[str return files } + +func TreeViewNodes(ctx *context.Context) { + results, err := files_service.GetTreeViewNodes(ctx, ctx.Repo.Commit, ctx.Repo.TreePath, ctx.FormString("sub_path")) + if err != nil { + ctx.ServerError("GetTreeViewNodes", err) + return + } + ctx.JSON(http.StatusOK, map[string]any{"fileTreeNodes": results}) +} diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index cb9c278cac..6ed5801d10 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -47,12 +47,14 @@ import ( ) const ( - tplRepoEMPTY templates.TplName = "repo/empty" - tplRepoHome templates.TplName = "repo/home" - tplRepoViewList templates.TplName = "repo/view_list" - tplWatchers templates.TplName = "repo/watchers" - tplForks templates.TplName = "repo/forks" - tplMigrating templates.TplName = "repo/migrate/migrating" + tplRepoEMPTY templates.TplName = "repo/empty" + tplRepoHome templates.TplName = "repo/home" + tplRepoView templates.TplName = "repo/view" + tplRepoViewContent templates.TplName = "repo/view_content" + tplRepoViewList templates.TplName = "repo/view_list" + tplWatchers templates.TplName = "repo/watchers" + tplForks templates.TplName = "repo/forks" + tplMigrating templates.TplName = "repo/migrate/migrating" ) type fileInfo struct { diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index 1da89686ad..d538406035 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -9,6 +9,7 @@ import ( "html/template" "net/http" "path" + "strconv" "strings" "time" @@ -17,6 +18,7 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" 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/log" repo_module "code.gitea.io/gitea/modules/repository" @@ -328,6 +330,19 @@ func handleRepoHomeFeed(ctx *context.Context) bool { return true } +func prepareHomeTreeSideBarSwitch(ctx *context.Context) { + showFileTree := true + if ctx.Doer != nil { + v, err := user_model.GetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyCodeViewShowFileTree, "true") + if err != nil { + log.Error("GetUserSetting: %v", err) + } else { + showFileTree, _ = strconv.ParseBool(v) + } + } + ctx.Data["UserSettingCodeViewShowFileTree"] = showFileTree +} + // Home render repository home page func Home(ctx *context.Context) { if handleRepoHomeFeed(ctx) { @@ -341,6 +356,8 @@ func Home(ctx *context.Context) { return } + prepareHomeTreeSideBarSwitch(ctx) + title := ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name if len(ctx.Repo.Repository.Description) > 0 { title += ": " + ctx.Repo.Repository.Description @@ -410,7 +427,13 @@ func Home(ctx *context.Context) { } } - ctx.HTML(http.StatusOK, tplRepoHome) + if ctx.FormBool("only_content") { + ctx.HTML(http.StatusOK, tplRepoViewContent) + } else if len(treeNames) != 0 { + ctx.HTML(http.StatusOK, tplRepoView) + } else { + ctx.HTML(http.StatusOK, tplRepoHome) + } } func RedirectRepoTreeToSrc(ctx *context.Context) { diff --git a/routers/web/user/setting/settings.go b/routers/web/user/setting/settings.go new file mode 100644 index 0000000000..111931633d --- /dev/null +++ b/routers/web/user/setting/settings.go @@ -0,0 +1,26 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package setting + +import ( + "net/http" + "strconv" + + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/services/context" +) + +func UpdatePreferences(ctx *context.Context) { + type preferencesForm struct { + CodeViewShowFileTree bool `json:"codeViewShowFileTree"` + } + form := &preferencesForm{} + if err := json.NewDecoder(ctx.Req.Body).Decode(&form); err != nil { + ctx.HTTPError(http.StatusBadRequest, "json decode failed") + return + } + _ = user_model.SetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyCodeViewShowFileTree, strconv.FormatBool(form.CodeViewShowFileTree)) + ctx.JSONOK() +} diff --git a/routers/web/web.go b/routers/web/web.go index 1223d56c92..f4bd3ef4bc 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -580,6 +580,7 @@ func registerRoutes(m *web.Router) { m.Group("/user/settings", func() { m.Get("", user_setting.Profile) m.Post("", web.Bind(forms.UpdateProfileForm{}), user_setting.ProfilePost) + m.Post("/update_preferences", user_setting.UpdatePreferences) m.Get("/change_password", auth.MustChangePassword) m.Post("/change_password", web.Bind(forms.MustChangePasswordForm{}), auth.MustChangePasswordPost) m.Post("/avatar", web.Bind(forms.AvatarForm{}), user_setting.AvatarPost) @@ -1175,6 +1176,11 @@ func registerRoutes(m *web.Router) { m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.TreeList) m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.TreeList) }) + m.Group("/tree-view", func() { + m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.TreeViewNodes) + m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.TreeViewNodes) + m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.TreeViewNodes) + }) m.Get("/compare", repo.MustBeNotEmpty, repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff) m.Combo("/compare/*", repo.MustBeNotEmpty, repo.SetEditorconfigIfExists). Get(repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff). diff --git a/services/contexttest/context_tests.go b/services/contexttest/context_tests.go index 98b8bdd63e..c895de3569 100644 --- a/services/contexttest/context_tests.go +++ b/services/contexttest/context_tests.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/cache" + git_module "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/reqctx" "code.gitea.io/gitea/modules/session" @@ -30,6 +31,7 @@ import ( "github.com/go-chi/chi/v5" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func mockRequest(t *testing.T, reqPath string) *http.Request { @@ -85,7 +87,7 @@ func MockAPIContext(t *testing.T, reqPath string) (*context.APIContext, *httptes base := context.NewBaseContext(resp, req) base.Data = middleware.GetContextData(req.Context()) base.Locale = &translation.MockLocale{} - ctx := &context.APIContext{Base: base} + ctx := &context.APIContext{Base: base, Repo: &context.Repository{}} chiCtx := chi.NewRouteContext() ctx.SetContextValue(chi.RouteCtxKey, chiCtx) return ctx, resp @@ -106,13 +108,13 @@ func MockPrivateContext(t *testing.T, reqPath string) (*context.PrivateContext, // LoadRepo load a repo into a test context. func LoadRepo(t *testing.T, ctx gocontext.Context, repoID int64) { var doer *user_model.User - repo := &context.Repository{} + var repo *context.Repository switch ctx := ctx.(type) { case *context.Context: - ctx.Repo = repo + repo = ctx.Repo doer = ctx.Doer case *context.APIContext: - ctx.Repo = repo + repo = ctx.Repo doer = ctx.Doer default: assert.FailNow(t, "context is not *context.Context or *context.APIContext") @@ -140,15 +142,17 @@ func LoadRepoCommit(t *testing.T, ctx gocontext.Context) { } gitRepo, err := gitrepo.OpenRepository(ctx, repo.Repository) - assert.NoError(t, err) + require.NoError(t, err) defer gitRepo.Close() - branch, err := gitRepo.GetHEADBranch() - assert.NoError(t, err) - assert.NotNil(t, branch) - if branch != nil { - repo.Commit, err = gitRepo.GetBranchCommit(branch.Name) - assert.NoError(t, err) + + if repo.RefFullName == "" { + repo.RefFullName = git_module.RefNameFromBranch(repo.Repository.DefaultBranch) } + if repo.RefFullName.IsPull() { + repo.BranchName = repo.RefFullName.ShortName() + } + repo.Commit, err = gitRepo.GetCommit(repo.RefFullName.String()) + require.NoError(t, err) } // LoadUser load a user into a test context diff --git a/services/repository/files/tree.go b/services/repository/files/tree.go index 6775186afd..9142416347 100644 --- a/services/repository/files/tree.go +++ b/services/repository/files/tree.go @@ -7,9 +7,13 @@ import ( "context" "fmt" "net/url" + "path" + "sort" + "strings" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" @@ -118,3 +122,98 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git } return tree, nil } + +func entryModeString(entryMode git.EntryMode) string { + switch entryMode { + case git.EntryModeBlob: + return "blob" + case git.EntryModeExec: + return "exec" + case git.EntryModeSymlink: + return "symlink" + case git.EntryModeCommit: + return "commit" // submodule + case git.EntryModeTree: + return "tree" + } + return "unknown" +} + +type TreeViewNode struct { + EntryName string `json:"entryName"` + EntryMode string `json:"entryMode"` + FullPath string `json:"fullPath"` + SubmoduleURL string `json:"submoduleUrl,omitempty"` + Children []*TreeViewNode `json:"children,omitempty"` +} + +func (node *TreeViewNode) sortLevel() int { + return util.Iif(node.EntryMode == "tree" || node.EntryMode == "commit", 0, 1) +} + +func newTreeViewNodeFromEntry(ctx context.Context, commit *git.Commit, parentDir string, entry *git.TreeEntry) *TreeViewNode { + node := &TreeViewNode{ + EntryName: entry.Name(), + EntryMode: entryModeString(entry.Mode()), + FullPath: path.Join(parentDir, entry.Name()), + } + + if node.EntryMode == "commit" { + if subModule, err := commit.GetSubModule(node.FullPath); err != nil { + log.Error("GetSubModule: %v", err) + } else if subModule != nil { + submoduleFile := git.NewCommitSubmoduleFile(subModule.URL, entry.ID.String()) + webLink := submoduleFile.SubmoduleWebLink(ctx) + node.SubmoduleURL = webLink.CommitWebLink + } + } + + return node +} + +// sortTreeViewNodes list directory first and with alpha sequence +func sortTreeViewNodes(nodes []*TreeViewNode) { + sort.Slice(nodes, func(i, j int) bool { + a, b := nodes[i].sortLevel(), nodes[j].sortLevel() + if a != b { + return a < b + } + return nodes[i].EntryName < nodes[j].EntryName + }) +} + +func listTreeNodes(ctx context.Context, commit *git.Commit, tree *git.Tree, treePath, subPath string) ([]*TreeViewNode, error) { + entries, err := tree.ListEntries() + if err != nil { + return nil, err + } + + subPathDirName, subPathRemaining, _ := strings.Cut(subPath, "/") + nodes := make([]*TreeViewNode, 0, len(entries)) + for _, entry := range entries { + node := newTreeViewNodeFromEntry(ctx, commit, treePath, entry) + nodes = append(nodes, node) + if entry.IsDir() && subPathDirName == entry.Name() { + subTreePath := treePath + "/" + node.EntryName + if subTreePath[0] == '/' { + subTreePath = subTreePath[1:] + } + subNodes, err := listTreeNodes(ctx, commit, entry.Tree(), subTreePath, subPathRemaining) + if err != nil { + log.Error("listTreeNodes: %v", err) + } else { + node.Children = subNodes + } + } + } + sortTreeViewNodes(nodes) + return nodes, nil +} + +func GetTreeViewNodes(ctx context.Context, commit *git.Commit, treePath, subPath string) ([]*TreeViewNode, error) { + entry, err := commit.GetTreeEntryByPath(treePath) + if err != nil { + return nil, err + } + return listTreeNodes(ctx, commit, entry.Tree(), treePath, subPath) +} diff --git a/services/repository/files/tree_test.go b/services/repository/files/tree_test.go index 0c60fddf7b..8ea54969ce 100644 --- a/services/repository/files/tree_test.go +++ b/services/repository/files/tree_test.go @@ -7,6 +7,7 @@ import ( "testing" "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/services/contexttest" @@ -50,3 +51,51 @@ func TestGetTreeBySHA(t *testing.T) { assert.EqualValues(t, expectedTree, tree) } + +func TestGetTreeViewNodes(t *testing.T) { + unittest.PrepareTestEnv(t) + ctx, _ := contexttest.MockContext(t, "user2/repo1") + ctx.Repo.RefFullName = git.RefNameFromBranch("sub-home-md-img-check") + contexttest.LoadRepo(t, ctx, 1) + contexttest.LoadRepoCommit(t, ctx) + contexttest.LoadUser(t, ctx, 2) + contexttest.LoadGitRepo(t, ctx) + defer ctx.Repo.GitRepo.Close() + + treeNodes, err := GetTreeViewNodes(ctx, ctx.Repo.Commit, "", "") + assert.NoError(t, err) + assert.Equal(t, []*TreeViewNode{ + { + EntryName: "docs", + EntryMode: "tree", + FullPath: "docs", + }, + }, treeNodes) + + treeNodes, err = GetTreeViewNodes(ctx, ctx.Repo.Commit, "", "docs/README.md") + assert.NoError(t, err) + assert.Equal(t, []*TreeViewNode{ + { + EntryName: "docs", + EntryMode: "tree", + FullPath: "docs", + Children: []*TreeViewNode{ + { + EntryName: "README.md", + EntryMode: "blob", + FullPath: "docs/README.md", + }, + }, + }, + }, treeNodes) + + treeNodes, err = GetTreeViewNodes(ctx, ctx.Repo.Commit, "docs", "README.md") + assert.NoError(t, err) + assert.Equal(t, []*TreeViewNode{ + { + EntryName: "README.md", + EntryMode: "blob", + FullPath: "docs/README.md", + }, + }, treeNodes) +} diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 31a8167b4b..f86b90502d 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -1,7 +1,8 @@ {{template "base/head" .}} +{{$showSidebar := and (not .TreeNames) (not .HideRepoInfo) (not .IsBlame)}}
{{template "repo/header" .}} -
+
{{template "base/alert" .}} {{if .Repository.IsArchived}} @@ -16,112 +17,9 @@ {{template "repo/code/recently_pushed_new_branches" .}} - {{$treeNamesLen := len .TreeNames}} - {{$isTreePathRoot := eq $treeNamesLen 0}} - {{$showSidebar := and $isTreePathRoot (not .HideRepoInfo) (not .IsBlame)}}
- {{template "repo/sub_menu" .}} -
-
- {{- /* for repo home (default branch) and /owner/repo/src/{RefType}/{RefShortName} */ -}} - {{- template "repo/branch_dropdown" dict - "Repository" .Repository - "ShowTabBranches" true - "ShowTabTags" true - "CurrentRefType" .RefFullName.RefType - "CurrentRefShortName" .RefFullName.ShortName - "CurrentTreePath" .TreePath - "RefLinkTemplate" "{RepoLink}/src/{RefType}/{RefShortName}/{TreePath}" - "AllowCreateNewRef" .CanCreateBranch - "ShowViewAllRefsEntry" true - -}} - {{if and .CanCompareOrPull .RefFullName.IsBranch (not .Repository.IsArchived)}} - {{$cmpBranch := ""}} - {{if ne .Repository.ID .BaseRepo.ID}} - {{$cmpBranch = printf "%s/%s:" (.Repository.OwnerName|PathEscape) (.Repository.Name|PathEscape)}} - {{end}} - {{$cmpBranch = print $cmpBranch (.BranchName|PathEscapeSegments)}} - {{$compareLink := printf "%s/compare/%s...%s" .BaseRepo.Link (.BaseRepo.DefaultBranch|PathEscapeSegments) $cmpBranch}} - - {{svg "octicon-git-pull-request"}} - - {{end}} - - - {{if $isTreePathRoot}} - {{ctx.Locale.Tr "repo.find_file.go_to_file"}} - {{end}} - - {{if and .CanWriteCode .RefFullName.IsBranch (not .Repository.IsMirror) (not .Repository.IsArchived) (not .IsViewFile)}} - - {{end}} - - {{if and $isTreePathRoot .Repository.IsTemplate}} - - {{ctx.Locale.Tr "repo.use_template"}} - - {{end}} - - {{if not $isTreePathRoot}} - {{$treeNameIdxLast := Eval $treeNamesLen "-" 1}} - - {{StringUtils.EllipsisString .Repository.Name 30}} - {{- range $i, $v := .TreeNames -}} - / - {{- if eq $i $treeNameIdxLast -}} - {{$v}} - - {{- else -}} - {{$p := index $.Paths $i}}{{$v}} - {{- end -}} - {{- end -}} - - {{end}} -
- -
- - {{if $isTreePathRoot}} - {{template "repo/clone_panel" .}} - {{end}} - {{if and (not $isTreePathRoot) (not .IsViewFile) (not .IsBlame)}}{{/* IsViewDirectory (not home), TODO: split the templates, avoid using "if" tricks */}} - - {{svg "octicon-history" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.file_history"}} - - {{end}} -
-
- {{if .IsViewFile}} - {{template "repo/view_file" .}} - {{else if .IsBlame}} - {{template "repo/blame" .}} - {{else}}{{/* IsViewDirectory */}} - {{if $isTreePathRoot}} - {{template "repo/code/upstream_diverging_info" .}} - {{end}} - {{template "repo/view_list" .}} - {{if and .ReadmeExist (or .IsMarkup .IsPlainText)}} - {{template "repo/view_file" .}} - {{end}} - {{end}} + {{template "repo/view_content" .}}
{{if $showSidebar}} diff --git a/templates/repo/view.tmpl b/templates/repo/view.tmpl new file mode 100644 index 0000000000..c3d562003d --- /dev/null +++ b/templates/repo/view.tmpl @@ -0,0 +1,29 @@ +{{template "base/head" .}} +
+ {{template "repo/header" .}} +
+ {{template "base/alert" .}} + + {{if .Repository.IsArchived}} +
+ {{if .Repository.ArchivedUnix.IsZero}} + {{ctx.Locale.Tr "repo.archive.title"}} + {{else}} + {{ctx.Locale.Tr "repo.archive.title_date" (DateUtils.AbsoluteLong .Repository.ArchivedUnix)}} + {{end}} +
+ {{end}} + + {{template "repo/code/recently_pushed_new_branches" .}} + +
+
+ {{template "repo/view_file_tree" .}} +
+
+ {{template "repo/view_content" .}} +
+
+
+
+{{template "base/footer" .}} diff --git a/templates/repo/view_content.tmpl b/templates/repo/view_content.tmpl new file mode 100644 index 0000000000..06e9f8515c --- /dev/null +++ b/templates/repo/view_content.tmpl @@ -0,0 +1,111 @@ +{{$isTreePathRoot := not .TreeNames}} + +{{template "repo/sub_menu" .}} +
+
+ {{if not $isTreePathRoot}} + + {{end}} + + {{template "repo/branch_dropdown" dict + "Repository" .Repository + "ShowTabBranches" true + "ShowTabTags" true + "CurrentRefType" .RefFullName.RefType + "CurrentRefShortName" .RefFullName.ShortName + "CurrentTreePath" .TreePath + "RefLinkTemplate" "{RepoLink}/src/{RefType}/{RefShortName}/{TreePath}" + "AllowCreateNewRef" .CanCreateBranch + "ShowViewAllRefsEntry" true + }} + + {{if and .CanCompareOrPull .RefFullName.IsBranch (not .Repository.IsArchived)}} + {{$cmpBranch := ""}} + {{if ne .Repository.ID .BaseRepo.ID}} + {{$cmpBranch = printf "%s/%s:" (.Repository.OwnerName|PathEscape) (.Repository.Name|PathEscape)}} + {{end}} + {{$cmpBranch = print $cmpBranch (.BranchName|PathEscapeSegments)}} + {{$compareLink := printf "%s/compare/%s...%s" .BaseRepo.Link (.BaseRepo.DefaultBranch|PathEscapeSegments) $cmpBranch}} + + {{svg "octicon-git-pull-request"}} + + {{end}} + + + {{if $isTreePathRoot}} + {{ctx.Locale.Tr "repo.find_file.go_to_file"}} + {{end}} + + {{if and .CanWriteCode .RefFullName.IsBranch (not .Repository.IsMirror) (not .Repository.IsArchived) (not .IsViewFile)}} + + {{end}} + + {{if and $isTreePathRoot .Repository.IsTemplate}} + + {{ctx.Locale.Tr "repo.use_template"}} + + {{end}} + + {{if not $isTreePathRoot}} + {{$treeNameIdxLast := Eval (len .TreeNames) "-" 1}} + + {{StringUtils.EllipsisString .Repository.Name 30}} + {{- range $i, $v := .TreeNames -}} + / + {{- if eq $i $treeNameIdxLast -}} + {{$v}} + + {{- else -}} + {{$p := index $.Paths $i}}{{$v}} + {{- end -}} + {{- end -}} + + {{end}} +
+ +
+ + {{if $isTreePathRoot}} + {{template "repo/clone_panel" .}} + {{end}} + {{if and (not $isTreePathRoot) (not .IsViewFile) (not .IsBlame)}}{{/* IsViewDirectory (not home), TODO: split the templates, avoid using "if" tricks */}} + + {{svg "octicon-history" 16 "tw-mr-2"}}{{ctx.Locale.Tr "repo.file_history"}} + + {{end}} +
+
+{{if .IsViewFile}} + {{template "repo/view_file" .}} +{{else if .IsBlame}} + {{template "repo/blame" .}} +{{else}}{{/* IsViewDirectory */}} + {{if $isTreePathRoot}} + {{template "repo/code/upstream_diverging_info" .}} + {{end}} + {{template "repo/view_list" .}} + {{if and .ReadmeExist (or .IsMarkup .IsPlainText)}} + {{template "repo/view_file" .}} + {{end}} +{{end}} diff --git a/templates/repo/view_file_tree.tmpl b/templates/repo/view_file_tree.tmpl new file mode 100644 index 0000000000..6e5d504a47 --- /dev/null +++ b/templates/repo/view_file_tree.tmpl @@ -0,0 +1,15 @@ +
+ + Files +
+ +{{/* TODO: Dynamically move components such as refSelector and createPR here */}} +
diff --git a/web_src/css/repo/home.css b/web_src/css/repo/home.css index 96551979ea..219be77adb 100644 --- a/web_src/css/repo/home.css +++ b/web_src/css/repo/home.css @@ -49,6 +49,21 @@ } } +.repo-view-container { + display: flex; + gap: var(--page-spacing); +} + +.repo-view-container .repo-view-file-tree-container { + flex: 0 1 15%; + min-width: 0; + max-height: 100vh; +} + +.repo-view-content { + flex: 1; +} + .language-stats { display: flex; gap: 2px; diff --git a/web_src/js/components/ViewFileTree.vue b/web_src/js/components/ViewFileTree.vue new file mode 100644 index 0000000000..1820c47e7a --- /dev/null +++ b/web_src/js/components/ViewFileTree.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/web_src/js/components/ViewFileTreeItem.vue b/web_src/js/components/ViewFileTreeItem.vue new file mode 100644 index 0000000000..4dffc86a1b --- /dev/null +++ b/web_src/js/components/ViewFileTreeItem.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/web_src/js/features/repo-view-file-tree.ts b/web_src/js/features/repo-view-file-tree.ts new file mode 100644 index 0000000000..f52b64cc51 --- /dev/null +++ b/web_src/js/features/repo-view-file-tree.ts @@ -0,0 +1,37 @@ +import {createApp} from 'vue'; +import {toggleElem} from '../utils/dom.ts'; +import {POST} from '../modules/fetch.ts'; +import ViewFileTree from '../components/ViewFileTree.vue'; +import {registerGlobalEventFunc} from '../modules/observer.ts'; + +const {appSubUrl} = window.config; + +async function toggleSidebar(btn: HTMLElement) { + const elToggleShow = document.querySelector('.repo-view-file-tree-toggle-show'); + const elFileTreeContainer = document.querySelector('.repo-view-file-tree-container'); + const shouldShow = btn.getAttribute('data-toggle-action') === 'show'; + toggleElem(elFileTreeContainer, shouldShow); + toggleElem(elToggleShow, !shouldShow); + + // FIXME: need to remove "full height" style from parent element + + if (!elFileTreeContainer.hasAttribute('data-user-is-signed-in')) return; + await POST(`${appSubUrl}/user/settings/update_preferences`, { + data: {codeViewShowFileTree: shouldShow}, + }); +} + +export async function initRepoViewFileTree() { + const sidebar = document.querySelector('.repo-view-file-tree-container'); + const repoViewContent = document.querySelector('.repo-view-content'); + if (!sidebar || !repoViewContent) return; + + registerGlobalEventFunc('click', 'onRepoViewFileTreeToggle', toggleSidebar); + + const fileTree = sidebar.querySelector('#view-file-tree'); + createApp(ViewFileTree, { + repoLink: fileTree.getAttribute('data-repo-link'), + treePath: fileTree.getAttribute('data-tree-path'), + currentRefNameSubURL: fileTree.getAttribute('data-current-ref-name-sub-url'), + }).mount(fileTree); +} diff --git a/web_src/js/index.ts b/web_src/js/index.ts index 2e44ef826a..839a160168 100644 --- a/web_src/js/index.ts +++ b/web_src/js/index.ts @@ -64,6 +64,7 @@ import {initFootLanguageMenu, initGlobalDropdown, initGlobalInput, initGlobalTab import {initGlobalButtonClickOnEnter, initGlobalButtons, initGlobalDeleteButton} from './features/common-button.ts'; import {initGlobalComboMarkdownEditor, initGlobalEnterQuickSubmit, initGlobalFormDirtyLeaveConfirm} from './features/common-form.ts'; import {callInitFunctions} from './modules/init.ts'; +import {initRepoViewFileTree} from './features/repo-view-file-tree.ts'; initGiteaFomantic(); initSubmitEventPolyfill(); @@ -139,6 +140,7 @@ onDomReady(() => { initRepoRelease, initRepoReleaseNew, initRepoTopicBar, + initRepoViewFileTree, initRepoWikiForm, initRepository, initRepositoryActionView, diff --git a/web_src/js/svg.ts b/web_src/js/svg.ts index 8316cbcf85..7b377e1ab4 100644 --- a/web_src/js/svg.ts +++ b/web_src/js/svg.ts @@ -29,6 +29,7 @@ import octiconFile from '../../public/assets/img/svg/octicon-file.svg'; import octiconFileDirectoryFill from '../../public/assets/img/svg/octicon-file-directory-fill.svg'; import octiconFileDirectoryOpenFill from '../../public/assets/img/svg/octicon-file-directory-open-fill.svg'; import octiconFileSubmodule from '../../public/assets/img/svg/octicon-file-submodule.svg'; +import octiconFileSymlinkFile from '../../public/assets/img/svg/octicon-file-symlink-file.svg'; import octiconFilter from '../../public/assets/img/svg/octicon-filter.svg'; import octiconGear from '../../public/assets/img/svg/octicon-gear.svg'; import octiconGitBranch from '../../public/assets/img/svg/octicon-git-branch.svg'; @@ -107,6 +108,7 @@ const svgs = { 'octicon-file-directory-fill': octiconFileDirectoryFill, 'octicon-file-directory-open-fill': octiconFileDirectoryOpenFill, 'octicon-file-submodule': octiconFileSubmodule, + 'octicon-file-symlink-file': octiconFileSymlinkFile, 'octicon-filter': octiconFilter, 'octicon-gear': octiconGear, 'octicon-git-branch': octiconGitBranch, From 7e8168f555b0a463866afcc10e9fddc34d363811 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sat, 15 Mar 2025 17:45:37 +0100 Subject: [PATCH 227/655] Fix cannot delete runners via the modal dialog (#33895) delete-button and show-modal class are conflicting Closes #33894 --- templates/shared/actions/runner_edit.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/shared/actions/runner_edit.tmpl b/templates/shared/actions/runner_edit.tmpl index 54250f830b..d452d69f7a 100644 --- a/templates/shared/actions/runner_edit.tmpl +++ b/templates/shared/actions/runner_edit.tmpl @@ -40,7 +40,7 @@
-
From 3e2e7bf4e540765d2138cf058f38a494a534c066 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 15 Mar 2025 10:23:18 -0700 Subject: [PATCH 228/655] Add lock for a repository pull mirror (#33876) Fix #33647 This PR add a global lock for repository pulling mirror. --- services/mirror/mirror_pull.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index 57dde25b3b..658747e7c8 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/git" giturl "code.gitea.io/gitea/modules/git/url" "code.gitea.io/gitea/modules/gitrepo" + "code.gitea.io/gitea/modules/globallock" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" @@ -425,6 +426,10 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo return parseRemoteUpdateOutput(output, m.GetRemoteName()), true } +func getRepoPullMirrorLockKey(repoID int64) string { + return fmt.Sprintf("repo_pull_mirror_%d", repoID) +} + // SyncPullMirror starts the sync of the pull mirror and schedules the next run. func SyncPullMirror(ctx context.Context, repoID int64) bool { log.Trace("SyncMirrors [repo_id: %v]", repoID) @@ -437,6 +442,13 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool { log.Error("PANIC whilst SyncMirrors[repo_id: %d] Panic: %v\nStacktrace: %s", repoID, err, log.Stack(2)) }() + releaser, err := globallock.Lock(ctx, getRepoPullMirrorLockKey(repoID)) + if err != nil { + log.Error("globallock.Lock(): %v", err) + return false + } + defer releaser() + m, err := repo_model.GetMirrorByRepoID(ctx, repoID) if err != nil { log.Error("SyncMirrors [repo_id: %v]: unable to GetMirrorByRepoID: %v", repoID, err) From 30b13942f09e8d92a4ff2e3a5feb3123941bbb47 Mon Sep 17 00:00:00 2001 From: Job Date: Sat, 15 Mar 2025 18:49:06 +0100 Subject: [PATCH 229/655] Give organisation members access to organisation feeds (#33508) Currently the organisation feed only includes items for public repositories (for non-administrators). This pull requests adds notifications from private repositories to the organisation-feed (for accounts that have access to the organisation). Feed-items only get shown for repositories where the users team(s) should have access to, this filtering seems to get done by some existing code. Needs some tests, but am unsure where/how to add them. Before: ![image](https://github.com/user-attachments/assets/8b63f430-227a-4b19-ad1a-f6f5175de301) After: ![image](https://github.com/user-attachments/assets/b439ce0e-4946-421c-a399-421806c7a6d8) --------- Co-authored-by: wxiaoguang --- models/unittest/fixtures_loader.go | 82 +++++++++++++-------- routers/web/feed/profile.go | 14 +++- routers/web/feed/profile_test.go | 38 ++++++++++ tests/integration/actions_job_test.go | 17 +---- tests/integration/actions_log_test.go | 7 +- tests/integration/api_repo_file_get_test.go | 2 - 6 files changed, 110 insertions(+), 50 deletions(-) create mode 100644 routers/web/feed/profile_test.go diff --git a/models/unittest/fixtures_loader.go b/models/unittest/fixtures_loader.go index 14686caf63..674f5cbe54 100644 --- a/models/unittest/fixtures_loader.go +++ b/models/unittest/fixtures_loader.go @@ -12,13 +12,17 @@ import ( "slices" "strings" + "code.gitea.io/gitea/models/db" + "gopkg.in/yaml.v3" "xorm.io/xorm" "xorm.io/xorm/schemas" ) -type fixtureItem struct { - tableName string +type FixtureItem struct { + fileFullPath string + tableName string + tableNameQuoted string sqlInserts []string sqlInsertArgs [][]any @@ -27,10 +31,11 @@ type fixtureItem struct { } type fixturesLoaderInternal struct { + xormEngine *xorm.Engine + xormTableNames map[string]bool db *sql.DB dbType schemas.DBType - files []string - fixtures map[string]*fixtureItem + fixtures map[string]*FixtureItem quoteObject func(string) string paramPlaceholder func(idx int) string } @@ -59,29 +64,27 @@ func (f *fixturesLoaderInternal) preprocessFixtureRow(row []map[string]any) (err return nil } -func (f *fixturesLoaderInternal) prepareFixtureItem(file string) (_ *fixtureItem, err error) { - fixture := &fixtureItem{} - fixture.tableName, _, _ = strings.Cut(filepath.Base(file), ".") +func (f *fixturesLoaderInternal) prepareFixtureItem(fixture *FixtureItem) (err error) { fixture.tableNameQuoted = f.quoteObject(fixture.tableName) if f.dbType == schemas.MSSQL { fixture.mssqlHasIdentityColumn, err = f.mssqlTableHasIdentityColumn(f.db, fixture.tableName) if err != nil { - return nil, err + return err } } - data, err := os.ReadFile(file) + data, err := os.ReadFile(fixture.fileFullPath) if err != nil { - return nil, fmt.Errorf("failed to read file %q: %w", file, err) + return fmt.Errorf("failed to read file %q: %w", fixture.fileFullPath, err) } var rows []map[string]any if err = yaml.Unmarshal(data, &rows); err != nil { - return nil, fmt.Errorf("failed to unmarshal yaml data from %q: %w", file, err) + return fmt.Errorf("failed to unmarshal yaml data from %q: %w", fixture.fileFullPath, err) } if err = f.preprocessFixtureRow(rows); err != nil { - return nil, fmt.Errorf("failed to preprocess fixture rows from %q: %w", file, err) + return fmt.Errorf("failed to preprocess fixture rows from %q: %w", fixture.fileFullPath, err) } var sqlBuf []byte @@ -107,16 +110,14 @@ func (f *fixturesLoaderInternal) prepareFixtureItem(file string) (_ *fixtureItem sqlBuf = sqlBuf[:0] sqlArguments = sqlArguments[:0] } - return fixture, nil + return nil } -func (f *fixturesLoaderInternal) loadFixtures(tx *sql.Tx, file string) (err error) { - fixture := f.fixtures[file] - if fixture == nil { - if fixture, err = f.prepareFixtureItem(file); err != nil { +func (f *fixturesLoaderInternal) loadFixtures(tx *sql.Tx, fixture *FixtureItem) (err error) { + if fixture.tableNameQuoted == "" { + if err = f.prepareFixtureItem(fixture); err != nil { return err } - f.fixtures[file] = fixture } _, err = tx.Exec(fmt.Sprintf("DELETE FROM %s", fixture.tableNameQuoted)) // sqlite3 doesn't support truncate @@ -147,15 +148,26 @@ func (f *fixturesLoaderInternal) Load() error { } defer func() { _ = tx.Rollback() }() - for _, file := range f.files { - if err := f.loadFixtures(tx, file); err != nil { - return fmt.Errorf("failed to load fixtures from %s: %w", file, err) + for _, fixture := range f.fixtures { + if !f.xormTableNames[fixture.tableName] { + continue + } + if err := f.loadFixtures(tx, fixture); err != nil { + return fmt.Errorf("failed to load fixtures from %s: %w", fixture.fileFullPath, err) } } - return tx.Commit() + if err = tx.Commit(); err != nil { + return err + } + for xormTableName := range f.xormTableNames { + if f.fixtures[xormTableName] == nil { + _, _ = f.xormEngine.Exec("DELETE FROM `" + xormTableName + "`") + } + } + return nil } -func FixturesFileFullPaths(dir string, files []string) ([]string, error) { +func FixturesFileFullPaths(dir string, files []string) (map[string]*FixtureItem, error) { if files != nil && len(files) == 0 { return nil, nil // load nothing } @@ -169,20 +181,25 @@ func FixturesFileFullPaths(dir string, files []string) ([]string, error) { files = append(files, e.Name()) } } - for i, file := range files { - if !filepath.IsAbs(file) { - files[i] = filepath.Join(dir, file) + fixtureItems := map[string]*FixtureItem{} + for _, file := range files { + fileFillPath := file + if !filepath.IsAbs(fileFillPath) { + fileFillPath = filepath.Join(dir, file) } + tableName, _, _ := strings.Cut(filepath.Base(file), ".") + fixtureItems[tableName] = &FixtureItem{fileFullPath: fileFillPath, tableName: tableName} } - return files, nil + return fixtureItems, nil } func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, error) { - files, err := FixturesFileFullPaths(opts.Dir, opts.Files) + fixtureItems, err := FixturesFileFullPaths(opts.Dir, opts.Files) if err != nil { return nil, fmt.Errorf("failed to get fixtures files: %w", err) } - f := &fixturesLoaderInternal{db: x.DB().DB, dbType: x.Dialect().URI().DBType, files: files, fixtures: map[string]*fixtureItem{}} + + f := &fixturesLoaderInternal{xormEngine: x, db: x.DB().DB, dbType: x.Dialect().URI().DBType, fixtures: fixtureItems} switch f.dbType { case schemas.SQLITE: f.quoteObject = func(s string) string { return fmt.Sprintf(`"%s"`, s) } @@ -197,5 +214,12 @@ func NewFixturesLoader(x *xorm.Engine, opts FixturesOptions) (FixturesLoader, er f.quoteObject = func(s string) string { return fmt.Sprintf("[%s]", s) } f.paramPlaceholder = func(idx int) string { return "?" } } + + xormBeans, _ := db.NamesToBean() + f.xormTableNames = map[string]bool{} + for _, bean := range xormBeans { + f.xormTableNames[db.TableName(bean)] = true + } + return f, nil } diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go index 4ec46e302a..cecf9d409a 100644 --- a/routers/web/feed/profile.go +++ b/routers/web/feed/profile.go @@ -7,6 +7,7 @@ import ( "time" activities_model "code.gitea.io/gitea/models/activities" + "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/renderhelper" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/services/context" @@ -28,12 +29,23 @@ func ShowUserFeedAtom(ctx *context.Context) { // showUserFeed show user activity as RSS / Atom feed func showUserFeed(ctx *context.Context, formatType string) { includePrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) + isOrganisation := ctx.ContextUser.IsOrganization() + if ctx.IsSigned && isOrganisation && !includePrivate { + // When feed is requested by a member of the organization, + // include the private repo's the member has access to. + isOrgMember, err := organization.IsOrganizationMember(ctx, ctx.ContextUser.ID, ctx.Doer.ID) + if err != nil { + ctx.ServerError("IsOrganizationMember", err) + return + } + includePrivate = isOrgMember + } actions, _, err := feed_service.GetFeeds(ctx, activities_model.GetFeedsOptions{ RequestedUser: ctx.ContextUser, Actor: ctx.Doer, IncludePrivate: includePrivate, - OnlyPerformedBy: !ctx.ContextUser.IsOrganization(), + OnlyPerformedBy: !isOrganisation, IncludeDeleted: false, Date: ctx.FormString("date"), }) diff --git a/routers/web/feed/profile_test.go b/routers/web/feed/profile_test.go new file mode 100644 index 0000000000..a0f1509269 --- /dev/null +++ b/routers/web/feed/profile_test.go @@ -0,0 +1,38 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT +package feed_test + +import ( + "testing" + + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/routers/web/feed" + "code.gitea.io/gitea/services/contexttest" + + "github.com/stretchr/testify/assert" +) + +func TestMain(m *testing.M) { + unittest.MainTest(m) +} + +func TestCheckGetOrgFeedsAsOrgMember(t *testing.T) { + unittest.PrepareTestEnv(t) + t.Run("OrgMember", func(t *testing.T) { + ctx, resp := contexttest.MockContext(t, "org3.atom") + ctx.ContextUser = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + contexttest.LoadUser(t, ctx, 2) + ctx.IsSigned = true + feed.ShowUserFeedAtom(ctx) + assert.Contains(t, resp.Body.String(), "") // Should contain 1 private entry + }) + t.Run("NonOrgMember", func(t *testing.T) { + ctx, resp := contexttest.MockContext(t, "org3.atom") + ctx.ContextUser = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) + contexttest.LoadUser(t, ctx, 5) + ctx.IsSigned = true + feed.ShowUserFeedAtom(ctx) + assert.NotContains(t, resp.Body.String(), "") // Should not contain any entries + }) +} diff --git a/tests/integration/actions_job_test.go b/tests/integration/actions_job_test.go index caab215cee..89c93e7a75 100644 --- a/tests/integration/actions_job_test.go +++ b/tests/integration/actions_job_test.go @@ -166,9 +166,6 @@ jobs: } }) } - - httpContext := NewAPITestContext(t, user2.Name, apiRepo.Name, auth_model.AccessTokenScopeWriteRepository) - doAPIDeleteRepository(httpContext)(t) }) } @@ -348,9 +345,6 @@ jobs: } }) } - - httpContext := NewAPITestContext(t, user2.Name, apiRepo.Name, auth_model.AccessTokenScopeWriteRepository) - doAPIDeleteRepository(httpContext)(t) }) } @@ -434,8 +428,6 @@ jobs: assert.Equal(t, setting.Actions.DefaultActionsURL.URL(), gtCtx["gitea_default_actions_url"].GetStringValue()) token := gtCtx["token"].GetStringValue() assert.Equal(t, actionTask.TokenLastEight, token[len(token)-8:]) - - doAPIDeleteRepository(user2APICtx)(t) }) } @@ -543,12 +535,14 @@ jobs: err = actions_service.CleanupEphemeralRunners(t.Context()) assert.NoError(t, err) - runner.client.runnerServiceClient.UpdateTask(t.Context(), connect.NewRequest(&runnerv1.UpdateTaskRequest{ + _, err = runner.client.runnerServiceClient.UpdateTask(t.Context(), connect.NewRequest(&runnerv1.UpdateTaskRequest{ State: &runnerv1.TaskState{ Id: actionTask.ID, Result: runnerv1.Result_RESULT_SUCCESS, }, })) + assert.NoError(t, err) + resp, err = runner.client.runnerServiceClient.FetchTask(t.Context(), connect.NewRequest(&runnerv1.FetchTaskRequest{ TasksVersion: 0, })) @@ -561,7 +555,7 @@ jobs: assert.Error(t, err) assert.Nil(t, resp) - // create an runner that picks a job and get force cancelled + // create a runner that picks a job and get force cancelled runnerToBeRemoved := newMockRunner() runnerToBeRemoved.registerAsRepoRunner(t, baseRepo.OwnerName, baseRepo.Name, "mock-runner-to-be-removed", []string{"ubuntu-latest"}, true) @@ -583,9 +577,6 @@ jobs: assert.NoError(t, err) unittest.AssertNotExistsBean(t, &actions_model.ActionRunner{ID: runnerToRemove.ID}) - - // this cleanup is required to allow further tests to pass - doAPIDeleteRepository(user2APICtx)(t) }) } diff --git a/tests/integration/actions_log_test.go b/tests/integration/actions_log_test.go index 8f10226721..5e99e5026d 100644 --- a/tests/integration/actions_log_test.go +++ b/tests/integration/actions_log_test.go @@ -35,7 +35,7 @@ func TestDownloadTaskLogs(t *testing.T) { { treePath: ".gitea/workflows/download-task-logs-zstd.yml", fileContent: `name: download-task-logs-zstd -on: +on: push: paths: - '.gitea/workflows/download-task-logs-zstd.yml' @@ -67,7 +67,7 @@ jobs: { treePath: ".gitea/workflows/download-task-logs-no-zstd.yml", fileContent: `name: download-task-logs-no-zstd -on: +on: push: paths: - '.gitea/workflows/download-task-logs-no-zstd.yml' @@ -152,8 +152,5 @@ jobs: resetFunc() }) } - - httpContext := NewAPITestContext(t, user2.Name, repo.Name, auth_model.AccessTokenScopeWriteRepository) - doAPIDeleteRepository(httpContext)(t) }) } diff --git a/tests/integration/api_repo_file_get_test.go b/tests/integration/api_repo_file_get_test.go index 2f897093ee..379851b689 100644 --- a/tests/integration/api_repo_file_get_test.go +++ b/tests/integration/api_repo_file_get_test.go @@ -44,8 +44,6 @@ func TestAPIGetRawFileOrLFS(t *testing.T) { reqLFS := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/media/"+lfs) respLFS := MakeRequestNilResponseRecorder(t, reqLFS, http.StatusOK) assert.Equal(t, testFileSizeSmall, respLFS.Length) - - doAPIDeleteRepository(httpContext) }) }) } From 10513df1bf1edd43f175991c9ce79967b001bc27 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 15 Mar 2025 11:55:58 -0700 Subject: [PATCH 230/655] Add missing translation (#33900) --- options/locale/locale_en-US.ini | 1 + templates/repo/view_file_tree.tmpl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index f1ce4b244f..3ee7c8818c 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -113,6 +113,7 @@ copy_type_unsupported = This file type cannot be copied write = Write preview = Preview loading = Loading… +files = Files error = Error error404 = The page you are trying to reach either does not exist or you are not authorized to view it. diff --git a/templates/repo/view_file_tree.tmpl b/templates/repo/view_file_tree.tmpl index 6e5d504a47..ce9b2e4d11 100644 --- a/templates/repo/view_file_tree.tmpl +++ b/templates/repo/view_file_tree.tmpl @@ -4,7 +4,7 @@ data-tooltip-content="{{ctx.Locale.Tr "repo.diff.hide_file_tree"}}"> {{svg "octicon-sidebar-expand"}} - Files + {{ctx.Locale.Tr "files"}}
{{/* TODO: Dynamically move components such as refSelector and createPR here */}} From f11ac6bf3cb45e01080b1ec5bd9cbdd1ee5cda92 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sun, 16 Mar 2025 00:36:54 +0000 Subject: [PATCH 231/655] [skip ci] Updated translations via Crowdin --- options/locale/locale_pt-PT.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index bcb420b5ea..26a1d7708e 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -1407,6 +1407,7 @@ commits.signed_by_untrusted_user_unmatched=Assinado por um utilizador não fiáv commits.gpg_key_id=ID da chave GPG commits.ssh_key_fingerprint=Identificação digital da chave SSH commits.view_path=Vista neste ponto do histórico +commits.view_file_diff=Ver as modificações deste ficheiro neste cometimento commit.operations=Operações commit.revert=Reverter @@ -1941,6 +1942,7 @@ pulls.outdated_with_base_branch=Este ramo é obsoleto em relação ao ramo base pulls.close=Encerrar pedido de integração pulls.closed_at=`fechou este pedido de integração %[2]s` pulls.reopened_at=`reabriu este pedido de integração %[2]s` +pulls.cmd_instruction_hint=Ver instruções para a linha de comandos pulls.cmd_instruction_checkout_title=Checkout pulls.cmd_instruction_checkout_desc=A partir do seu repositório, crie um novo ramo e teste nele as modificações. pulls.cmd_instruction_merge_title=Integrar From 0056fdb94201f54fcbb51d741a68b04bf41213fc Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 15 Mar 2025 19:48:59 -0700 Subject: [PATCH 232/655] Move git references checking to gitrepo packages to reduce expose of repository path (#33891) --- modules/git/repo_tag.go | 6 ------ modules/gitrepo/branch.go | 18 ++++++++++++++++++ modules/gitrepo/tag.go | 15 +++++++++++++++ routers/api/v1/repo/branch.go | 4 ++-- routers/api/v1/repo/pull.go | 2 +- routers/api/v1/repo/repo.go | 2 +- routers/private/hook_pre_receive.go | 5 +++-- routers/web/repo/compare.go | 8 ++++---- routers/web/repo/issue_comment.go | 3 ++- routers/web/repo/issue_view.go | 3 ++- routers/web/repo/pull.go | 6 +++--- routers/web/repo/release.go | 3 ++- routers/web/repo/setting/default_branch.go | 2 +- services/agit/agit.go | 5 +++-- services/automerge/automerge.go | 6 +++--- services/context/api.go | 4 ++-- services/context/repo.go | 6 +++--- services/pull/commit_status.go | 5 ++--- services/pull/protected_branch.go | 5 +++-- services/pull/pull.go | 2 +- services/pull/temp_repo.go | 3 ++- services/release/release.go | 2 +- services/repository/branch.go | 8 ++++---- services/wiki/wiki.go | 2 +- 24 files changed, 79 insertions(+), 46 deletions(-) create mode 100644 modules/gitrepo/tag.go diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go index d653b0e2e6..c74618471a 100644 --- a/modules/git/repo_tag.go +++ b/modules/git/repo_tag.go @@ -5,7 +5,6 @@ package git import ( - "context" "fmt" "io" "strings" @@ -17,11 +16,6 @@ import ( // TagPrefix tags prefix path on the repository const TagPrefix = "refs/tags/" -// IsTagExist returns true if given tag exists in the repository. -func IsTagExist(ctx context.Context, repoPath, name string) bool { - return IsReferenceExist(ctx, repoPath, TagPrefix+name) -} - // CreateTag create one tag in the repository func (repo *Repository) CreateTag(name, revision string) error { _, _, err := NewCommand("tag").AddDashesAndList(name, revision).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) diff --git a/modules/gitrepo/branch.go b/modules/gitrepo/branch.go index 3336036248..9c4bdc5bdf 100644 --- a/modules/gitrepo/branch.go +++ b/modules/gitrepo/branch.go @@ -47,3 +47,21 @@ func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) { func GetWikiDefaultBranch(ctx context.Context, repo Repository) (string, error) { return git.GetDefaultBranch(ctx, wikiPath(repo)) } + +// IsReferenceExist returns true if given reference exists in the repository. +func IsReferenceExist(ctx context.Context, repo Repository, name string) bool { + return git.IsReferenceExist(ctx, repoPath(repo), name) +} + +func IsWikiReferenceExist(ctx context.Context, repo Repository, name string) bool { + return git.IsReferenceExist(ctx, wikiPath(repo), name) +} + +// IsBranchExist returns true if given branch exists in the repository. +func IsBranchExist(ctx context.Context, repo Repository, name string) bool { + return IsReferenceExist(ctx, repo, git.BranchPrefix+name) +} + +func IsWikiBranchExist(ctx context.Context, repo Repository, name string) bool { + return IsWikiReferenceExist(ctx, repo, git.BranchPrefix+name) +} diff --git a/modules/gitrepo/tag.go b/modules/gitrepo/tag.go new file mode 100644 index 0000000000..58ed204a99 --- /dev/null +++ b/modules/gitrepo/tag.go @@ -0,0 +1,15 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitrepo + +import ( + "context" + + "code.gitea.io/gitea/modules/git" +) + +// IsTagExist returns true if given tag exists in the repository. +func IsTagExist(ctx context.Context, repo Repository, name string) bool { + return IsReferenceExist(ctx, repo, git.TagPrefix+name) +} diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index f866f2048e..9c6e572fb4 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -227,7 +227,7 @@ func CreateBranch(ctx *context.APIContext) { return } } else if len(opt.OldBranchName) > 0 { //nolint - if ctx.Repo.GitRepo.IsBranchExist(opt.OldBranchName) { //nolint + if gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, opt.OldBranchName) { //nolint oldCommit, err = ctx.Repo.GitRepo.GetBranchCommit(opt.OldBranchName) //nolint if err != nil { ctx.APIErrorInternal(err) @@ -1019,7 +1019,7 @@ func EditBranchProtection(ctx *context.APIContext) { isPlainRule := !git_model.IsRuleNameSpecial(bpName) var isBranchExist bool if isPlainRule { - isBranchExist = git.IsBranchExist(ctx.Req.Context(), ctx.Repo.Repository.RepoPath(), bpName) + isBranchExist = gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, bpName) } if isBranchExist { diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 2f32f01c4f..f5d0e37c65 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -742,7 +742,7 @@ func EditPullRequest(ctx *context.APIContext) { // change pull target branch if !pr.HasMerged && len(form.Base) != 0 && form.Base != pr.BaseBranch { - if !ctx.Repo.GitRepo.IsBranchExist(form.Base) { + if !gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, form.Base) { ctx.APIError(http.StatusNotFound, fmt.Errorf("new base '%s' not exist", form.Base)) return } diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 5ef510fd84..3d638cb05e 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -734,7 +734,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err // Default branch only updated if changed and exist or the repository is empty updateRepoLicense := false - if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || ctx.Repo.GitRepo.IsBranchExist(*opts.DefaultBranch)) { + if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, *opts.DefaultBranch)) { if !repo.IsEmpty { if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, *opts.DefaultBranch); err != nil { ctx.APIErrorInternal(err) diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index c64033d9e2..ae23abc542 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -16,6 +16,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/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/web" @@ -447,13 +448,13 @@ func preReceiveFor(ctx *preReceiveContext, refFullName git.RefName) { baseBranchName := refFullName.ForBranchName() baseBranchExist := false - if ctx.Repo.GitRepo.IsBranchExist(baseBranchName) { + if gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, baseBranchName) { baseBranchExist = true } if !baseBranchExist { for p, v := range baseBranchName { - if v == '/' && ctx.Repo.GitRepo.IsBranchExist(baseBranchName[:p]) && p != len(baseBranchName)-1 { + if v == '/' && gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, baseBranchName[:p]) && p != len(baseBranchName)-1 { baseBranchExist = true break } diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index a01cd753bf..6cea95e387 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -301,8 +301,8 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { // Check if base branch is valid. baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(ci.BaseBranch) - baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(ci.BaseBranch) - baseIsTag := ctx.Repo.GitRepo.IsTagExist(ci.BaseBranch) + baseIsBranch := gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, ci.BaseBranch) + baseIsTag := gitrepo.IsTagExist(ctx, ctx.Repo.Repository, ci.BaseBranch) if !baseIsCommit && !baseIsBranch && !baseIsTag { // Check if baseBranch is short sha commit hash @@ -504,8 +504,8 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { // Check if head branch is valid. headIsCommit := ci.HeadGitRepo.IsCommitExist(ci.HeadBranch) - headIsBranch := ci.HeadGitRepo.IsBranchExist(ci.HeadBranch) - headIsTag := ci.HeadGitRepo.IsTagExist(ci.HeadBranch) + headIsBranch := gitrepo.IsBranchExist(ctx, ci.HeadRepo, ci.HeadBranch) + headIsTag := gitrepo.IsTagExist(ctx, ci.HeadRepo, ci.HeadBranch) if !headIsCommit && !headIsBranch && !headIsTag { // Check if headBranch is short sha commit hash if headCommit, _ := ci.HeadGitRepo.GetCommit(ci.HeadBranch); headCommit != nil { diff --git a/routers/web/repo/issue_comment.go b/routers/web/repo/issue_comment.go index bc84950701..45463200f6 100644 --- a/routers/web/repo/issue_comment.go +++ b/routers/web/repo/issue_comment.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models/renderhelper" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup/markdown" repo_module "code.gitea.io/gitea/modules/repository" @@ -117,7 +118,7 @@ func NewComment(ctx *context.Context) { ctx.ServerError("Unable to load head repo", err) return } - if ok := git.IsBranchExist(ctx, pull.HeadRepo.RepoPath(), pull.BaseBranch); !ok { + if ok := gitrepo.IsBranchExist(ctx, pull.HeadRepo, pull.BaseBranch); !ok { // todo localize ctx.JSONError("The origin branch is delete, cannot reopen.") return diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index 37e1b27931..b312f1260a 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -24,6 +24,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/emoji" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" @@ -526,7 +527,7 @@ func preparePullViewDeleteBranch(ctx *context.Context, issue *issues_model.Issue pull := issue.PullRequest isPullBranchDeletable := canDelete && pull.HeadRepo != nil && - git.IsBranchExist(ctx, pull.HeadRepo.RepoPath(), pull.HeadBranch) && + gitrepo.IsBranchExist(ctx, pull.HeadRepo, pull.HeadBranch) && (!pull.HasMerged || ctx.Data["HeadBranchCommitID"] == ctx.Data["PullHeadCommitID"]) if isPullBranchDeletable && pull.HasMerged { diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 9eb6917617..e12798f93d 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -347,7 +347,7 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C defer baseGitRepo.Close() } - if !baseGitRepo.IsBranchExist(pull.BaseBranch) { + if !gitrepo.IsBranchExist(ctx, pull.BaseRepo, pull.BaseBranch) { ctx.Data["BaseBranchNotExist"] = true ctx.Data["IsPullRequestBroken"] = true ctx.Data["BaseTarget"] = pull.BaseBranch @@ -404,9 +404,9 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C defer closer.Close() if pull.Flow == issues_model.PullRequestFlowGithub { - headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch) + headBranchExist = gitrepo.IsBranchExist(ctx, pull.HeadRepo, pull.HeadBranch) } else { - headBranchExist = git.IsReferenceExist(ctx, baseGitRepo.Path, pull.GetGitRefName()) + headBranchExist = gitrepo.IsReferenceExist(ctx, pull.BaseRepo, pull.GetGitRefName()) } if headBranchExist { diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 2ad0bf7e3a..553bdbf6e5 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.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/gitrepo" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" @@ -420,7 +421,7 @@ func NewReleasePost(ctx *context.Context) { return } - if !ctx.Repo.GitRepo.IsBranchExist(form.Target) { + if !gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, form.Target) { ctx.RenderWithErr(ctx.Tr("form.target_branch_not_exist"), tplReleaseNew, &form) return } diff --git a/routers/web/repo/setting/default_branch.go b/routers/web/repo/setting/default_branch.go index e0822ba540..044c9e556a 100644 --- a/routers/web/repo/setting/default_branch.go +++ b/routers/web/repo/setting/default_branch.go @@ -34,7 +34,7 @@ func SetDefaultBranchPost(ctx *context.Context) { } branch := ctx.FormString("branch") - if err := repo_service.SetRepoDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, branch); err != nil { + if err := repo_service.SetRepoDefaultBranch(ctx, ctx.Repo.Repository, branch); err != nil { switch { case git_model.IsErrBranchNotExist(err): ctx.Status(http.StatusNotFound) diff --git a/services/agit/agit.go b/services/agit/agit.go index 7d2ccbd0c2..1e6ce93312 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -13,6 +13,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/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/setting" @@ -56,10 +57,10 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. baseBranchName := opts.RefFullNames[i].ForBranchName() currentTopicBranch := "" - if !gitRepo.IsBranchExist(baseBranchName) { + if !gitrepo.IsBranchExist(ctx, repo, baseBranchName) { // try match refs/for// for p, v := range baseBranchName { - if v == '/' && gitRepo.IsBranchExist(baseBranchName[:p]) && p != len(baseBranchName)-1 { + if v == '/' && gitrepo.IsBranchExist(ctx, repo, baseBranchName[:p]) && p != len(baseBranchName)-1 { currentTopicBranch = baseBranchName[p+1:] baseBranchName = baseBranchName[:p] break diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index bdb0493ae8..62d560ff94 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -248,13 +248,13 @@ func handlePullRequestAutoMerge(pullID int64, sha string) { switch pr.Flow { case issues_model.PullRequestFlowGithub: - headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch) - if pr.HeadRepo == nil || !headBranchExist { + headBranchExist := pr.HeadRepo != nil && gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) + if !headBranchExist { log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch) return } case issues_model.PullRequestFlowAGit: - headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName()) + headBranchExist := gitrepo.IsReferenceExist(ctx, pr.BaseRepo, pr.GetGitRefName()) if !headBranchExist { log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch(Agit): %s]", pr, pr.HeadRepoID, pr.HeadBranch) return diff --git a/services/context/api.go b/services/context/api.go index 89280cac80..10fad419ba 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -304,14 +304,14 @@ func RepoRefForAPI(next http.Handler) http.Handler { refName, _, _ := getRefNameLegacy(ctx.Base, ctx.Repo, ctx.PathParam("*"), ctx.FormTrim("ref")) var err error - if ctx.Repo.GitRepo.IsBranchExist(refName) { + if gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, refName) { ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) if err != nil { ctx.APIErrorInternal(err) return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if ctx.Repo.GitRepo.IsTagExist(refName) { + } else if gitrepo.IsTagExist(ctx, ctx.Repo.Repository, refName) { ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName) if err != nil { ctx.APIErrorInternal(err) diff --git a/services/context/repo.go b/services/context/repo.go index e63e3e5317..6eccd1312a 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -814,7 +814,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { reqPath := ctx.PathParam("*") if reqPath == "" { refShortName = ctx.Repo.Repository.DefaultBranch - if !ctx.Repo.GitRepo.IsBranchExist(refShortName) { + if !gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, refShortName) { brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1) if err == nil && len(brs) != 0 { refShortName = brs[0].Name @@ -854,7 +854,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { return } - if refType == git.RefTypeBranch && ctx.Repo.GitRepo.IsBranchExist(refShortName) { + if refType == git.RefTypeBranch && gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, refShortName) { ctx.Repo.BranchName = refShortName ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName) @@ -864,7 +864,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if refType == git.RefTypeTag && ctx.Repo.GitRepo.IsTagExist(refShortName) { + } else if refType == git.RefTypeTag && gitrepo.IsTagExist(ctx, ctx.Repo.Repository, refShortName) { ctx.Repo.RefFullName = git.RefNameFromTag(refShortName) ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refShortName) diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go index aa1ad7cd66..0bfff21746 100644 --- a/services/pull/commit_status.go +++ b/services/pull/commit_status.go @@ -10,7 +10,6 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" @@ -131,10 +130,10 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullR } defer closer.Close() - if pr.Flow == issues_model.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) { + if pr.Flow == issues_model.PullRequestFlowGithub && !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) { return "", errors.New("Head branch does not exist, can not merge") } - if pr.Flow == issues_model.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) { + if pr.Flow == issues_model.PullRequestFlowAGit && !gitrepo.IsReferenceExist(ctx, pr.HeadRepo, pr.GetGitRefName()) { return "", errors.New("Head branch does not exist, can not merge") } diff --git a/services/pull/protected_branch.go b/services/pull/protected_branch.go index 5f42629ddc..181bd32f44 100644 --- a/services/pull/protected_branch.go +++ b/services/pull/protected_branch.go @@ -8,7 +8,7 @@ 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/gitrepo" ) func CreateOrUpdateProtectedBranch(ctx context.Context, repo *repo_model.Repository, @@ -22,7 +22,8 @@ func CreateOrUpdateProtectedBranch(ctx context.Context, repo *repo_model.Reposit isPlainRule := !git_model.IsRuleNameSpecial(protectBranch.RuleName) var isBranchExist bool if isPlainRule { - isBranchExist = git.IsBranchExist(ctx, repo.RepoPath(), protectBranch.RuleName) + // TODO: read the database directly to check if the branch exists + isBranchExist = gitrepo.IsBranchExist(ctx, repo, protectBranch.RuleName) } if isBranchExist { diff --git a/services/pull/pull.go b/services/pull/pull.go index 21f31e16cf..4641d4ac40 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -491,7 +491,7 @@ func AddTestPullRequestTask(opts TestPullRequestOptions) { for _, pr := range prs { divergence, err := GetDiverging(ctx, pr) if err != nil { - if git_model.IsErrBranchNotExist(err) && !git.IsBranchExist(ctx, pr.HeadRepo.RepoPath(), pr.HeadBranch) { + if git_model.IsErrBranchNotExist(err) && !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) { log.Warn("Cannot test PR %s/%d: head_branch %s no longer exists", pr.BaseRepo.Name, pr.IssueID, pr.HeadBranch) } else { log.Error("GetDiverging: %v", err) diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go index 911db85585..3f33370798 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/gitrepo" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" ) @@ -181,7 +182,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest) if err := git.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch). Run(ctx, prCtx.RunOpts()); err != nil { cancel() - if !git.IsBranchExist(ctx, pr.HeadRepo.RepoPath(), pr.HeadBranch) { + if !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) { return nil, nil, git_model.ErrBranchNotExist{ BranchName: pr.HeadBranch, } diff --git a/services/release/release.go b/services/release/release.go index d1dbb11ea1..0b8a74252a 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -77,7 +77,7 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel var created bool // Only actual create when publish. if !rel.IsDraft { - if !gitRepo.IsTagExist(rel.TagName) { + if !gitrepo.IsTagExist(ctx, rel.Repo, rel.TagName) { if err := rel.LoadAttributes(ctx); err != nil { log.Error("LoadAttributes: %v", err) return false, err diff --git a/services/repository/branch.go b/services/repository/branch.go index d0d8851423..8804778bd5 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -410,11 +410,11 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m return "target_exist", nil } - if gitRepo.IsBranchExist(to) { + if gitrepo.IsBranchExist(ctx, repo, to) { return "target_exist", nil } - if !gitRepo.IsBranchExist(from) { + if !gitrepo.IsBranchExist(ctx, repo, from) { return "from_not_exist", nil } @@ -618,12 +618,12 @@ func AddAllRepoBranchesToSyncQueue(ctx context.Context) error { return nil } -func SetRepoDefaultBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, newBranchName string) error { +func SetRepoDefaultBranch(ctx context.Context, repo *repo_model.Repository, newBranchName string) error { if repo.DefaultBranch == newBranchName { return nil } - if !gitRepo.IsBranchExist(newBranchName) { + if !gitrepo.IsBranchExist(ctx, repo, newBranchName) { return git_model.ErrBranchNotExist{ BranchName: newBranchName, } diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go index 66f4456185..413d416b8d 100644 --- a/services/wiki/wiki.go +++ b/services/wiki/wiki.go @@ -100,7 +100,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model return fmt.Errorf("InitWiki: %w", err) } - hasDefaultBranch := git.IsBranchExist(ctx, repo.WikiPath(), repo.DefaultWikiBranch) + hasDefaultBranch := gitrepo.IsWikiBranchExist(ctx, repo, repo.DefaultWikiBranch) basePath, err := repo_module.CreateTemporaryPath("update-wiki") if err != nil { From c88e71c1d2d1af0ac9de73ae43484fa9063cb8d5 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 15 Mar 2025 20:14:56 -0700 Subject: [PATCH 233/655] Refactor functions to reduce repopath expose (#33892) --- models/git/commit_status.go | 7 +++---- modules/indexer/stats/db.go | 10 +++++----- modules/repository/commits.go | 13 +++++++------ modules/repository/commits_test.go | 10 +++++----- services/actions/notifier.go | 4 ++-- services/webhook/notifier.go | 6 +++--- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 5432eea55e..d1c94aa023 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -453,9 +453,8 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error { return fmt.Errorf("NewCommitStatus[nil, %s]: no repository specified", opts.SHA) } - repoPath := opts.Repo.RepoPath() if opts.Creator == nil { - return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", repoPath, opts.SHA) + return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", opts.Repo.FullName(), opts.SHA) } ctx, committer, err := db.TxContext(ctx) @@ -477,13 +476,13 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error { opts.CommitStatus.CreatorID = opts.Creator.ID opts.CommitStatus.RepoID = opts.Repo.ID opts.CommitStatus.Index = idx - log.Debug("NewCommitStatus[%s, %s]: %d", repoPath, opts.SHA, opts.CommitStatus.Index) + log.Debug("NewCommitStatus[%s, %s]: %d", opts.Repo.FullName(), opts.SHA, opts.CommitStatus.Index) opts.CommitStatus.ContextHash = hashCommitStatusContext(opts.CommitStatus.Context) // Insert new CommitStatus if _, err = db.GetEngine(ctx).Insert(opts.CommitStatus); err != nil { - return fmt.Errorf("insert CommitStatus[%s, %s]: %w", repoPath, opts.SHA, err) + return fmt.Errorf("insert CommitStatus[%s, %s]: %w", opts.Repo.FullName(), opts.SHA, err) } return committer.Commit() diff --git a/modules/indexer/stats/db.go b/modules/indexer/stats/db.go index 98a977c700..067a6f609b 100644 --- a/modules/indexer/stats/db.go +++ b/modules/indexer/stats/db.go @@ -49,10 +49,10 @@ func (db *DBIndexer) Index(id int64) error { commitID, err := gitRepo.GetBranchCommitID(repo.DefaultBranch) if err != nil { if git.IsErrBranchNotExist(err) || git.IsErrNotExist(err) || setting.IsInTesting { - log.Debug("Unable to get commit ID for default branch %s in %s ... skipping this repository", repo.DefaultBranch, repo.RepoPath()) + log.Debug("Unable to get commit ID for default branch %s in %s ... skipping this repository", repo.DefaultBranch, repo.FullName()) return nil } - log.Error("Unable to get commit ID for default branch %s in %s. Error: %v", repo.DefaultBranch, repo.RepoPath(), err) + log.Error("Unable to get commit ID for default branch %s in %s. Error: %v", repo.DefaultBranch, repo.FullName(), err) return err } @@ -65,17 +65,17 @@ func (db *DBIndexer) Index(id int64) error { stats, err := gitRepo.GetLanguageStats(commitID) if err != nil { if !setting.IsInTesting { - log.Error("Unable to get language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.RepoPath(), err) + log.Error("Unable to get language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.FullName(), err) } return err } err = repo_model.UpdateLanguageStats(ctx, repo, commitID, stats) if err != nil { - log.Error("Unable to update language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.RepoPath(), err) + log.Error("Unable to update language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.FullName(), err) return err } - log.Debug("DBIndexer completed language stats for ID %s for default branch %s in %s. stats count: %d", commitID, repo.DefaultBranch, repo.RepoPath(), len(stats)) + log.Debug("DBIndexer completed language stats for ID %s for default branch %s in %s. stats count: %d", commitID, repo.DefaultBranch, repo.FullName(), len(stats)) return nil } diff --git a/modules/repository/commits.go b/modules/repository/commits.go index 6e4b75d5ca..16520fb28a 100644 --- a/modules/repository/commits.go +++ b/modules/repository/commits.go @@ -10,6 +10,7 @@ import ( "time" "code.gitea.io/gitea/models/avatars" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" @@ -43,7 +44,7 @@ func NewPushCommits() *PushCommits { } // ToAPIPayloadCommit converts a single PushCommit to an api.PayloadCommit object. -func ToAPIPayloadCommit(ctx context.Context, emailUsers map[string]*user_model.User, repoPath, repoLink string, commit *PushCommit) (*api.PayloadCommit, error) { +func ToAPIPayloadCommit(ctx context.Context, emailUsers map[string]*user_model.User, repo *repo_model.Repository, commit *PushCommit) (*api.PayloadCommit, error) { var err error authorUsername := "" author, ok := emailUsers[commit.AuthorEmail] @@ -70,7 +71,7 @@ func ToAPIPayloadCommit(ctx context.Context, emailUsers map[string]*user_model.U committerUsername = committer.Name } - fileStatus, err := git.GetCommitFileStatus(ctx, repoPath, commit.Sha1) + fileStatus, err := git.GetCommitFileStatus(ctx, repo.RepoPath(), commit.Sha1) if err != nil { return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %w", commit.Sha1, err) } @@ -78,7 +79,7 @@ func ToAPIPayloadCommit(ctx context.Context, emailUsers map[string]*user_model.U return &api.PayloadCommit{ ID: commit.Sha1, Message: commit.Message, - URL: fmt.Sprintf("%s/commit/%s", repoLink, url.PathEscape(commit.Sha1)), + URL: fmt.Sprintf("%s/commit/%s", repo.HTMLURL(), url.PathEscape(commit.Sha1)), Author: &api.PayloadUser{ Name: commit.AuthorName, Email: commit.AuthorEmail, @@ -98,14 +99,14 @@ func ToAPIPayloadCommit(ctx context.Context, emailUsers map[string]*user_model.U // ToAPIPayloadCommits converts a PushCommits object to api.PayloadCommit format. // It returns all converted commits and, if provided, the head commit or an error otherwise. -func (pc *PushCommits) ToAPIPayloadCommits(ctx context.Context, repoPath, repoLink string) ([]*api.PayloadCommit, *api.PayloadCommit, error) { +func (pc *PushCommits) ToAPIPayloadCommits(ctx context.Context, repo *repo_model.Repository) ([]*api.PayloadCommit, *api.PayloadCommit, error) { commits := make([]*api.PayloadCommit, len(pc.Commits)) var headCommit *api.PayloadCommit emailUsers := make(map[string]*user_model.User) for i, commit := range pc.Commits { - apiCommit, err := ToAPIPayloadCommit(ctx, emailUsers, repoPath, repoLink, commit) + apiCommit, err := ToAPIPayloadCommit(ctx, emailUsers, repo, commit) if err != nil { return nil, nil, err } @@ -117,7 +118,7 @@ func (pc *PushCommits) ToAPIPayloadCommits(ctx context.Context, repoPath, repoLi } if pc.HeadCommit != nil && headCommit == nil { var err error - headCommit, err = ToAPIPayloadCommit(ctx, emailUsers, repoPath, repoLink, pc.HeadCommit) + headCommit, err = ToAPIPayloadCommit(ctx, emailUsers, repo, pc.HeadCommit) if err != nil { return nil, nil, err } diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 3afc116e68..e8dbf0b4e9 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -50,14 +50,14 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { pushCommits.HeadCommit = &PushCommit{Sha1: "69554a6"} repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) - payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(git.DefaultContext, repo.RepoPath(), "/user2/repo16") + payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(git.DefaultContext, repo) assert.NoError(t, err) assert.Len(t, payloadCommits, 3) assert.NotNil(t, headCommit) assert.Equal(t, "69554a6", payloadCommits[0].ID) assert.Equal(t, "not signed commit", payloadCommits[0].Message) - assert.Equal(t, "/user2/repo16/commit/69554a6", payloadCommits[0].URL) + assert.Equal(t, "https://try.gitea.io/user2/repo16/commit/69554a6", payloadCommits[0].URL) assert.Equal(t, "User2", payloadCommits[0].Committer.Name) assert.Equal(t, "user2", payloadCommits[0].Committer.UserName) assert.Equal(t, "User2", payloadCommits[0].Author.Name) @@ -68,7 +68,7 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { assert.Equal(t, "27566bd", payloadCommits[1].ID) assert.Equal(t, "good signed commit (with not yet validated email)", payloadCommits[1].Message) - assert.Equal(t, "/user2/repo16/commit/27566bd", payloadCommits[1].URL) + assert.Equal(t, "https://try.gitea.io/user2/repo16/commit/27566bd", payloadCommits[1].URL) assert.Equal(t, "User2", payloadCommits[1].Committer.Name) assert.Equal(t, "user2", payloadCommits[1].Committer.UserName) assert.Equal(t, "User2", payloadCommits[1].Author.Name) @@ -79,7 +79,7 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { assert.Equal(t, "5099b81", payloadCommits[2].ID) assert.Equal(t, "good signed commit", payloadCommits[2].Message) - assert.Equal(t, "/user2/repo16/commit/5099b81", payloadCommits[2].URL) + assert.Equal(t, "https://try.gitea.io/user2/repo16/commit/5099b81", payloadCommits[2].URL) assert.Equal(t, "User2", payloadCommits[2].Committer.Name) assert.Equal(t, "user2", payloadCommits[2].Committer.UserName) assert.Equal(t, "User2", payloadCommits[2].Author.Name) @@ -90,7 +90,7 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { assert.Equal(t, "69554a6", headCommit.ID) assert.Equal(t, "not signed commit", headCommit.Message) - assert.Equal(t, "/user2/repo16/commit/69554a6", headCommit.URL) + assert.Equal(t, "https://try.gitea.io/user2/repo16/commit/69554a6", headCommit.URL) assert.Equal(t, "User2", headCommit.Committer.Name) assert.Equal(t, "user2", headCommit.Committer.UserName) assert.Equal(t, "User2", headCommit.Author.Name) diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 1a23b4e0c5..831cde3523 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -532,7 +532,7 @@ func (n *actionsNotifier) PushCommits(ctx context.Context, pusher *user_model.Us ctx = withMethod(ctx, "PushCommits") apiPusher := convert.ToUser(ctx, pusher, nil) - apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo.RepoPath(), repo.HTMLURL()) + apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo) if err != nil { log.Error("commits.ToAPIPayloadCommits failed: %v", err) return @@ -593,7 +593,7 @@ func (n *actionsNotifier) SyncPushCommits(ctx context.Context, pusher *user_mode ctx = withMethod(ctx, "SyncPushCommits") apiPusher := convert.ToUser(ctx, pusher, nil) - apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo.RepoPath(), repo.HTMLURL()) + apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo) if err != nil { log.Error("commits.ToAPIPayloadCommits failed: %v", err) return diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index 7d779cd527..9e3f21de29 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -606,7 +606,7 @@ func (m *webhookNotifier) IssueChangeMilestone(ctx context.Context, doer *user_m func (m *webhookNotifier) PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { apiPusher := convert.ToUser(ctx, pusher, nil) - apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo.RepoPath(), repo.HTMLURL()) + apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo) if err != nil { log.Error("commits.ToAPIPayloadCommits failed: %v", err) return @@ -845,7 +845,7 @@ func (m *webhookNotifier) DeleteRelease(ctx context.Context, doer *user_model.Us func (m *webhookNotifier) SyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { apiPusher := convert.ToUser(ctx, pusher, nil) - apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo.RepoPath(), repo.HTMLURL()) + apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(ctx, repo) if err != nil { log.Error("commits.ToAPIPayloadCommits failed: %v", err) return @@ -869,7 +869,7 @@ func (m *webhookNotifier) SyncPushCommits(ctx context.Context, pusher *user_mode func (m *webhookNotifier) CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit *repository.PushCommit, sender *user_model.User, status *git_model.CommitStatus) { apiSender := convert.ToUser(ctx, sender, nil) - apiCommit, err := repository.ToAPIPayloadCommit(ctx, map[string]*user_model.User{}, repo.RepoPath(), repo.HTMLURL(), commit) + apiCommit, err := repository.ToAPIPayloadCommit(ctx, map[string]*user_model.User{}, repo, commit) if err != nil { log.Error("commits.ToAPIPayloadCommits failed: %v", err) return From 52663113d46c3adc80f54f6f4595fa8d3dcd0ae0 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 16 Mar 2025 10:04:18 +0100 Subject: [PATCH 234/655] Update JS and PY deps, misc tweaks (#33903) - Update all updateable dependencies - Add a few more unupgradable ones to updates blocklist - Adapt to breaking changes - Update to typescript 5.8, enable `erasableSyntaxOnly` which necessitated a change because of forbidden syntax - Misc cleanups - Tested htmx, easymde, swagger, chart.js --- .eslintrc.cjs | 4 +- package-lock.json | 2322 ++++++++--------- package.json | 50 +- poetry.lock | 24 +- pyproject.toml | 2 +- tsconfig.json | 2 + updates.config.js | 3 + .../features/repo-issue-sidebar-combolist.ts | 6 +- web_src/js/htmx.ts | 2 +- webpack.config.js | 1 - 10 files changed, 1188 insertions(+), 1228 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index f2af1709e4..f9e1050240 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -104,7 +104,7 @@ module.exports = { '@vitest/no-disabled-tests': [0], '@vitest/no-done-callback': [0], '@vitest/no-duplicate-hooks': [0], - '@vitest/no-focused-tests': [0], + '@vitest/no-focused-tests': [2], '@vitest/no-hooks': [0], '@vitest/no-identical-title': [2], '@vitest/no-interpolation-in-snapshots': [0], @@ -155,7 +155,7 @@ module.exports = { 'eslint-plugin-vue-scoped-css', ], extends: [ - 'plugin:vue/vue3-recommended', + 'plugin:vue/recommended', 'plugin:vue-scoped-css/vue3-recommended', ], rules: { diff --git a/package-lock.json b/package-lock.json index 46baf94200..c347cf5fd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,12 +13,12 @@ "@github/relative-time-element": "4.4.5", "@github/text-expander-element": "2.9.1", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", - "@primer/octicons": "19.15.0", + "@primer/octicons": "19.15.1", "@silverwind/vue3-calendar-heatmap": "2.0.6", "add-asset-webpack-plugin": "3.0.0", "ansi_up": "6.0.2", "asciinema-player": "3.9.0", - "chart.js": "4.4.7", + "chart.js": "4.4.8", "chartjs-adapter-dayjs-4": "1.0.4", "chartjs-plugin-zoom": "2.2.0", "clippie": "4.1.5", @@ -26,34 +26,34 @@ "css-loader": "7.1.2", "dayjs": "1.11.13", "dropzone": "6.0.0-beta.2", - "easymde": "2.18.0", + "easymde": "2.20.0", "esbuild-loader": "4.3.0", "escape-goat": "4.0.0", "fast-glob": "3.3.3", "htmx.org": "2.0.4", - "idiomorph": "0.4.0", + "idiomorph": "0.7.3", "jquery": "3.7.1", "katex": "0.16.21", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "11.4.1", + "mermaid": "11.5.0", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.1", "monaco-editor": "0.52.2", "monaco-editor-webpack-plugin": "7.1.0", "pdfobject": "2.3.1", "perfect-debounce": "1.0.0", - "postcss": "8.5.2", + "postcss": "8.5.3", "postcss-loader": "8.1.1", "postcss-nesting": "13.0.1", "sortablejs": "1.15.6", - "swagger-ui-dist": "5.18.3", + "swagger-ui-dist": "5.20.1", "tailwindcss": "3.4.17", "throttle-debounce": "5.0.2", "tinycolor2": "1.6.0", "tippy.js": "6.3.7", "toastify-js": "1.12.0", "tributejs": "5.1.3", - "typescript": "5.7.3", + "typescript": "5.8.2", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", "vue": "3.5.13", @@ -67,7 +67,7 @@ "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "4.4.1", "@playwright/test": "1.49.1", - "@stoplight/spectral-cli": "6.14.2", + "@stoplight/spectral-cli": "6.14.3", "@stylistic/eslint-plugin-js": "3.1.0", "@stylistic/stylelint-plugin": "3.1.2", "@types/dropzone": "5.7.9", @@ -80,41 +80,41 @@ "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", "@types/toastify-js": "1.12.3", - "@typescript-eslint/eslint-plugin": "8.24.0", - "@typescript-eslint/parser": "8.24.0", + "@typescript-eslint/eslint-plugin": "8.26.1", + "@typescript-eslint/parser": "8.26.1", "@vitejs/plugin-vue": "5.2.1", - "@vitest/eslint-plugin": "1.1.31", + "@vitest/eslint-plugin": "1.1.37", "eslint": "8.57.0", - "eslint-import-resolver-typescript": "3.8.0", + "eslint-import-resolver-typescript": "3.9.0", "eslint-plugin-array-func": "4.0.0", "eslint-plugin-github": "5.0.2", - "eslint-plugin-import-x": "4.6.1", - "eslint-plugin-no-jquery": "3.1.0", + "eslint-plugin-import-x": "4.7.2", + "eslint-plugin-no-jquery": "3.1.1", "eslint-plugin-no-use-extend-native": "0.5.0", "eslint-plugin-playwright": "2.2.0", "eslint-plugin-regexp": "2.7.0", "eslint-plugin-sonarjs": "3.0.2", "eslint-plugin-unicorn": "56.0.1", - "eslint-plugin-vue": "9.32.0", + "eslint-plugin-vue": "10.0.0", "eslint-plugin-vue-scoped-css": "2.9.0", - "eslint-plugin-wc": "2.2.0", - "happy-dom": "17.1.0", + "eslint-plugin-wc": "2.2.1", + "happy-dom": "17.4.4", "markdownlint-cli": "0.44.0", "material-icon-theme": "5.20.0", - "nolyfill": "1.0.43", + "nolyfill": "1.0.44", "postcss-html": "1.8.0", - "stylelint": "16.14.1", + "stylelint": "16.16.0", "stylelint-config-recommended": "15.0.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", - "stylelint-declaration-strict-value": "1.10.7", - "stylelint-define-config": "16.14.1", + "stylelint-declaration-strict-value": "1.10.11", + "stylelint-define-config": "16.15.0", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "3.3.2", - "type-fest": "4.34.1", + "type-fest": "4.37.0", "updates": "16.4.2", "vite-string-plugin": "1.4.4", - "vitest": "3.0.5", - "vue-tsc": "2.2.2" + "vitest": "3.0.8", + "vue-tsc": "2.2.8" }, "engines": { "node": ">= 18.0.0" @@ -146,9 +146,9 @@ } }, "node_modules/@antfu/utils": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.0.tgz", - "integrity": "sha512-XPR7Jfwp0FFl/dFYPX8ZjpmU4/1mIXTjnZ1ba48BLMyKOV62/tiRjdsFcPs2hsYcSud4tzk7w3a3LjX8Fu3huA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz", + "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" @@ -203,12 +203,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz", - "integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.8" + "@babel/types": "^7.26.10" }, "bin": { "parser": "bin/babel-parser.js" @@ -218,9 +218,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", - "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -230,9 +230,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz", - "integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -520,10 +520,44 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/@emnapi/core": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.3.1.tgz", + "integrity": "sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz", + "integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", - "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", "cpu": [ "ppc64" ], @@ -537,9 +571,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", "cpu": [ "arm" ], @@ -553,9 +587,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", "cpu": [ "arm64" ], @@ -569,9 +603,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", "cpu": [ "x64" ], @@ -585,9 +619,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", "cpu": [ "arm64" ], @@ -601,9 +635,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", "cpu": [ "x64" ], @@ -617,9 +651,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", "cpu": [ "arm64" ], @@ -633,9 +667,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", "cpu": [ "x64" ], @@ -649,9 +683,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", "cpu": [ "arm" ], @@ -665,9 +699,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", "cpu": [ "arm64" ], @@ -681,9 +715,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", "cpu": [ "ia32" ], @@ -697,9 +731,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", "cpu": [ "loong64" ], @@ -713,9 +747,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", "cpu": [ "mips64el" ], @@ -729,9 +763,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", "cpu": [ "ppc64" ], @@ -745,9 +779,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", "cpu": [ "riscv64" ], @@ -761,9 +795,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", "cpu": [ "s390x" ], @@ -777,9 +811,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", "cpu": [ "x64" ], @@ -793,9 +827,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", "cpu": [ "arm64" ], @@ -809,9 +843,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", "cpu": [ "x64" ], @@ -825,9 +859,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", "cpu": [ "arm64" ], @@ -841,9 +875,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", "cpu": [ "x64" ], @@ -857,9 +891,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", "cpu": [ "x64" ], @@ -873,9 +907,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", "cpu": [ "arm64" ], @@ -889,9 +923,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", "cpu": [ "ia32" ], @@ -905,9 +939,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", "cpu": [ "x64" ], @@ -941,9 +975,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", + "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", "dev": true, "license": "MIT", "dependencies": { @@ -1414,9 +1448,9 @@ } }, "node_modules/@keyv/serialize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.2.tgz", - "integrity": "sha512-+E/LyaAeuABniD/RvUezWVXKpeuvwLEA9//nE9952zBaOdBd2mQ3pPoM8cUe2X6IcMByfuSLzmYqnYshG60+HQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz", + "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==", "dev": true, "license": "MIT", "dependencies": { @@ -1514,6 +1548,19 @@ "langium": "3.0.0" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.7.tgz", + "integrity": "sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.3.1", + "@emnapi/runtime": "^1.3.1", + "@tybys/wasm-util": "^0.9.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1560,12 +1607,169 @@ } }, "node_modules/@nolyfill/shared": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/shared/-/shared-1.0.28.tgz", - "integrity": "sha512-UJTshFMDgugBcYXGLopbL1enYpGREOEfjUMQKLPLeJqWfbfElGtYbGbUcucCENa7cicGo3M5u/DnPiZe/PYQyw==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/shared/-/shared-1.0.44.tgz", + "integrity": "sha512-NI1zxDh4LYL7PYlKKCwojjuc5CEZslywrOTKBNyodjmWjRiZ4AlCMs3Gp+zDoPQPNkYCSQp/luNojHmJWWfCbw==", "dev": true, "license": "MIT" }, + "node_modules/@oxc-resolver/binding-darwin-arm64": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-5.0.0.tgz", + "integrity": "sha512-zwHAf+owoxSWTDD4dFuwW+FkpaDzbaL30H5Ltocb+RmLyg4WKuteusRLKh5Y8b/cyu7UzhxM0haIqQjyqA1iuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxc-resolver/binding-darwin-x64": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-5.0.0.tgz", + "integrity": "sha512-1lS3aBNVjVQKBvZdHm13+8tSjvu2Tl1Cv4FnUyMYxqx6+rsom2YaOylS5LhDUwfZu0zAgpLMwK6kGpF/UPncNg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxc-resolver/binding-freebsd-x64": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-5.0.0.tgz", + "integrity": "sha512-q9sRd68wC1/AJ0eu6ClhxlklVfe8gH4wrUkSyEbIYTZ8zY5yjsLY3fpqqsaCvWJUx65nW+XtnAxCGCi5AXr1Mw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-5.0.0.tgz", + "integrity": "sha512-catYavWsvqViYnCveQjhrK6yVYDEPFvIOgGLxnz5r2dcgrjpmquzREoyss0L2QG/J5HTTbwqwZ1kk+g56hE/1A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm64-gnu": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-5.0.0.tgz", + "integrity": "sha512-l/0pWoQM5kVmJLg4frQ1mKZOXgi0ex/hzvFt8E4WK2ifXr5JgKFUokxsb/oat7f5YzdJJh5r9p+qS/t3dA26Aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-arm64-musl": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-5.0.0.tgz", + "integrity": "sha512-bx0oz/oaAW4FGYqpIIxJCnmgb906YfMhTEWCJvYkxjpEI8VKLJEL3PQevYiqDq36SA0yRLJ/sQK2fqry8AFBfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-x64-gnu": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-5.0.0.tgz", + "integrity": "sha512-4PH++qbSIhlRsFYdN1P9neDov4OGhTGo5nbQ1D7AL6gWFLo3gdZTc00FM2y8JjeTcPWEXkViZuwpuc0w5i6qHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-linux-x64-musl": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-5.0.0.tgz", + "integrity": "sha512-mLfQFpX3/5y9oWi0b+9FbWDkL2hM0Y29653beCHiHxAdGyVgb2DsJbK74WkMTwtSz9by8vyBh8jGPZcg1yLZbQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxc-resolver/binding-wasm32-wasi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-5.0.0.tgz", + "integrity": "sha512-uEhsAZSo65qsRi6+IfBTEUUFbjg7T2yruJeLYpFfEATpm3ory5Mgo5vx3L0c2/Cz1OUZXBgp3A8x6VMUB2jT2A==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.7" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@oxc-resolver/binding-win32-arm64-msvc": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-5.0.0.tgz", + "integrity": "sha512-8DbSso9Jp1ns8AYuZFXdRfAcdJrzZwkFm/RjPuvAPTENsm685dosBF8G6gTHQlHvULnk6o3sa9ygZaTGC/UoEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxc-resolver/binding-win32-x64-msvc": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-5.0.0.tgz", + "integrity": "sha512-ylppfPEg63NuRXOPNsXFlgyl37JrtRn0QMO26X3K3Ytp5HtLrMreQMGVtgr30e1l2YmAWqhvmKlCryOqzGPD/g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1616,9 +1820,9 @@ } }, "node_modules/@primer/octicons": { - "version": "19.15.0", - "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.15.0.tgz", - "integrity": "sha512-WaZ3Qno+MJZh0skrZ8nEfYJdrqTLuxxHxJqHjhc/QRLNojcHq57njtqOt9H8d0dCGAem2stQJ3nAK8893Hz5pA==", + "version": "19.15.1", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.15.1.tgz", + "integrity": "sha512-2cFLIrfbNvfeAPxmJTr/k7/b5QvIxqM7MeroGrXojDodA2yB1nXyt91Xhu9+2e0CL5ZAe3Vd2/fEf9N9EUiX9A==", "license": "MIT", "dependencies": { "object-assign": "^4.1.1" @@ -1672,9 +1876,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz", - "integrity": "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", + "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", "cpu": [ "arm" ], @@ -1686,9 +1890,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz", - "integrity": "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", + "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", "cpu": [ "arm64" ], @@ -1700,9 +1904,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz", - "integrity": "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", + "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", "cpu": [ "arm64" ], @@ -1714,9 +1918,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz", - "integrity": "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", + "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", "cpu": [ "x64" ], @@ -1728,9 +1932,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz", - "integrity": "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", + "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", "cpu": [ "arm64" ], @@ -1742,9 +1946,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz", - "integrity": "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", + "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", "cpu": [ "x64" ], @@ -1756,9 +1960,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz", - "integrity": "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", + "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", "cpu": [ "arm" ], @@ -1770,9 +1974,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz", - "integrity": "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", + "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", "cpu": [ "arm" ], @@ -1784,9 +1988,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz", - "integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", + "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", "cpu": [ "arm64" ], @@ -1798,9 +2002,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz", - "integrity": "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", + "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", "cpu": [ "arm64" ], @@ -1812,9 +2016,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz", - "integrity": "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", + "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", "cpu": [ "loong64" ], @@ -1826,9 +2030,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz", - "integrity": "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", + "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", "cpu": [ "ppc64" ], @@ -1840,9 +2044,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz", - "integrity": "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", + "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", "cpu": [ "riscv64" ], @@ -1854,9 +2058,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz", - "integrity": "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", + "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", "cpu": [ "s390x" ], @@ -1868,9 +2072,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz", - "integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", + "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", "cpu": [ "x64" ], @@ -1882,9 +2086,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz", - "integrity": "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", + "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", "cpu": [ "x64" ], @@ -1896,9 +2100,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz", - "integrity": "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", + "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", "cpu": [ "arm64" ], @@ -1910,9 +2114,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz", - "integrity": "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", + "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", "cpu": [ "ia32" ], @@ -1924,9 +2128,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz", - "integrity": "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", + "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", "cpu": [ "x64" ], @@ -2063,15 +2267,15 @@ } }, "node_modules/@stoplight/spectral-cli": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.14.2.tgz", - "integrity": "sha512-yn49Tkin/Zzjwt39CbQvj3NZVolvXrjO3OLNn+Yd+LhQE5C96QNsULuE4q98e7+WRcLu4gK+Z0l5CxYNtsoPtw==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.14.3.tgz", + "integrity": "sha512-vKy7d2yqBfOf94uB6KXzujDl6/qjXa8mCQ6cfsQ8xYsoArZN9iBHpS3271hR5IyTm3R1GwMgaSZ1h0sfZjZrZw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@stoplight/json": "~3.21.0", "@stoplight/path": "1.3.2", - "@stoplight/spectral-core": "^1.19.4", + "@stoplight/spectral-core": "^1.19.5", "@stoplight/spectral-formatters": "^1.4.1", "@stoplight/spectral-parsers": "^1.0.4", "@stoplight/spectral-ref-resolver": "^1.0.4", @@ -2127,9 +2331,9 @@ } }, "node_modules/@stoplight/spectral-core": { - "version": "1.19.4", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.19.4.tgz", - "integrity": "sha512-8hnZXfssTlV99SKo8J8BwMt5LsiBFHkCh0V3P7j8IPcCNl//bpG92U4TpYy7AwmUms/zCLX7sxNQC6AZ+bkfzg==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.19.5.tgz", + "integrity": "sha512-i+njdliW7bAHGsHEgDvH0To/9IxiYiBELltkZ7ASVy4i+WXtZ40lQXpeRQRwePrBcSgQl0gcZFuKX10nmSHtbw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2144,9 +2348,9 @@ "@types/json-schema": "^7.0.11", "ajv": "^8.17.1", "ajv-errors": "~3.0.0", - "ajv-formats": "~2.1.0", + "ajv-formats": "~2.1.1", "es-aggregate-error": "^1.0.7", - "jsonpath-plus": "10.2.0", + "jsonpath-plus": "^10.3.0", "lodash": "~4.17.21", "lodash.topath": "^4.5.2", "minimatch": "3.1.2", @@ -2239,9 +2443,9 @@ } }, "node_modules/@stoplight/spectral-functions": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.9.3.tgz", - "integrity": "sha512-jy4mguk0Ddz0Vr76PHervOZeyXTUW650zVfNT2Vt9Ji3SqtTVziHjq913CBVEGFS+IQw1McUXuHVLM6YKVZ6fQ==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.9.4.tgz", + "integrity": "sha512-+dgu7QQ1JIZFsNLhNbQLPA9tniIT3KjOc9ORv0LYSCLvZjkWT2bN7vgmathbXsbmhnmhvl15H9sRqUIqzi+qoQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2253,7 +2457,7 @@ "ajv": "^8.17.1", "ajv-draft-04": "~1.0.0", "ajv-errors": "~3.0.0", - "ajv-formats": "~2.1.0", + "ajv-formats": "~2.1.1", "lodash": "~4.17.21", "tslib": "^2.8.1" }, @@ -2309,9 +2513,9 @@ } }, "node_modules/@stoplight/spectral-ruleset-bundler": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.6.1.tgz", - "integrity": "sha512-Pk0OVqyHXc/grFtaOWXF268UNRjwAnSGf9idBXO1XZJbieUyrYRJ44v5/E1UVxRMvzVkQ6/As/Ggi8hsEybKZw==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.6.2.tgz", + "integrity": "sha512-Tg7y/0e/6yY4hiebh9YLUGa/fHcgI6RyjfBcRGipYU7QDcJUn2UZYSzeC9hggMwT0UiRzdQlch0aEl7L4VL1GQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2337,9 +2541,9 @@ } }, "node_modules/@stoplight/spectral-ruleset-migrator": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-migrator/-/spectral-ruleset-migrator-1.11.1.tgz", - "integrity": "sha512-z2A1Ual3bU7zLDxYqdHaxYgyirb7TVDaWXc9ONEBAo5W1isio0EHV59ujAUEOUHCLcY5ubd0eYeqgSjqPIQe8w==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-migrator/-/spectral-ruleset-migrator-1.11.2.tgz", + "integrity": "sha512-6r5i4hrDmppspSSxdUKKNHc07NGSSIkvwKNk3M5ukCwvSslImvDEimeWAhPBryhmSJ82YAsKr8erZZpKullxWw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2386,9 +2590,9 @@ "license": "Apache-2.0" }, "node_modules/@stoplight/spectral-rulesets": { - "version": "1.21.3", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.21.3.tgz", - "integrity": "sha512-SQp/NNDykfCvgmo9DW1pBAbmyKRHhEHmsc28kuRHC6nJblGFsLyNVGkEDjSIJuviR7ooC2Y00vmf0R3OGcyhyw==", + "version": "1.21.4", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.21.4.tgz", + "integrity": "sha512-F03Uf+Rb9FnxfjNeIeB0B/dGDJ+NozRkQZtZ/jryoOu+7Qp7rI1e/BkFWEM3y4Fr0zcNEkpS7bjkXnW4frHPcA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2402,7 +2606,7 @@ "@stoplight/types": "^13.6.0", "@types/json-schema": "^7.0.7", "ajv": "^8.17.1", - "ajv-formats": "~2.1.0", + "ajv-formats": "~2.1.1", "json-schema-traverse": "^1.0.0", "leven": "3.1.0", "lodash": "~4.17.21", @@ -2413,9 +2617,9 @@ } }, "node_modules/@stoplight/spectral-runtime": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.3.tgz", - "integrity": "sha512-uoKSVX/OYXOEBRQN7EtAaVefl8MlyhBkDcU2aDYEGALwYXHAH+vmF3ljhZrueMA3fSWLHTL3RxWqsjeeCor6lw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.4.tgz", + "integrity": "sha512-YHbhX3dqW0do6DhiPSgSGQzr6yQLlWybhKwWx0cqxjMwxej3TqLv3BXMfIUYFKKUqIwH4Q2mV8rrMM8qD2N0rQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2424,7 +2628,7 @@ "@stoplight/types": "^13.6.0", "abort-controller": "^3.0.0", "lodash": "^4.17.21", - "node-fetch": "^2.6.7", + "node-fetch": "^2.7.0", "tslib": "^2.8.1" }, "engines": { @@ -2538,6 +2742,17 @@ "node": ">=10.13.0" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/codemirror": { "version": "5.60.15", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", @@ -2936,9 +3151,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.13.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz", - "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==", + "version": "22.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", + "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", "license": "MIT", "dependencies": { "undici-types": "~6.20.0" @@ -3099,17 +3314,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz", - "integrity": "sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.1.tgz", + "integrity": "sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.24.0", - "@typescript-eslint/type-utils": "8.24.0", - "@typescript-eslint/utils": "8.24.0", - "@typescript-eslint/visitor-keys": "8.24.0", + "@typescript-eslint/scope-manager": "8.26.1", + "@typescript-eslint/type-utils": "8.26.1", + "@typescript-eslint/utils": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3125,20 +3340,20 @@ "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.24.0.tgz", - "integrity": "sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.1.tgz", + "integrity": "sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.24.0", - "@typescript-eslint/types": "8.24.0", - "@typescript-eslint/typescript-estree": "8.24.0", - "@typescript-eslint/visitor-keys": "8.24.0", + "@typescript-eslint/scope-manager": "8.26.1", + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/typescript-estree": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1", "debug": "^4.3.4" }, "engines": { @@ -3150,18 +3365,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz", - "integrity": "sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.1.tgz", + "integrity": "sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.24.0", - "@typescript-eslint/visitor-keys": "8.24.0" + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3172,14 +3387,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz", - "integrity": "sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.1.tgz", + "integrity": "sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.24.0", - "@typescript-eslint/utils": "8.24.0", + "@typescript-eslint/typescript-estree": "8.26.1", + "@typescript-eslint/utils": "8.26.1", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, @@ -3192,13 +3407,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz", - "integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.1.tgz", + "integrity": "sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==", "dev": true, "license": "MIT", "engines": { @@ -3210,14 +3425,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz", - "integrity": "sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.1.tgz", + "integrity": "sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.24.0", - "@typescript-eslint/visitor-keys": "8.24.0", + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/visitor-keys": "8.26.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3233,7 +3448,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { @@ -3253,16 +3468,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.24.0.tgz", - "integrity": "sha512-07rLuUBElvvEb1ICnafYWr4hk8/U7X9RDCOqd9JcAMtjh/9oRmcfN4yGzbPVirgMR0+HLVHehmu19CWeh7fsmQ==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.1.tgz", + "integrity": "sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.24.0", - "@typescript-eslint/types": "8.24.0", - "@typescript-eslint/typescript-estree": "8.24.0" + "@typescript-eslint/scope-manager": "8.26.1", + "@typescript-eslint/types": "8.26.1", + "@typescript-eslint/typescript-estree": "8.26.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3273,17 +3488,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz", - "integrity": "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==", + "version": "8.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.1.tgz", + "integrity": "sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.24.0", + "@typescript-eslint/types": "8.26.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -3301,6 +3516,163 @@ "dev": true, "license": "ISC" }, + "node_modules/@unrs/rspack-resolver-binding-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-darwin-arm64/-/rspack-resolver-binding-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-otdWnJrycP8Ow0rbiKKjhrW7PPeHPoIglYjBruqh75fEwQGV2EmA9oZMgD4YA6g+/hGzD0mXI26YnWL0G0SkTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-darwin-x64/-/rspack-resolver-binding-darwin-x64-1.1.0.tgz", + "integrity": "sha512-MqHyrtIw2ra0KZlniDITROq6rEiMsBnaJtQDYLNDv/y+pvPSXdB3VveZCwSldXJ9TrST2b3NnIbmehljjsMVhg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-freebsd-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-freebsd-x64/-/rspack-resolver-binding-freebsd-x64-1.1.0.tgz", + "integrity": "sha512-bopyOqmtWn8np1d4iN90PE1tYHopdWwei7mK8/8mf4qhc99f7WRNXtWa1MoL5sjN3DWef3jvr0+MGnMS9MTfJA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-linux-arm-gnueabihf": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm-gnueabihf/-/rspack-resolver-binding-linux-arm-gnueabihf-1.1.0.tgz", + "integrity": "sha512-XldXRkQurDBXCiCuIaWcqOX6UtvjFW8O3CH/kFEZxNJISOAt+ztgyRQRxYhf+T1p18R4boripKmWKEE0uBCiYw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-linux-arm64-gnu": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm64-gnu/-/rspack-resolver-binding-linux-arm64-gnu-1.1.0.tgz", + "integrity": "sha512-8zubI4MY3whPfLNHEiJ0TeSC5eSmNVWTEGAeMGALCUQtVD9TyZTd6wGwWrQVRN7ESIapWUSChkPLr+Bi13d9sQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-linux-arm64-musl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm64-musl/-/rspack-resolver-binding-linux-arm64-musl-1.1.0.tgz", + "integrity": "sha512-+GAyOhl8KPqJsILpHTB/mMc4hfOwI4INed8VAZnSvdaL0ec3Sz/6UXEeTtucW1fWhwaP3lVlpjv2xuRhOCjehA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-linux-x64-gnu": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-x64-gnu/-/rspack-resolver-binding-linux-x64-gnu-1.1.0.tgz", + "integrity": "sha512-0zoy6UwRFoto5boJKGjgDpA+4kv+G1kysgrAe0KVefJXOnDNJlfgcV7mOV2O9J+FqtIQsXvzmOJxDB9e1Hhbzw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-linux-x64-musl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-x64-musl/-/rspack-resolver-binding-linux-x64-musl-1.1.0.tgz", + "integrity": "sha512-XjC+aZKi+X+ma5e6yaVTvojK0v0kxfikbP1dB0klx80NjCW9KRrldiZxAo7ME8Tb4a7Fz0J6PDOVzd9tFYwkQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-wasm32-wasi": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-wasm32-wasi/-/rspack-resolver-binding-wasm32-wasi-1.1.0.tgz", + "integrity": "sha512-eVBK4z9VN3vahAh2+bQBl+vs9JgWEF1xeccilDcerGNkmlFHB1My5++sbeZzou+DExkioVAdfK+uVyVnHS4k7Q==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.7" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/rspack-resolver-binding-win32-arm64-msvc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-win32-arm64-msvc/-/rspack-resolver-binding-win32-arm64-msvc-1.1.0.tgz", + "integrity": "sha512-ktm/CnSKOt/Wwdi2SBECLPJ+gL5oaw8LDHG4IfOQO5oT6qlIP0DaOUPrTf8g/WTlLnSp4TryDBM0B/gGla3LEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/rspack-resolver-binding-win32-x64-msvc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-win32-x64-msvc/-/rspack-resolver-binding-win32-x64-msvc-1.1.0.tgz", + "integrity": "sha512-cdMid8RdR6XaQ5uAudzdu9Ydl3HbYjiwpsh+X01APmTZG2ph7OeaRTozW4F8ScUHkPHfrYedv9McICbHxgBvXQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@vitejs/plugin-vue": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz", @@ -3316,13 +3688,13 @@ } }, "node_modules/@vitest/eslint-plugin": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.31.tgz", - "integrity": "sha512-xlsLr+e+AXZ/00eVZCtNmMeCJoJaRCoLDiAgLcxgQjSS1EertieB2MUHf8xIqPKs9lECc/UpL+y1xDcpvi02hw==", + "version": "1.1.37", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.37.tgz", + "integrity": "sha512-cnlBV8zr0oaBu1Vk6ruqWzpPzFCtwY0yuwUQpNIeFOUl3UhXVwNUoOYfWkZzeToGuNBaXvIsr6/RgHrXiHXqXA==", "dev": true, "license": "MIT", "peerDependencies": { - "@typescript-eslint/utils": ">= 8.0", + "@typescript-eslint/utils": "^8.24.0", "eslint": ">= 8.57.0", "typescript": ">= 5.0.0", "vitest": "*" @@ -3337,15 +3709,15 @@ } }, "node_modules/@vitest/expect": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.5.tgz", - "integrity": "sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.8.tgz", + "integrity": "sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.0.5", - "@vitest/utils": "3.0.5", - "chai": "^5.1.2", + "@vitest/spy": "3.0.8", + "@vitest/utils": "3.0.8", + "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, "funding": { @@ -3353,13 +3725,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.5.tgz", - "integrity": "sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.8.tgz", + "integrity": "sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.0.5", + "@vitest/spy": "3.0.8", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -3407,9 +3779,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.5.tgz", - "integrity": "sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.8.tgz", + "integrity": "sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==", "dev": true, "license": "MIT", "dependencies": { @@ -3420,29 +3792,29 @@ } }, "node_modules/@vitest/runner": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.5.tgz", - "integrity": "sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.8.tgz", + "integrity": "sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.0.5", - "pathe": "^2.0.2" + "@vitest/utils": "3.0.8", + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.5.tgz", - "integrity": "sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.8.tgz", + "integrity": "sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.0.5", + "@vitest/pretty-format": "3.0.8", "magic-string": "^0.30.17", - "pathe": "^2.0.2" + "pathe": "^2.0.3" }, "funding": { "url": "https://opencollective.com/vitest" @@ -3459,9 +3831,9 @@ } }, "node_modules/@vitest/spy": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.5.tgz", - "integrity": "sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.8.tgz", + "integrity": "sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3472,14 +3844,14 @@ } }, "node_modules/@vitest/utils": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.5.tgz", - "integrity": "sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.8.tgz", + "integrity": "sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.0.5", - "loupe": "^3.1.2", + "@vitest/pretty-format": "3.0.8", + "loupe": "^3.1.3", "tinyrainbow": "^2.0.0" }, "funding": { @@ -3487,30 +3859,30 @@ } }, "node_modules/@volar/language-core": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.11.tgz", - "integrity": "sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.12.tgz", + "integrity": "sha512-RLrFdXEaQBWfSnYGVxvR2WrO6Bub0unkdHYIdC31HzIEqATIuuhRRzYu76iGPZ6OtA4Au1SnW0ZwIqPP217YhA==", "dev": true, "license": "MIT", "dependencies": { - "@volar/source-map": "2.4.11" + "@volar/source-map": "2.4.12" } }, "node_modules/@volar/source-map": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.11.tgz", - "integrity": "sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.12.tgz", + "integrity": "sha512-bUFIKvn2U0AWojOaqf63ER0N/iHIBYZPpNGogfLPQ68F5Eet6FnLlyho7BS0y2HJ1jFhSif7AcuTx1TqsCzRzw==", "dev": true, "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.11.tgz", - "integrity": "sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.12.tgz", + "integrity": "sha512-HJB73OTJDgPc80K30wxi3if4fSsZZAOScbj2fcicMuOPoOkcf9NNAINb33o+DzhBdF9xTKC1gnPmIRDous5S0g==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.11", + "@volar/language-core": "2.4.12", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } @@ -3586,9 +3958,9 @@ } }, "node_modules/@vue/language-core": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.2.tgz", - "integrity": "sha512-QotO41kurE5PLf3vrNgGTk3QswO2PdUFjBwNiOi7zMmGhwb25PSTh9hD1MCgKC06AVv+8sZQvlL3Do4TTVHSiQ==", + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.8.tgz", + "integrity": "sha512-rrzB0wPGBvcwaSNRriVWdNAbHQWSf0NlGqgKHK5mEkXpefjUlVRP62u03KvwZpvKVjRnBIQ/Lwre+Mx9N6juUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3892,9 +4264,9 @@ } }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -3999,9 +4371,9 @@ } }, "node_modules/alien-signals": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.3.tgz", - "integrity": "sha512-zQOh3wAYK5ujENxvBBR3CFGF/b6afaSzZ/c9yNhJ1ENrGHETvpUuKQsa93Qrclp0+PzTF93MaZ7scVp1uUozhA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.4.tgz", + "integrity": "sha512-DJqqQD3XcsaQcQ1s+iE2jDUZmmQpXwHiR6fCAim/w87luaW+vmLY8fMlrdkmRwzaFXhkxf3rqPCR59tKVv1MDw==", "dev": true, "license": "MIT" }, @@ -4090,13 +4462,13 @@ }, "node_modules/array-includes": { "name": "@nolyfill/array-includes", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/array-includes/-/array-includes-1.0.28.tgz", - "integrity": "sha512-3LFZArKSQTQu//UvQXb4lBHWvhxmiZ5h2v50WIXfWb5UPNgeLpeGP8WgsfTePCpZgNlxt5JVFDdv5zLRa7cQXw==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/array-includes/-/array-includes-1.0.44.tgz", + "integrity": "sha512-IVEqpEgFbLaU0hUoMwJYXNSdi6lq+FxHdxd8xTKDLxh8k6u5YNGz4Bo6bT46l7p0x8PbJmHViBtngqhvE528fA==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -4114,34 +4486,27 @@ }, "node_modules/array.prototype.findlastindex": { "name": "@nolyfill/array.prototype.findlastindex", - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.findlastindex/-/array.prototype.findlastindex-1.0.24.tgz", - "integrity": "sha512-UhPUzrObJnaFB94ywGz818q9KLbgffieqKfkG/5kL9j7VS+ikC4gG2jo8/i4zqgvJT3ppHb9buEQ3RRg7fZg8Q==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.findlastindex/-/array.prototype.findlastindex-1.0.44.tgz", + "integrity": "sha512-BLeHS3SulsR3iFxxETL9q21lArV2KS7lh2wcUnhue1ppx19xah1W7MdFxepyeGbM3Umk9S90snfboXAds5HkTg==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.24" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" } }, - "node_modules/array.prototype.findlastindex/node_modules/@nolyfill/shared": { - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/@nolyfill/shared/-/shared-1.0.24.tgz", - "integrity": "sha512-TGCpg3k5N7jj9AgU/1xFw9K1g4AC1vEE5ZFkW77oPNNLzprxT17PvFaNr/lr3BkkT5fJ5LNMntaTIq+pyWaeEA==", - "dev": true, - "license": "MIT" - }, "node_modules/array.prototype.flat": { "name": "@nolyfill/array.prototype.flat", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.flat/-/array.prototype.flat-1.0.28.tgz", - "integrity": "sha512-bvBWaZDCWV7+jD70tJCy3Olp03Qx9svHN2KmC2j0CYvqfYRet5+iOb09nzb6QULqGrj7O8DQJ03ZQk6gih9J3g==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.flat/-/array.prototype.flat-1.0.44.tgz", + "integrity": "sha512-HnOqOT4te0l+XU9UKhy3ry+pc+ZRNsUJFR7omMEtjXf4+dq6oXmIBk7vR35+hSTk4ldjwm/27jwV3ZIGp3l4IQ==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -4149,13 +4514,13 @@ }, "node_modules/array.prototype.flatmap": { "name": "@nolyfill/array.prototype.flatmap", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.flatmap/-/array.prototype.flatmap-1.0.28.tgz", - "integrity": "sha512-Ui/aMijqnYISchzIG0MbRiRh2DKWORJW2s//nw6rJ5jFp6x+nmFCQ5U2be3+id36VsmTxXiv+qLAHxdfXz8g8g==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/array.prototype.flatmap/-/array.prototype.flatmap-1.0.44.tgz", + "integrity": "sha512-P6OsaEUrpBJ9NdNekFDQVM9LOFHPDKSJzwOWRBaC6LqREX+4lkZT2Q+to78R6aG6atuOQsxBVqPjMGCKjWdvyQ==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -4245,9 +4610,9 @@ } }, "node_modules/axe-core": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", - "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", "dev": true, "license": "MPL-2.0", "engines": { @@ -4442,24 +4807,24 @@ } }, "node_modules/cacheable": { - "version": "1.8.8", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.8.8.tgz", - "integrity": "sha512-OE1/jlarWxROUIpd0qGBSKFLkNsotY8pt4GeiVErUYh/NUeTNrT+SBksUgllQv4m6a0W/VZsLuiHb88maavqEw==", + "version": "1.8.9", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.8.9.tgz", + "integrity": "sha512-FicwAUyWnrtnd4QqYAoRlNs44/a1jTL7XDKqm5gJ90wz1DQPlC7U2Rd1Tydpv+E7WAr4sQHuw8Q8M3nZMAyecQ==", "dev": true, "license": "MIT", "dependencies": { - "hookified": "^1.7.0", - "keyv": "^5.2.3" + "hookified": "^1.7.1", + "keyv": "^5.3.1" } }, "node_modules/cacheable/node_modules/keyv": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.2.3.tgz", - "integrity": "sha512-AGKecUfzrowabUv0bH1RIR5Vf7w+l4S3xtQAypKaUpTdIR1EbrAcTxHCrpo9Q+IWeUlFE2palRtgIQcgm+PQJw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.2.tgz", + "integrity": "sha512-Lji2XRxqqa5Wg+CHLVfFKBImfJZ4pCSccu9eVWK6w4c2SDFLd8JAn1zqTuSFnsxb7ope6rMsnIHfp+eBbRBRZQ==", "dev": true, "license": "MIT", "dependencies": { - "@keyv/serialize": "^1.0.2" + "@keyv/serialize": "^1.0.3" } }, "node_modules/callsites": { @@ -4481,9 +4846,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001699", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz", - "integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==", + "version": "1.0.30001705", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001705.tgz", + "integrity": "sha512-S0uyMMiYvA7CxNgomYBwwwPUnWzFD83f3B1ce5jHUfHTH//QL6hHsreI8RVC5606R4ssqravelYO5TU6t8sEyg==", "funding": [ { "type": "opencollective", @@ -4501,9 +4866,9 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", - "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", "dev": true, "license": "MIT", "dependencies": { @@ -4567,9 +4932,9 @@ } }, "node_modules/chart.js": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.7.tgz", - "integrity": "sha512-pwkcKfdzTMAU/+jNosKhNL2bHtJc/sSmYgVbuGTEDhzkrhmyihmP7vUc/5ZK9WopidMDHNe3Wm7jOd/WhuHWuw==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.8.tgz", + "integrity": "sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==", "license": "MIT", "dependencies": { "@kurkle/color": "^0.3.0" @@ -4693,9 +5058,9 @@ } }, "node_modules/ci-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.1.0.tgz", - "integrity": "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", + "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==", "dev": true, "funding": [ { @@ -4878,19 +5243,19 @@ "license": "MIT" }, "node_modules/confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.1.tgz", + "integrity": "sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==", "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", - "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz", + "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.24.3" + "browserslist": "^4.24.4" }, "funding": { "type": "opencollective", @@ -5108,9 +5473,9 @@ "license": "MIT" }, "node_modules/cytoscape": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.31.0.tgz", - "integrity": "sha512-zDGn1K/tfZwEnoGOcHc0H4XazqAAXAuDpcYw9mUnUjATjqljyCNGJv8uEvbvxGaGHaVshxMecyl6oc6uKzRfbw==", + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.31.1.tgz", + "integrity": "sha512-Hx5Mtb1+hnmAKaZZ/7zL1Y5HTFYOjdDswZy/jD+1WINRU8KVi1B7+vlHdsTwY+VCFucTreoyu1RDzQJ9u0d2Hw==", "license": "MIT", "engines": { "node": ">=0.10" @@ -5660,9 +6025,9 @@ } }, "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", "dev": true, "license": "MIT", "dependencies": { @@ -5912,22 +6277,22 @@ "license": "MIT" }, "node_modules/easymde": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.18.0.tgz", - "integrity": "sha512-IxVVUxNWIoXLeqtBU4BLc+eS/ScYhT1Dcb6yF5Wchoj1iXAV+TIIDWx+NCaZhY7RcSHqDPKllbYq7nwGKILnoA==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.20.0.tgz", + "integrity": "sha512-V1Z5f92TfR42Na852OWnIZMbM7zotWQYTddNaLYZFVKj7APBbyZ3FYJ27gBw2grMW3R6Qdv9J8n5Ij7XRSIgXQ==", "license": "MIT", "dependencies": { - "@types/codemirror": "^5.60.4", + "@types/codemirror": "^5.60.10", "@types/marked": "^4.0.7", - "codemirror": "^5.63.1", + "codemirror": "^5.65.15", "codemirror-spell-checker": "1.1.2", "marked": "^4.1.0" } }, "node_modules/electron-to-chromium": { - "version": "1.5.99", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.99.tgz", - "integrity": "sha512-77c/+fCyL2U+aOyqfIFi89wYLBeSTCs55xCZL0oFH0KjqsvSvyh6AdQ+UIl1vgpnQQE6g+/KK8hOIupH6VwPtg==", + "version": "1.5.119", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.119.tgz", + "integrity": "sha512-Ku4NMzUjz3e3Vweh7PhApPrZSS4fyiCIbcIrG9eKrriYVLmbMepETR/v6SU7xPm98QTqMSYiCwfO89QNjXLkbQ==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -6002,13 +6367,13 @@ }, "node_modules/es-aggregate-error": { "name": "@nolyfill/es-aggregate-error", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/es-aggregate-error/-/es-aggregate-error-1.0.28.tgz", - "integrity": "sha512-rznCu74ormHtT2JkCgARsrWRAMDhkvS3PM+vz1BXKY0IsrXfwtxM0PlxfDexvCQ1tf/kq69Dfp2No5hJ1WAJVQ==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/es-aggregate-error/-/es-aggregate-error-1.0.44.tgz", + "integrity": "sha512-NBXDS4gpOiK4csFDGjqAF0WVKAMsqq/2ZU+/z+q+Mmvpr6CIrwKC/X+EbMpalEOZYT8kSTaCMVDUcXTDeMYOLw==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -6021,9 +6386,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -6033,31 +6398,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" } }, "node_modules/esbuild-loader": { @@ -6186,13 +6551,13 @@ } }, "node_modules/eslint-config-prettier": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz", - "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.1.tgz", + "integrity": "sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==", "dev": true, "license": "MIT", "bin": { - "eslint-config-prettier": "build/bin/cli.js" + "eslint-config-prettier": "bin/cli.js" }, "peerDependencies": { "eslint": ">=7.0.0" @@ -6221,19 +6586,19 @@ } }, "node_modules/eslint-import-resolver-typescript": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.8.0.tgz", - "integrity": "sha512-fItUrP/+xwpavWgadrn6lsvcMe80s08xIVFXkUXvhR4cZD2ga96kRF/z/iFGDI7ZDnvtlaZ0wGic7Tw+DhgVnA==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.9.0.tgz", + "integrity": "sha512-EUcFmaz0zAa6P2C9jAb5XDymRld8S6TURvWcIW7y+czOW+K8hrjgQgbhBsNE0J/dDZ6HLfcn70LqnIil9W+ICw==", "dev": true, "license": "ISC", "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.3.7", - "enhanced-resolve": "^5.15.0", "get-tsconfig": "^4.10.0", "is-bun-module": "^1.0.2", - "stable-hash": "^0.0.4", - "tinyglobby": "^0.2.10" + "oxc-resolver": "^5.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.12" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -6432,25 +6797,24 @@ } }, "node_modules/eslint-plugin-import-x": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.6.1.tgz", - "integrity": "sha512-wluSUifMIb7UfwWXqx7Yx0lE/SGCcGXECLx/9bCmbY2nneLwvAZ4vkd1IXDjPKFvdcdUgr1BaRnaRpx3k2+Pfw==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.7.2.tgz", + "integrity": "sha512-+GpGWKbQMK3izrwU4XoRGdAJHwvxuboiNusqU25nNXlRsmnxj8B5niQRuFK1aHEvcbIKE6D9ZfwjsLmBQbnJmw==", "dev": true, "license": "MIT", "dependencies": { "@types/doctrine": "^0.0.9", - "@typescript-eslint/scope-manager": "^8.1.0", - "@typescript-eslint/utils": "^8.1.0", - "debug": "^4.3.4", + "@typescript-eslint/utils": "^8.26.1", + "debug": "^4.4.0", "doctrine": "^3.0.0", - "enhanced-resolve": "^5.17.1", "eslint-import-resolver-node": "^0.3.9", - "get-tsconfig": "^4.7.3", + "get-tsconfig": "^4.10.0", "is-glob": "^4.0.3", - "minimatch": "^9.0.3", - "semver": "^7.6.3", - "stable-hash": "^0.0.4", - "tslib": "^2.6.3" + "minimatch": "^10.0.1", + "rspack-resolver": "^1.1.0", + "semver": "^7.7.1", + "stable-hash": "^0.0.5", + "tslib": "^2.8.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6459,22 +6823,6 @@ "eslint": "^8.57.0 || ^9.0.0" } }, - "node_modules/eslint-plugin-import-x/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -6587,9 +6935,9 @@ } }, "node_modules/eslint-plugin-no-jquery": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.0.tgz", - "integrity": "sha512-Ze+eRlAbLAoceBqMXI2E9s6o3dC7zE75niP2Sy4D8I/u1TyLegrIpjc4emPN90dH0IA+uXNUmQbzBuCaihxwIQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz", + "integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==", "dev": true, "license": "MIT", "peerDependencies": { @@ -6779,26 +7127,25 @@ } }, "node_modules/eslint-plugin-vue": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.32.0.tgz", - "integrity": "sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.0.0.tgz", + "integrity": "sha512-XKckedtajqwmaX6u1VnECmZ6xJt+YvlmMzBPZd+/sI3ub2lpYZyFnsyWo7c3nMOQKJQudeyk1lw/JxdgeKT64w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "globals": "^13.24.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", "semver": "^7.6.3", - "vue-eslint-parser": "^9.4.3", "xml-name-validator": "^4.0.0" }, "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "vue-eslint-parser": "^10.0.0" } }, "node_modules/eslint-plugin-vue-scoped-css": { @@ -6829,9 +7176,9 @@ } }, "node_modules/eslint-plugin-wc": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.2.0.tgz", - "integrity": "sha512-kjPp+aXz23fOl0JZJOJS+6adwhEv98KjZ2FJqWpc4vtmk4Oenz/JJmmNZrGSARgtyR0BLIF/kVWC6GSlHA+5MA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.2.1.tgz", + "integrity": "sha512-KstLqGmyQz088DvFlDYHg0sHih+w2QeulreCi1D1ftr357klO2zqHdG/bbnNMmuQdVFDuNkopNIyNhmG0XCT/g==", "dev": true, "license": "MIT", "dependencies": { @@ -7056,15 +7403,21 @@ } }, "node_modules/expect-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", - "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz", + "integrity": "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==", "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.0.0" } }, + "node_modules/exsolve": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.4.tgz", + "integrity": "sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7153,9 +7506,9 @@ } }, "node_modules/fastq": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", - "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -7257,19 +7610,19 @@ } }, "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -7571,9 +7924,9 @@ } }, "node_modules/happy-dom": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.1.0.tgz", - "integrity": "sha512-9tUhXyePCjzUMycaHS/IzrIpF69xiq/laAT7golk4MtZ6t8ft5+Rv7U3lfrs2b4NMH0JTL3EhZzjfahrPmOnaQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.4.4.tgz", + "integrity": "sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA==", "dev": true, "license": "MIT", "dependencies": { @@ -7601,9 +7954,9 @@ }, "node_modules/hasown": { "name": "@nolyfill/hasown", - "version": "1.0.29", - "resolved": "https://registry.npmjs.org/@nolyfill/hasown/-/hasown-1.0.29.tgz", - "integrity": "sha512-9h/nxZqmCy26r9VXGUz+Q77vq3eINXOYgE4st3dj6DoE7tulfJueCLw5d4hfDy3S8mKg4cFXaP+KxYQ+txvMzw==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/hasown/-/hasown-1.0.44.tgz", + "integrity": "sha512-GA/21lkTr2PAQuT6jGnhLuBD5IFd/AEhBXJ/tf33+/bVxPxg+5ejKx9jGQGnyV/P0eSmdup5E+s8b2HL6lOrwQ==", "dev": true, "license": "MIT", "engines": { @@ -7621,9 +7974,9 @@ } }, "node_modules/hookified": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.7.0.tgz", - "integrity": "sha512-XQdMjqC1AyeOzfs+17cnIk7Wdfu1hh2JtcyNfBf5u9jHrT3iZUlGHxLTntFBuk5lwkqJ6l3+daeQdHK5yByHVA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.8.1.tgz", + "integrity": "sha512-GrO2l93P8xCWBSTBX9l2BxI78VU/MAAYag+pG8curS3aBGy0++ZlxrQ7PdUOUVMbn5BwkGb6+eRrnf43ipnFEA==", "dev": true, "license": "MIT" }, @@ -7708,10 +8061,10 @@ } }, "node_modules/idiomorph": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/idiomorph/-/idiomorph-0.4.0.tgz", - "integrity": "sha512-VdXFpZOTXhLatJmhCWJR5oQKLXT01O6sFCJqT0/EqG71C4tYZdPJ5etvttwWsT2WKRYWz160XkNr1DUqXNMZHg==", - "license": "BSD-2-Clause" + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/idiomorph/-/idiomorph-0.7.3.tgz", + "integrity": "sha512-YI/L1QQkBRDtiaGZN+/KolIkNoZuIsCgus1ciueosiqdyWz/weeP+ghFgDQpk2vzA3BkX6/M/kY5SCM03LBDkA==", + "license": "0BSD" }, "node_modules/ieee754": { "version": "1.2.1", @@ -8294,9 +8647,9 @@ } }, "node_modules/jsonpath-plus": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.2.0.tgz", - "integrity": "sha512-T9V+8iNYKFL2n2rF+w02LBOT2JjDnTjioaNFrxRy0Bv1y/hNsqR/EBK7Ojy2ythRHwmz2cRIls+9JitQGZC/sw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", + "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==", "dev": true, "license": "MIT", "dependencies": { @@ -8580,13 +8933,14 @@ } }, "node_modules/local-pkg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.0.0.tgz", - "integrity": "sha512-bbgPw/wmroJsil/GgL4qjDzs5YLTBMQ99weRsok1XCDccQeehbHA/I1oRvk2NPtr7KGZgT/Y5tPRnAtMqeG2Kg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", "license": "MIT", "dependencies": { - "mlly": "^1.7.3", - "pkg-types": "^1.3.0" + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" }, "engines": { "node": ">=14" @@ -8962,37 +9316,37 @@ } }, "node_modules/mermaid": { - "version": "11.4.1", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.1.tgz", - "integrity": "sha512-Mb01JT/x6CKDWaxigwfZYuYmDZ6xtrNwNlidKZwkSrDaY9n90tdrJTV5Umk+wP1fZscGptmKFXHsXMDEVZ+Q6A==", + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.5.0.tgz", + "integrity": "sha512-IYhyukID3zzDj1EihKiN1lp+PXNImoJ3Iyz73qeDAgnus4BNGsJV1n471P4PyeGxPVONerZxignwGxGTSwZnlg==", "license": "MIT", "dependencies": { - "@braintree/sanitize-url": "^7.0.1", - "@iconify/utils": "^2.1.32", + "@braintree/sanitize-url": "^7.0.4", + "@iconify/utils": "^2.1.33", "@mermaid-js/parser": "^0.3.0", "@types/d3": "^7.4.3", - "cytoscape": "^3.29.2", + "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.11", - "dayjs": "^1.11.10", - "dompurify": "^3.2.1", + "dayjs": "^1.11.13", + "dompurify": "^3.2.4", "katex": "^0.16.9", "khroma": "^2.1.0", "lodash-es": "^4.17.21", - "marked": "^13.0.2", + "marked": "^15.0.7", "roughjs": "^4.6.6", - "stylis": "^4.3.1", + "stylis": "^4.3.6", "ts-dedent": "^2.2.0", - "uuid": "^9.0.1" + "uuid": "^11.1.0" } }, "node_modules/mermaid/node_modules/marked": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", - "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.7.tgz", + "integrity": "sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==", "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -9481,9 +9835,9 @@ } }, "node_modules/micromark-util-subtokenize": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.4.tgz", - "integrity": "sha512-N6hXjrin2GTJDe3MVjf5FuXpm12PGm80BrUAeub9XFXca8JZbP+oIwY4LJSVwFUCL1IPm/WwSVUN7goFHmSGGQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", "dev": true, "funding": [ { @@ -9647,6 +10001,23 @@ "ufo": "^1.5.4" } }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/monaco-editor": { "version": "0.52.2", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", @@ -9697,9 +10068,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz", + "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==", "funding": [ { "type": "github", @@ -9788,9 +10159,9 @@ } }, "node_modules/nolyfill": { - "version": "1.0.43", - "resolved": "https://registry.npmjs.org/nolyfill/-/nolyfill-1.0.43.tgz", - "integrity": "sha512-wi8cCDStYl2cmKOWoF5Jv/0PZXkFcRgKpk9rtxWk+7/VDlI6WDBdPM5nUOsphZjibudajsyAh1+QQvxCyLnbMA==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/nolyfill/-/nolyfill-1.0.44.tgz", + "integrity": "sha512-PoggwVLiJUn0MnodpftsiC7EuknW5+6v62ntTOQ6T6l7g2r6aoaOwgk0tQW2BxGLYw9bF298LL8jDFTmEFuzlA==", "dev": true, "license": "MIT", "bin": { @@ -9875,13 +10246,13 @@ }, "node_modules/object.assign": { "name": "@nolyfill/object.assign", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/object.assign/-/object.assign-1.0.28.tgz", - "integrity": "sha512-rrtnXgU2XJvUF9jFMwRbyvLdAlCIJOKtecflza4xWDom6u8UPliTOS0OQ6kvhql7/hpv9b8x9p0s467BVY58xg==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/object.assign/-/object.assign-1.0.44.tgz", + "integrity": "sha512-cZoXq09YZXDgkxRMAP/TTb3kAsWm7p5OyBugWDe4fOfxf0XRI55mgDSkuyq41sV1qW1zVC5aSsKEh1hQo1KOvA==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -9889,13 +10260,13 @@ }, "node_modules/object.fromentries": { "name": "@nolyfill/object.fromentries", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/object.fromentries/-/object.fromentries-1.0.28.tgz", - "integrity": "sha512-EUt70p38p+xdHDi2i8pIgw6HjrI3y9zndVhAZdEQsAvatKGKRpe3XWZRleEwYRZjkbeAG53Pz30j4tE1IJjvQQ==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/object.fromentries/-/object.fromentries-1.0.44.tgz", + "integrity": "sha512-/LrsCtpLmByZ6GwP/NeXULSgMyNsVr5d6FlgQy1HZatAiBc8c+WZ1VmFkK19ZLXCNNXBedXDultrp0x4Nz+QQw==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -9903,34 +10274,27 @@ }, "node_modules/object.groupby": { "name": "@nolyfill/object.groupby", - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/@nolyfill/object.groupby/-/object.groupby-1.0.24.tgz", - "integrity": "sha512-1PYpcT9MfPB4WRoZMUhuOrXNplTiqob7t5RKUYRh+yJm1Y8lSaDWKw2EUIJDthPbjB+UMpo75nKxdbXhRms5SQ==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/object.groupby/-/object.groupby-1.0.44.tgz", + "integrity": "sha512-jCt/8pN+10mlbeg0ZESpVVaqn5qqpv6kpjM+GDfEP7cXGDSPlIjtvfYWRZK4k4Gftkhhgqkzvcrr8z1wuNO1TQ==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.24" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" } }, - "node_modules/object.groupby/node_modules/@nolyfill/shared": { - "version": "1.0.24", - "resolved": "https://registry.npmjs.org/@nolyfill/shared/-/shared-1.0.24.tgz", - "integrity": "sha512-TGCpg3k5N7jj9AgU/1xFw9K1g4AC1vEE5ZFkW77oPNNLzprxT17PvFaNr/lr3BkkT5fJ5LNMntaTIq+pyWaeEA==", - "dev": true, - "license": "MIT" - }, "node_modules/object.values": { "name": "@nolyfill/object.values", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/object.values/-/object.values-1.0.28.tgz", - "integrity": "sha512-W6CdQv4Y/19aA5tenUhRELqlBoD92D4Uh1TDp5uHXD7s9zEHgcDCPCdA8ak6y4I66fR//Fir6C1mAQWv1QLnXw==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/object.values/-/object.values-1.0.44.tgz", + "integrity": "sha512-bwIpVzFMudUC0ofnvdSDB/OyGUizcU+r32ZZ0QTMbN03gUttMtdCFDekuSYT0XGFgufTQyZ4ONBnAeb3DFCPGQ==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -9963,6 +10327,29 @@ "node": ">= 0.8.0" } }, + "node_modules/oxc-resolver": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-5.0.0.tgz", + "integrity": "sha512-66fopyAqCN8Mx4tzNiBXWbk8asCSuxUWN62gwTc3yfRs7JfWhX/eVJCf+fUrfbNOdQVOWn+o8pAKllp76ysMXA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxc-resolver/binding-darwin-arm64": "5.0.0", + "@oxc-resolver/binding-darwin-x64": "5.0.0", + "@oxc-resolver/binding-freebsd-x64": "5.0.0", + "@oxc-resolver/binding-linux-arm-gnueabihf": "5.0.0", + "@oxc-resolver/binding-linux-arm64-gnu": "5.0.0", + "@oxc-resolver/binding-linux-arm64-musl": "5.0.0", + "@oxc-resolver/binding-linux-x64-gnu": "5.0.0", + "@oxc-resolver/binding-linux-x64-musl": "5.0.0", + "@oxc-resolver/binding-wasm32-wasi": "5.0.0", + "@oxc-resolver/binding-win32-arm64-msvc": "5.0.0", + "@oxc-resolver/binding-win32-x64-msvc": "5.0.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -10011,10 +10398,13 @@ "license": "BlueOak-1.0.0" }, "node_modules/package-manager-detector": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.9.tgz", - "integrity": "sha512-+vYvA/Y31l8Zk8dwxHhL3JfTuHPm6tlxM2A3GeQyl7ovYnSp1+mzAxClxaOr0qO1TtPxbQxetI7v5XqKLJZk7Q==", - "license": "MIT" + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "license": "MIT", + "dependencies": { + "quansync": "^0.2.7" + } }, "node_modules/parent-module": { "version": "1.0.1", @@ -10267,14 +10657,14 @@ } }, "node_modules/pkg-types": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", + "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", "license": "MIT", "dependencies": { - "confbox": "^0.1.8", - "mlly": "^1.7.4", - "pathe": "^2.0.1" + "confbox": "^0.2.1", + "exsolve": "^1.0.1", + "pathe": "^2.0.3" } }, "node_modules/playwright": { @@ -10346,9 +10736,9 @@ } }, "node_modules/postcss": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", - "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "funding": [ { "type": "opencollective", @@ -10786,9 +11176,9 @@ } }, "node_modules/prettier": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz", - "integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", "bin": { @@ -10851,6 +11241,22 @@ "node": ">=6" } }, + "node_modules/quansync": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.8.tgz", + "integrity": "sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11186,9 +11592,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -11246,6 +11652,29 @@ "points-on-path": "^0.2.1" } }, + "node_modules/rspack-resolver": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/rspack-resolver/-/rspack-resolver-1.1.0.tgz", + "integrity": "sha512-pJfTX5KuwbJc4agd2AQ9sMwrBxMAGkLt4/HHw5+L06WuzxjsEjg3oDKdbfn43QGq0Stw8wQ7VpZjWA/T03L0Pg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/JounQin" + }, + "optionalDependencies": { + "@unrs/rspack-resolver-binding-darwin-arm64": "1.1.0", + "@unrs/rspack-resolver-binding-darwin-x64": "1.1.0", + "@unrs/rspack-resolver-binding-freebsd-x64": "1.1.0", + "@unrs/rspack-resolver-binding-linux-arm-gnueabihf": "1.1.0", + "@unrs/rspack-resolver-binding-linux-arm64-gnu": "1.1.0", + "@unrs/rspack-resolver-binding-linux-arm64-musl": "1.1.0", + "@unrs/rspack-resolver-binding-linux-x64-gnu": "1.1.0", + "@unrs/rspack-resolver-binding-linux-x64-musl": "1.1.0", + "@unrs/rspack-resolver-binding-wasm32-wasi": "1.1.0", + "@unrs/rspack-resolver-binding-win32-arm64-msvc": "1.1.0", + "@unrs/rspack-resolver-binding-win32-x64-msvc": "1.1.0" + } + }, "node_modules/run-con": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", @@ -11293,9 +11722,9 @@ }, "node_modules/safe-buffer": { "name": "@nolyfill/safe-buffer", - "version": "1.0.41", - "resolved": "https://registry.npmjs.org/@nolyfill/safe-buffer/-/safe-buffer-1.0.41.tgz", - "integrity": "sha512-QUutoN6a0Rf49n6kYVSppQpfraXfrtrUaxTU/GhcxIhz+3GHp+SrBVnTKE3ASB7AzgZJ7XrxhaBgwrF+hSmeKg==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/safe-buffer/-/safe-buffer-1.0.44.tgz", + "integrity": "sha512-SqlKXtlhNTDMeZKey9jnnuPhi8YTl1lJuEcY9zbm5i4Pqe79UJJ8IJ9oiD6DhgI8KjYc+HtLzpQJNRdNYqb/hw==", "license": "MIT", "engines": { "node": ">=12.4.0" @@ -11303,9 +11732,9 @@ }, "node_modules/safe-regex-test": { "name": "@nolyfill/safe-regex-test", - "version": "1.0.29", - "resolved": "https://registry.npmjs.org/@nolyfill/safe-regex-test/-/safe-regex-test-1.0.29.tgz", - "integrity": "sha512-aar+tW/KIy5tzhV/DDty2IM3tEvXqj6dhP8iXIVZOa9gFwPqLZzy54D7gYkn7EwxLPNhHordzsqmnrFEHDYTSg==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/safe-regex-test/-/safe-regex-test-1.0.44.tgz", + "integrity": "sha512-Q6veatd1NebtD8Sre6zjvO35QzG21IskMVOOEbePFcNO9noanNJgsqHeOCr0c5yZz6Z0DAizLg2gIZWokJSkXw==", "dev": true, "license": "MIT", "engines": { @@ -11321,9 +11750,9 @@ }, "node_modules/safer-buffer": { "name": "@nolyfill/safer-buffer", - "version": "1.0.41", - "resolved": "https://registry.npmjs.org/@nolyfill/safer-buffer/-/safer-buffer-1.0.41.tgz", - "integrity": "sha512-RieuhcNjFpL2NObzKlsNGM5rCan1y2PH3KUUJ01Yhxqj4gTB20WplufPmQRSrLdI9BWf8cBrxvXuRtjvMRKzxQ==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/safer-buffer/-/safer-buffer-1.0.44.tgz", + "integrity": "sha512-Ouw1fMwjAy1V4MpnDASfu1DCPgkP0nNFteiiWbFoEGSqa7Vnmkb6if2c522N2WcMk+RuaaabQbC1F1D4/kTXcg==", "license": "MIT", "engines": { "node": ">=12.4.0" @@ -11519,9 +11948,9 @@ } }, "node_modules/solid-js": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.4.tgz", - "integrity": "sha512-ipQl8FJ31bFUoBNScDQTG3BjN6+9Rg+Q+f10bUbnO6EOTTf5NGerJeHc7wyu5I4RMHEl/WwZwUmy/PTRgxxZ8g==", + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.5.tgz", + "integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==", "license": "MIT", "dependencies": { "csstype": "^3.1.0", @@ -11660,9 +12089,9 @@ } }, "node_modules/stable-hash": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", - "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", "dev": true, "license": "MIT" }, @@ -11685,9 +12114,9 @@ } }, "node_modules/std-env": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", - "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", + "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", "dev": true, "license": "MIT" }, @@ -11734,13 +12163,13 @@ }, "node_modules/string.prototype.includes": { "name": "@nolyfill/string.prototype.includes", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/string.prototype.includes/-/string.prototype.includes-1.0.28.tgz", - "integrity": "sha512-RfwmNcAKnstWgNxfVlYpz/hK6V2pnl0r1uinLmGrf4pYN+QviciawKGcBUjkyeB8WUFCuIDE9JhCnTydqJ5O2w==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/string.prototype.includes/-/string.prototype.includes-1.0.44.tgz", + "integrity": "sha512-d1t7rnoAYyoap0X3a/gCnusCvxzK6v7uMFzW8k0mI2WtAK8HiKuzaQUwAriyVPh63GsvQCqvXx8Y5gtdh4LjSA==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -11748,13 +12177,13 @@ }, "node_modules/string.prototype.trimend": { "name": "@nolyfill/string.prototype.trimend", - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/@nolyfill/string.prototype.trimend/-/string.prototype.trimend-1.0.28.tgz", - "integrity": "sha512-fxCTYRU/F6O0Kkhm84Ns4vIWhfFKqCErjpTsmzBPxUefYsUtII0gzpKq08Kzolv779PLL3On048VNEwn8dun4g==", + "version": "1.0.44", + "resolved": "https://registry.npmjs.org/@nolyfill/string.prototype.trimend/-/string.prototype.trimend-1.0.44.tgz", + "integrity": "sha512-3dsKlf4Ma7o+uxLIg5OI1Tgwfet2pE8WTbPjEGWvOe6CSjMtK0skJnnSVHaEVX4N4mYU81To0qDeZOPqjaUotg==", "dev": true, "license": "MIT", "dependencies": { - "@nolyfill/shared": "1.0.28" + "@nolyfill/shared": "1.0.44" }, "engines": { "node": ">=12.4.0" @@ -11829,9 +12258,9 @@ "license": "ISC" }, "node_modules/stylelint": { - "version": "16.14.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.14.1.tgz", - "integrity": "sha512-oqCL7AC3786oTax35T/nuLL8p2C3k/8rHKAooezrPGRvUX0wX+qqs5kMWh5YYT4PHQgVDobHT4tw55WgpYG6Sw==", + "version": "16.16.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.16.0.tgz", + "integrity": "sha512-40X5UOb/0CEFnZVEHyN260HlSSUxPES+arrUphOumGWgXERHfwCD0kNBVILgQSij8iliYVwlc0V7M5bcLP9vPg==", "dev": true, "funding": [ { @@ -11858,7 +12287,7 @@ "debug": "^4.3.7", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^10.0.5", + "file-entry-cache": "^10.0.7", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -11872,14 +12301,14 @@ "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", - "postcss": "^8.5.1", + "postcss": "^8.5.3", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^7.0.0", + "postcss-selector-parser": "^7.1.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", - "supports-hyperlinks": "^3.1.0", + "supports-hyperlinks": "^3.2.0", "svg-tags": "^1.0.0", "table": "^6.9.0", "write-file-atomic": "^5.0.1" @@ -11928,9 +12357,9 @@ } }, "node_modules/stylelint-declaration-strict-value": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/stylelint-declaration-strict-value/-/stylelint-declaration-strict-value-1.10.7.tgz", - "integrity": "sha512-FlMvc3uoQtMcItW3Zh8lHJ7oN2KGns3vZDCaTZoGFRiRIjImQoxO+6gAeRf+Dgi0nXFICIPq9xxFsMi8zuYUsg==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/stylelint-declaration-strict-value/-/stylelint-declaration-strict-value-1.10.11.tgz", + "integrity": "sha512-oVQvhZlFZAiDz9r2BPFZLtTGm1A2JVhdKObKAJoTjFfR4F/NpApC4bMBTxf4sZS76Na3njYKVOaAaKSZ4+FU+g==", "dev": true, "license": "MIT", "engines": { @@ -11941,9 +12370,9 @@ } }, "node_modules/stylelint-define-config": { - "version": "16.14.1", - "resolved": "https://registry.npmjs.org/stylelint-define-config/-/stylelint-define-config-16.14.1.tgz", - "integrity": "sha512-pFMY96De80ZUZldX0iFLnd+FXd/hezIvU4POZNiU+BzcqtvvruTVItc8CJQzSePB5g5AsD5bo28kFa7R4tpS1Q==", + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/stylelint-define-config/-/stylelint-define-config-16.15.0.tgz", + "integrity": "sha512-nzHX9ZpI/k4A7izGYPS79xLAf2HyGvYkk/UXMgsQ7ZQEvkOZpQt4Aca4Qn5DYqNmWnqNlW5E3wK+qUmdR3vdxg==", "dev": true, "license": "MIT", "dependencies": { @@ -12030,25 +12459,25 @@ "license": "MIT" }, "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.0.6.tgz", - "integrity": "sha512-0wvv16mVo9nN0Md3k7DMjgAPKG/TY4F/gYMBVb/wMThFRJvzrpaqBFqF6km9wf8QfYTN+mNg5aeaBLfy8k35uA==", + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.0.7.tgz", + "integrity": "sha512-txsf5fu3anp2ff3+gOJJzRImtrtm/oa9tYLN0iTuINZ++EyVR/nRrg2fKYwvG/pXDofcrvvb0scEbX3NyW/COw==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^6.1.6" + "flat-cache": "^6.1.7" } }, "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.6.tgz", - "integrity": "sha512-F+CKgSwp0pzLx67u+Zy1aCueVWFAHWbXepvXlZ+bWVTaASbm5SyCnSJ80Fp1ePEmS57wU+Bf6cx6525qtMZ4lQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.7.tgz", + "integrity": "sha512-qwZ4xf1v1m7Rc9XiORly31YaChvKt6oNVHuqqZcoED/7O+ToyNVGobKsIAopY9ODcWpEDKEBAbrSOCBHtNQvew==", "dev": true, "license": "MIT", "dependencies": { - "cacheable": "^1.8.8", - "flatted": "^3.3.2", - "hookified": "^1.7.0" + "cacheable": "^1.8.9", + "flatted": "^3.3.3", + "hookified": "^1.7.1" } }, "node_modules/stylelint/node_modules/ignore": { @@ -12348,9 +12777,9 @@ } }, "node_modules/swagger-ui-dist": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.18.3.tgz", - "integrity": "sha512-G33HFW0iFNStfY2x6QXO2JYVMrFruc8AZRX0U/L71aA7WeWfX2E5Nm8E/tsipSZJeIZZbSjUDeynLK/wcuNWIw==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.20.1.tgz", + "integrity": "sha512-qBPCis2w8nP4US7SvUxdJD3OwKcqiWeZmjN2VWhq2v+ESZEXOP/7n4DeiOiiZcGYTKMHAHUUrroHaTsjUWTEGw==", "license": "Apache-2.0", "dependencies": { "@scarf/scarf": "=1.4.0" @@ -12468,9 +12897,9 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", - "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", @@ -12564,17 +12993,20 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", - "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", + "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.2", + "fdir": "^6.4.3", "picomatch": "^4.0.2" }, "engines": { "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, "node_modules/tinyglobby/node_modules/fdir": { @@ -12749,9 +13181,9 @@ } }, "node_modules/type-fest": { - "version": "4.34.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.34.1.tgz", - "integrity": "sha512-6kSc32kT0rbwxD6QL1CYe8IqdzN/J/ILMrNK+HMQCKH3insCDRY/3ITb0vcBss0a3t72fzh2YSzj8ko1HgwT3g==", + "version": "4.37.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz", + "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -12762,9 +13194,9 @@ } }, "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -12816,9 +13248,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "funding": [ { "type": "opencollective", @@ -12892,16 +13324,16 @@ } }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/validate-npm-package-license": { @@ -12932,14 +13364,14 @@ "license": "MIT" }, "node_modules/vite": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz", - "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz", + "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.24.2", - "postcss": "^8.5.1", + "esbuild": "^0.25.0", + "postcss": "^8.5.3", "rollup": "^4.30.1" }, "bin": { @@ -13004,16 +13436,16 @@ } }, "node_modules/vite-node": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.5.tgz", - "integrity": "sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.8.tgz", + "integrity": "sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", "debug": "^4.4.0", "es-module-lexer": "^1.6.0", - "pathe": "^2.0.2", + "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0" }, "bin": { @@ -13033,431 +13465,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", - "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", - "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", - "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", - "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", - "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", - "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", - "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", - "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", - "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", - "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", - "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", - "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", - "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", - "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", - "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", - "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", - "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", - "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", - "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", - "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", - "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", - "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", - "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", - "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/vite/node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -13465,47 +13472,6 @@ "dev": true, "license": "MIT" }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", - "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.24.2", - "@esbuild/android-arm": "0.24.2", - "@esbuild/android-arm64": "0.24.2", - "@esbuild/android-x64": "0.24.2", - "@esbuild/darwin-arm64": "0.24.2", - "@esbuild/darwin-x64": "0.24.2", - "@esbuild/freebsd-arm64": "0.24.2", - "@esbuild/freebsd-x64": "0.24.2", - "@esbuild/linux-arm": "0.24.2", - "@esbuild/linux-arm64": "0.24.2", - "@esbuild/linux-ia32": "0.24.2", - "@esbuild/linux-loong64": "0.24.2", - "@esbuild/linux-mips64el": "0.24.2", - "@esbuild/linux-ppc64": "0.24.2", - "@esbuild/linux-riscv64": "0.24.2", - "@esbuild/linux-s390x": "0.24.2", - "@esbuild/linux-x64": "0.24.2", - "@esbuild/netbsd-arm64": "0.24.2", - "@esbuild/netbsd-x64": "0.24.2", - "@esbuild/openbsd-arm64": "0.24.2", - "@esbuild/openbsd-x64": "0.24.2", - "@esbuild/sunos-x64": "0.24.2", - "@esbuild/win32-arm64": "0.24.2", - "@esbuild/win32-ia32": "0.24.2", - "@esbuild/win32-x64": "0.24.2" - } - }, "node_modules/vite/node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -13522,9 +13488,9 @@ } }, "node_modules/vite/node_modules/rollup": { - "version": "4.34.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz", - "integrity": "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", + "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", "dev": true, "license": "MIT", "dependencies": { @@ -13538,54 +13504,54 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.6", - "@rollup/rollup-android-arm64": "4.34.6", - "@rollup/rollup-darwin-arm64": "4.34.6", - "@rollup/rollup-darwin-x64": "4.34.6", - "@rollup/rollup-freebsd-arm64": "4.34.6", - "@rollup/rollup-freebsd-x64": "4.34.6", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.6", - "@rollup/rollup-linux-arm-musleabihf": "4.34.6", - "@rollup/rollup-linux-arm64-gnu": "4.34.6", - "@rollup/rollup-linux-arm64-musl": "4.34.6", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.6", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.6", - "@rollup/rollup-linux-riscv64-gnu": "4.34.6", - "@rollup/rollup-linux-s390x-gnu": "4.34.6", - "@rollup/rollup-linux-x64-gnu": "4.34.6", - "@rollup/rollup-linux-x64-musl": "4.34.6", - "@rollup/rollup-win32-arm64-msvc": "4.34.6", - "@rollup/rollup-win32-ia32-msvc": "4.34.6", - "@rollup/rollup-win32-x64-msvc": "4.34.6", + "@rollup/rollup-android-arm-eabi": "4.35.0", + "@rollup/rollup-android-arm64": "4.35.0", + "@rollup/rollup-darwin-arm64": "4.35.0", + "@rollup/rollup-darwin-x64": "4.35.0", + "@rollup/rollup-freebsd-arm64": "4.35.0", + "@rollup/rollup-freebsd-x64": "4.35.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", + "@rollup/rollup-linux-arm-musleabihf": "4.35.0", + "@rollup/rollup-linux-arm64-gnu": "4.35.0", + "@rollup/rollup-linux-arm64-musl": "4.35.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", + "@rollup/rollup-linux-riscv64-gnu": "4.35.0", + "@rollup/rollup-linux-s390x-gnu": "4.35.0", + "@rollup/rollup-linux-x64-gnu": "4.35.0", + "@rollup/rollup-linux-x64-musl": "4.35.0", + "@rollup/rollup-win32-arm64-msvc": "4.35.0", + "@rollup/rollup-win32-ia32-msvc": "4.35.0", + "@rollup/rollup-win32-x64-msvc": "4.35.0", "fsevents": "~2.3.2" } }, "node_modules/vitest": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz", - "integrity": "sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz", + "integrity": "sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "3.0.5", - "@vitest/mocker": "3.0.5", - "@vitest/pretty-format": "^3.0.5", - "@vitest/runner": "3.0.5", - "@vitest/snapshot": "3.0.5", - "@vitest/spy": "3.0.5", - "@vitest/utils": "3.0.5", - "chai": "^5.1.2", + "@vitest/expect": "3.0.8", + "@vitest/mocker": "3.0.8", + "@vitest/pretty-format": "^3.0.8", + "@vitest/runner": "3.0.8", + "@vitest/snapshot": "3.0.8", + "@vitest/spy": "3.0.8", + "@vitest/utils": "3.0.8", + "chai": "^5.2.0", "debug": "^4.4.0", "expect-type": "^1.1.0", "magic-string": "^0.30.17", - "pathe": "^2.0.2", + "pathe": "^2.0.3", "std-env": "^3.8.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinypool": "^1.0.2", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0", - "vite-node": "3.0.5", + "vite-node": "3.0.8", "why-is-node-running": "^2.3.0" }, "bin": { @@ -13601,8 +13567,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.0.5", - "@vitest/ui": "3.0.5", + "@vitest/browser": "3.0.8", + "@vitest/ui": "3.0.8", "happy-dom": "*", "jsdom": "*" }, @@ -13730,56 +13696,44 @@ } }, "node_modules/vue-eslint-parser": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", - "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.1.1.tgz", + "integrity": "sha512-bh2Z/Au5slro9QJ3neFYLanZtb1jH+W2bKqGHXAoYD4vZgNG3KeotL7JpPv5xzY4UXUXJl7TrIsnzECH63kd3Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "debug": "^4.3.4", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", + "debug": "^4.4.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.6.0", "lodash": "^4.17.21", - "semver": "^7.3.6" + "semver": "^7.6.3" }, "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://github.com/sponsors/mysticatea" }, "peerDependencies": { - "eslint": ">=6.0.0" + "eslint": "^8.57.0 || ^9.0.0" } }, - "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/vue-eslint-parser/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/vue-eslint-parser/node_modules/eslint-scope": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -13808,14 +13762,14 @@ } }, "node_modules/vue-tsc": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.2.tgz", - "integrity": "sha512-1icPKkxAA5KTAaSwg0wVWdE48EdsH8fgvcbAiqojP4jXKl6LEM3soiW1aG/zrWrFt8Mw1ncG2vG1PvpZpVfehA==", + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.8.tgz", + "integrity": "sha512-jBYKBNFADTN+L+MdesNX/TB3XuDSyaWynKMDgR+yCSln0GQ9Tfb7JS2lr46s2LiFUT1WsmfWsSvIElyxzOPqcQ==", "dev": true, "license": "MIT", "dependencies": { "@volar/typescript": "~2.4.11", - "@vue/language-core": "2.2.2" + "@vue/language-core": "2.2.8" }, "bin": { "vue-tsc": "bin/vue-tsc.js" diff --git a/package.json b/package.json index b6ebec3850..ef1a132994 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,12 @@ "@github/relative-time-element": "4.4.5", "@github/text-expander-element": "2.9.1", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", - "@primer/octicons": "19.15.0", + "@primer/octicons": "19.15.1", "@silverwind/vue3-calendar-heatmap": "2.0.6", "add-asset-webpack-plugin": "3.0.0", "ansi_up": "6.0.2", "asciinema-player": "3.9.0", - "chart.js": "4.4.7", + "chart.js": "4.4.8", "chartjs-adapter-dayjs-4": "1.0.4", "chartjs-plugin-zoom": "2.2.0", "clippie": "4.1.5", @@ -25,34 +25,34 @@ "css-loader": "7.1.2", "dayjs": "1.11.13", "dropzone": "6.0.0-beta.2", - "easymde": "2.18.0", + "easymde": "2.20.0", "esbuild-loader": "4.3.0", "escape-goat": "4.0.0", "fast-glob": "3.3.3", "htmx.org": "2.0.4", - "idiomorph": "0.4.0", + "idiomorph": "0.7.3", "jquery": "3.7.1", "katex": "0.16.21", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "11.4.1", + "mermaid": "11.5.0", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.1", "monaco-editor": "0.52.2", "monaco-editor-webpack-plugin": "7.1.0", "pdfobject": "2.3.1", "perfect-debounce": "1.0.0", - "postcss": "8.5.2", + "postcss": "8.5.3", "postcss-loader": "8.1.1", "postcss-nesting": "13.0.1", "sortablejs": "1.15.6", - "swagger-ui-dist": "5.18.3", + "swagger-ui-dist": "5.20.1", "tailwindcss": "3.4.17", "throttle-debounce": "5.0.2", "tinycolor2": "1.6.0", "tippy.js": "6.3.7", "toastify-js": "1.12.0", "tributejs": "5.1.3", - "typescript": "5.7.3", + "typescript": "5.8.2", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", "vue": "3.5.13", @@ -66,7 +66,7 @@ "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "4.4.1", "@playwright/test": "1.49.1", - "@stoplight/spectral-cli": "6.14.2", + "@stoplight/spectral-cli": "6.14.3", "@stylistic/eslint-plugin-js": "3.1.0", "@stylistic/stylelint-plugin": "3.1.2", "@types/dropzone": "5.7.9", @@ -79,41 +79,41 @@ "@types/throttle-debounce": "5.0.2", "@types/tinycolor2": "1.4.6", "@types/toastify-js": "1.12.3", - "@typescript-eslint/eslint-plugin": "8.24.0", - "@typescript-eslint/parser": "8.24.0", + "@typescript-eslint/eslint-plugin": "8.26.1", + "@typescript-eslint/parser": "8.26.1", "@vitejs/plugin-vue": "5.2.1", - "@vitest/eslint-plugin": "1.1.31", + "@vitest/eslint-plugin": "1.1.37", "eslint": "8.57.0", - "eslint-import-resolver-typescript": "3.8.0", + "eslint-import-resolver-typescript": "3.9.0", "eslint-plugin-array-func": "4.0.0", "eslint-plugin-github": "5.0.2", - "eslint-plugin-import-x": "4.6.1", - "eslint-plugin-no-jquery": "3.1.0", + "eslint-plugin-import-x": "4.7.2", + "eslint-plugin-no-jquery": "3.1.1", "eslint-plugin-no-use-extend-native": "0.5.0", "eslint-plugin-playwright": "2.2.0", "eslint-plugin-regexp": "2.7.0", "eslint-plugin-sonarjs": "3.0.2", "eslint-plugin-unicorn": "56.0.1", - "eslint-plugin-vue": "9.32.0", + "eslint-plugin-vue": "10.0.0", "eslint-plugin-vue-scoped-css": "2.9.0", - "eslint-plugin-wc": "2.2.0", - "happy-dom": "17.1.0", + "eslint-plugin-wc": "2.2.1", + "happy-dom": "17.4.4", "markdownlint-cli": "0.44.0", "material-icon-theme": "5.20.0", - "nolyfill": "1.0.43", + "nolyfill": "1.0.44", "postcss-html": "1.8.0", - "stylelint": "16.14.1", + "stylelint": "16.16.0", "stylelint-config-recommended": "15.0.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", - "stylelint-declaration-strict-value": "1.10.7", - "stylelint-define-config": "16.14.1", + "stylelint-declaration-strict-value": "1.10.11", + "stylelint-define-config": "16.15.0", "stylelint-value-no-unknown-custom-properties": "6.0.1", "svgo": "3.3.2", - "type-fest": "4.34.1", + "type-fest": "4.37.0", "updates": "16.4.2", "vite-string-plugin": "1.4.4", - "vitest": "3.0.5", - "vue-tsc": "2.2.2" + "vitest": "3.0.8", + "vue-tsc": "2.2.8" }, "browserslist": [ "defaults" diff --git a/poetry.lock b/poetry.lock index 16de98b5e2..ca7ae78cb8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "click" @@ -29,14 +29,14 @@ files = [ [[package]] name = "cssbeautifier" -version = "1.15.3" +version = "1.15.4" description = "CSS unobfuscator and beautifier." optional = false python-versions = "*" groups = ["dev"] files = [ - {file = "cssbeautifier-1.15.3-py3-none-any.whl", hash = "sha256:0dcaf5ce197743a79b3a160b84ea58fcbd9e3e767c96df1171e428125b16d410"}, - {file = "cssbeautifier-1.15.3.tar.gz", hash = "sha256:406b04d09e7d62c0be084fbfa2cba5126fe37359ea0d8d9f7b963a6354fc8303"}, + {file = "cssbeautifier-1.15.4-py3-none-any.whl", hash = "sha256:78c84d5e5378df7d08622bbd0477a1abdbd209680e95480bf22f12d5701efc98"}, + {file = "cssbeautifier-1.15.4.tar.gz", hash = "sha256:9bb08dc3f64c101a01677f128acf01905914cf406baf87434dcde05b74c0acf5"}, ] [package.dependencies] @@ -103,14 +103,14 @@ files = [ [[package]] name = "jsbeautifier" -version = "1.15.3" +version = "1.15.4" description = "JavaScript unobfuscator and beautifier." optional = false python-versions = "*" groups = ["dev"] files = [ - {file = "jsbeautifier-1.15.3-py3-none-any.whl", hash = "sha256:b207a15ab7529eee4a35ae7790e9ec4e32a2b5026d51e2d0386c3a65e6ecfc91"}, - {file = "jsbeautifier-1.15.3.tar.gz", hash = "sha256:5f1baf3d4ca6a615bb5417ee861b34b77609eeb12875555f8bbfabd9bf2f3457"}, + {file = "jsbeautifier-1.15.4-py3-none-any.whl", hash = "sha256:72f65de312a3f10900d7685557f84cb61a9733c50dcc27271a39f5b0051bf528"}, + {file = "jsbeautifier-1.15.4.tar.gz", hash = "sha256:5bb18d9efb9331d825735fbc5360ee8f1aac5e52780042803943aa7f854f7592"}, ] [package.dependencies] @@ -403,14 +403,14 @@ files = [ [[package]] name = "yamllint" -version = "1.35.1" +version = "1.36.1" description = "A linter for YAML files." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3"}, - {file = "yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd"}, + {file = "yamllint-1.36.1-py3-none-any.whl", hash = "sha256:3e2ccd47ea12449837adf6b2c56fd9e31172ce42bc1470380806be461f25df66"}, + {file = "yamllint-1.36.1.tar.gz", hash = "sha256:a287689daaafc301a80549b2d0170452ebfdcabd826e3fe3b4c66e322d4851fa"}, ] [package.dependencies] @@ -423,4 +423,4 @@ dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] [metadata] lock-version = "2.1" python-versions = "^3.10" -content-hash = "f2e8260efe6e25f77ef387daff9551e41d25027e4794b42bc7a851ed0dfafd85" +content-hash = "d48a461813418f7b803a7f94713d93076a009a96554e0f4c707be0cc2a95b563" diff --git a/pyproject.toml b/pyproject.toml index 851504e72b..a2aedfe148 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ python = "^3.10" [tool.poetry.group.dev.dependencies] djlint = "1.36.4" -yamllint = "1.35.1" +yamllint = "1.36.1" [tool.djlint] profile="golang" diff --git a/tsconfig.json b/tsconfig.json index 25b500c10d..4dcee6666f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,8 +18,10 @@ "allowJs": true, "allowSyntheticDefaultImports": true, "alwaysStrict": true, + "erasableSyntaxOnly": true, "esModuleInterop": true, "isolatedModules": true, + "libReplacement": false, "noEmit": true, "resolveJsonModule": true, "skipLibCheck": true, diff --git a/updates.config.js b/updates.config.js index 4ef1ca701b..c1dae1875b 100644 --- a/updates.config.js +++ b/updates.config.js @@ -1,10 +1,13 @@ export default { exclude: [ '@mcaptcha/vanilla-glue', // breaking changes in rc versions need to be handled + '@stylistic/eslint-plugin-js', // need to migrate to eslint 9 'eslint', // need to migrate to eslint flat config first 'eslint-plugin-array-func', // need to migrate to eslint flat config first 'eslint-plugin-github', // need to migrate to eslint 9 - https://github.com/github/eslint-plugin-github/issues/585 'eslint-plugin-no-use-extend-native', // need to migrate to eslint flat config first + 'eslint-plugin-unicorn', // need to migrate to eslint 9 'eslint-plugin-vitest', // need to migrate to eslint flat config first + 'tailwindcss', // need to migrate ], }; diff --git a/web_src/js/features/repo-issue-sidebar-combolist.ts b/web_src/js/features/repo-issue-sidebar-combolist.ts index 8db2f7665f..c30d4fe50d 100644 --- a/web_src/js/features/repo-issue-sidebar-combolist.ts +++ b/web_src/js/features/repo-issue-sidebar-combolist.ts @@ -30,9 +30,11 @@ class IssueSidebarComboList { elList: HTMLElement; elComboValue: HTMLInputElement; initialValues: string[]; + container: HTMLElement; - constructor(private container: HTMLElement) { - this.updateUrl = this.container.getAttribute('data-update-url'); + constructor(container: HTMLElement) { + this.container = container; + this.updateUrl = container.getAttribute('data-update-url'); this.updateAlgo = container.getAttribute('data-update-algo'); this.selectionMode = container.getAttribute('data-selection-mode'); if (!['single', 'multiple'].includes(this.selectionMode)) throw new Error(`Invalid data-update-on: ${this.selectionMode}`); diff --git a/web_src/js/htmx.ts b/web_src/js/htmx.ts index 3f9a5a815c..c23c3a21fa 100644 --- a/web_src/js/htmx.ts +++ b/web_src/js/htmx.ts @@ -1,5 +1,5 @@ import {showErrorToast} from './modules/toast.ts'; -import 'idiomorph/dist/idiomorph-ext.js'; // https://github.com/bigskysoftware/idiomorph#htmx +import 'idiomorph/htmx'; import type {HtmxResponseInfo} from 'htmx.org'; type HtmxEvent = Event & {detail: HtmxResponseInfo}; diff --git a/webpack.config.js b/webpack.config.js index 7e6f499611..931bf67071 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -249,7 +249,6 @@ export default { }, override: { 'khroma@*': {licenseName: 'MIT'}, // https://github.com/fabiospampinato/khroma/pull/33 - 'idiomorph@0.3.0': {licenseName: 'BSD-2-Clause'}, // https://github.com/bigskysoftware/idiomorph/pull/37 }, emitError: true, allow: '(Apache-2.0 OR 0BSD OR BSD-2-Clause OR BSD-3-Clause OR MIT OR ISC OR CPAL-1.0 OR Unlicense OR EPL-1.0 OR EPL-2.0)', From 01c8f092a078af23c5588107ef2a6858ed3b8d83 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 16 Mar 2025 12:05:26 +0100 Subject: [PATCH 235/655] Simplify secure context check (#33906) As discussed in https://github.com/go-gitea/gitea/pull/33820/files#r1997532169. --- web_src/js/features/user-auth-webauthn.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/web_src/js/features/user-auth-webauthn.ts b/web_src/js/features/user-auth-webauthn.ts index e6c37581e0..1f336b9741 100644 --- a/web_src/js/features/user-auth-webauthn.ts +++ b/web_src/js/features/user-auth-webauthn.ts @@ -11,13 +11,10 @@ export async function initUserAuthWebAuthn() { return; } - if (window.location.protocol === 'http:') { - // webauthn is only supported on secure contexts - const isLocalhost = ['localhost', '127.0.0.1'].includes(window.location.hostname); - if (!isLocalhost) { - hideElem(elSignInPasskeyBtn); - return; - } + // webauthn is only supported on secure contexts + if (!window.isSecureContext) { + hideElem(elSignInPasskeyBtn); + return; } if (!detectWebAuthnSupport()) { From 1ea5216f4a5887e585bf7de12b62cfec83b0f4e3 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 16 Mar 2025 13:08:16 +0100 Subject: [PATCH 236/655] Replace text-align classes with tailwind (#33905) Small refactor to remove these CSS classes in favor of tailwind. --------- Co-authored-by: wxiaoguang --- templates/admin/dashboard.tmpl | 26 ++++++++-------- templates/devtest/fomantic-modal.tmpl | 10 +++++++ templates/install.tmpl | 2 +- templates/org/team/new.tmpl | 12 ++++---- templates/org/team/teams.tmpl | 2 +- templates/projects/view.tmpl | 2 +- templates/repo/branch/list.tmpl | 6 ++-- templates/repo/commit_page.tmpl | 4 +-- templates/repo/commits_list.tmpl | 8 ++--- templates/repo/diff/box.tmpl | 2 +- templates/repo/issue/choose.tmpl | 12 ++++---- templates/repo/issue/milestone_issues.tmpl | 2 +- templates/repo/issue/new_form.tmpl | 2 +- .../repo/issue/sidebar/issue_management.tmpl | 2 +- .../repo/issue/sidebar/reviewer_list.tmpl | 2 +- templates/repo/issue/view_content.tmpl | 4 +-- .../view_content/reference_issue_dialog.tmpl | 2 +- templates/repo/migrate/migrating.tmpl | 8 ++--- templates/repo/pulse.tmpl | 2 +- templates/repo/settings/branches.tmpl | 2 +- templates/repo/settings/lfs.tmpl | 2 +- templates/repo/settings/lfs_locks.tmpl | 2 +- templates/repo/settings/options.tmpl | 14 ++++----- templates/repo/settings/tags.tmpl | 4 +-- templates/repo/wiki/new.tmpl | 2 +- templates/repo/wiki/pages.tmpl | 2 +- templates/repo/wiki/revision.tmpl | 2 +- templates/shared/actions/runner_list.tmpl | 2 +- templates/shared/user/block_user_dialog.tmpl | 2 +- templates/shared/user/blocked_users.tmpl | 2 +- templates/user/auth/grant.tmpl | 2 +- templates/user/auth/grant_error.tmpl | 2 +- templates/user/auth/webauthn.tmpl | 2 +- .../notification_subscriptions.tmpl | 2 +- web_src/css/base.css | 8 ----- web_src/css/modules/container.css | 4 --- web_src/css/modules/grid.css | 30 ------------------- web_src/css/modules/modal.css | 1 + web_src/css/modules/segment.css | 7 ----- web_src/css/modules/table.css | 15 ---------- 40 files changed, 83 insertions(+), 136 deletions(-) diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl index af2349d288..2426a43b15 100644 --- a/templates/admin/dashboard.tmpl +++ b/templates/admin/dashboard.tmpl @@ -15,57 +15,57 @@ {{ctx.Locale.Tr "admin.dashboard.delete_inactive_accounts"}} - + {{ctx.Locale.Tr "admin.dashboard.delete_repo_archives"}} - + {{ctx.Locale.Tr "admin.dashboard.delete_missing_repos"}} - + {{ctx.Locale.Tr "admin.dashboard.git_gc_repos"}} - + {{if and (not .SSH.Disabled) (not .SSH.StartBuiltinServer)}} {{ctx.Locale.Tr "admin.dashboard.resync_all_sshkeys"}} - + {{ctx.Locale.Tr "admin.dashboard.resync_all_sshprincipals"}} - + {{end}} {{ctx.Locale.Tr "admin.dashboard.resync_all_hooks"}} - + {{ctx.Locale.Tr "admin.dashboard.reinit_missing_repos"}} - + {{ctx.Locale.Tr "admin.dashboard.sync_external_users"}} - + {{ctx.Locale.Tr "admin.dashboard.repo_health_check"}} - + {{ctx.Locale.Tr "admin.dashboard.delete_generated_repository_avatars"}} - + {{ctx.Locale.Tr "admin.dashboard.sync_repo_branches"}} - + {{ctx.Locale.Tr "admin.dashboard.sync_repo_tags"}} - + diff --git a/templates/devtest/fomantic-modal.tmpl b/templates/devtest/fomantic-modal.tmpl index 2fbe2bd97d..838c6893a4 100644 --- a/templates/devtest/fomantic-modal.tmpl +++ b/templates/devtest/fomantic-modal.tmpl @@ -49,6 +49,16 @@
+ +