From 5f136783d114b302eb2a42219e403624ef2abd93 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 13 Jun 2022 00:10:09 +0000 Subject: [PATCH 1/7] [skip ci] Updated translations via Crowdin --- options/locale/locale_bg-BG.ini | 4 ++++ options/locale/locale_cs-CZ.ini | 4 ++++ options/locale/locale_de-DE.ini | 4 ++++ options/locale/locale_el-GR.ini | 20 ++++---------------- options/locale/locale_es-ES.ini | 4 ++++ options/locale/locale_fa-IR.ini | 4 ++++ options/locale/locale_fi-FI.ini | 4 ++++ options/locale/locale_fr-FR.ini | 4 ++++ options/locale/locale_hu-HU.ini | 4 ++++ options/locale/locale_id-ID.ini | 4 ++++ options/locale/locale_is-IS.ini | 4 ++++ options/locale/locale_it-IT.ini | 4 ++++ options/locale/locale_ja-JP.ini | 20 ++++---------------- options/locale/locale_ko-KR.ini | 4 ++++ options/locale/locale_lv-LV.ini | 4 ++++ options/locale/locale_ml-IN.ini | 4 ++++ options/locale/locale_nl-NL.ini | 4 ++++ options/locale/locale_pl-PL.ini | 4 ++++ options/locale/locale_pt-BR.ini | 9 ++++----- options/locale/locale_pt-PT.ini | 29 +++++++++++++---------------- options/locale/locale_ru-RU.ini | 4 ++++ options/locale/locale_si-LK.ini | 4 ++++ options/locale/locale_sv-SE.ini | 4 ++++ options/locale/locale_tr-TR.ini | 4 ++++ options/locale/locale_uk-UA.ini | 4 ++++ options/locale/locale_zh-CN.ini | 29 +++++++++++++---------------- options/locale/locale_zh-HK.ini | 4 ++++ options/locale/locale_zh-TW.ini | 18 +++++++++++++++++- 28 files changed, 143 insertions(+), 70 deletions(-) diff --git a/options/locale/locale_bg-BG.ini b/options/locale/locale_bg-BG.ini index ea4e2a105d..ee19a6ad23 100644 --- a/options/locale/locale_bg-BG.ini +++ b/options/locale/locale_bg-BG.ini @@ -768,9 +768,13 @@ pulls.num_conflicting_files_n=%d конфликтни файлове pulls.no_merge_desc=Тази заявка за сливане не може да бъде обединена, защото всички опции за обединяване на хранилището са изключени. pulls.no_merge_helper=Включете опции за сливане в настройките на хранилището или обединете заявката за сливане ръчно. pulls.no_merge_wip=Тази заявка за сливане не може да бъде обединена, защото е отбелязана като работа в прогрес. + ; %[2]s
%[3]s
pulls.status_checks_success=Всички проверявания бяха успешни + + + milestones.new=Нов етап milestones.open_tab=%d отворени milestones.close_tab=%d затворени diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 896b4ee970..6ad2bd679b 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -1500,6 +1500,7 @@ pulls.squash_merge_pull_request=Vytvořit squash commit pulls.merge_manually=Sloučeno ručně pulls.merge_commit_id=ID slučovacího commitu pulls.require_signed_wont_sign=Větev vyžaduje podepsané commity, ale toto sloučení nebude podepsáno + pulls.invalid_merge_option=Nemůžete použít tuto možnost sloučení pro tento požadavek na natažení. pulls.merge_conflict=Sloučení selhalo: Došlo ke konfliktu při sloučení. Tip: Zkuste jinou strategii pulls.merge_conflict_summary=Chybové hlášení @@ -1528,6 +1529,9 @@ pulls.merge_instruction_hint=`Můžete také zobrazit Anleitu pulls.merge_instruction_step1_desc=Wechsle auf einen neuen Branch in deinem lokalen Repository und teste die Änderungen. pulls.merge_instruction_step2_desc=Führe die Änderungen zusammen und aktualisiere den Stand online auf Gitea. + + + milestones.new=Neuer Meilenstein milestones.open_tab=%d offen milestones.close_tab=%d geschlossen diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 11d8855f96..99b90edc4b 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -1568,14 +1568,7 @@ pulls.squash_merge_pull_request=Δημιουργία υποβολής squash pulls.merge_manually=Συγχωνεύτηκαν χειροκίνητα pulls.merge_commit_id=Το ID της υποβολής συγχώνευσης pulls.require_signed_wont_sign=Ο κλάδος απαιτεί υπογεγραμμένες υποβολές αλλά αυτή η συγχώνευση δεν θα υπογραφεί -pulls.merge_pull_request_now=Συγχώνευση του Pull Request Τώρα -pulls.rebase_merge_pull_request_now=Αλλαγή Βάσης και Συγχώνευση Τώρα -pulls.rebase_merge_commit_pull_request_now=Αλλαγή Βάσης και Συγχώνευση Τώρα (--no-ff) -pulls.squash_merge_pull_request_now=Στρίμωγμα και Συγχώνευση τώρα -pulls.merge_pull_request_on_status_success=Συγχώνευση Του Pull Request Όταν Όλοι Οι Έλεγχοι Επιτύχουν -pulls.rebase_merge_pull_request_on_status_success=Αλλαγή Βάσης και Συγχώνευση Όταν Όλοι Οι Έλεγχοι Πετύχουν -pulls.rebase_merge_commit_pull_request_on_status_success=Αλλαγή Βάσης και Συγχώνευση (--no-ff) Όταν Όλοι Οι Έλεγχοι Πετύχουν -pulls.squash_merge_pull_request_on_status_success=Στρίμωγμα και Συγχώνευση Όταν Όλοι Οι Έλεγχοι Επιτύχουν + pulls.invalid_merge_option=Δεν μπορείτε να χρησιμοποιήσετε αυτήν την επιλογή συγχώνευσης για αυτό το pull request. pulls.merge_conflict=Η Συγχώνευση Απέτυχε: Υπήρξε μια διένεξη κατά τη συγχώνευση. Υπόδειξη: Δοκιμάστε μια διαφορετική στρατηγική pulls.merge_conflict_summary=Μήνυμα Σφάλματος @@ -1606,14 +1599,9 @@ pulls.reopened_at=`άνοιξε ξανά αυτό το pull request τις οδηγίες της γραμμής εντολών.` pulls.merge_instruction_step1_desc=Από το αποθετήριο του έργου σας, ελέγξτε έναν νέο κλάδο και τεστάρετε τις αλλαγές. pulls.merge_instruction_step2_desc=Συγχώνευσε τις αλλαγές και ενημέρωσε στο Gitea. -pulls.merge_on_status_success=Το pull request προγραμματίστηκε για συγχώνευση όταν πετύχουν όλοι οι έλεγχοι. -pulls.merge_on_status_success_already_scheduled=Αυτό το αίτημα έλξης έχει ήδη προγραμματιστεί για συγχώνευση όταν πετύχουν όλοι οι έλεγχοι. -pulls.pr_has_pending_merge_on_success=%[1]s έχει προγραμματίσει αυτό το pull request για αυτόματη συγχώνευση όταν όλοι οι έλεγχοι επιτύχουν %[2]s. -pulls.merge_pull_on_success_cancel=Ακύρωση αυτόματης συγχώνευσης -pulls.pull_request_not_scheduled=Αυτό το pull request δεν είναι προγραμματισμένο να συγχωνευτεί αυτόματα. -pulls.pull_request_schedule_canceled=Η αυτόματη συγχώνευση ακυρώθηκε για αυτό το pull request. -pulls.pull_request_scheduled_auto_merge=`έχει προγραμματισεί αυτό το pull request για αυτόματη συγχώνευση όταν όλοι οι έλεγχοι πετύχουν %[1]s` -pulls.pull_request_canceled_scheduled_auto_merge=`ακύρωσε την αυτόματη συγχώνευση αυτού του pull request όταν όλοι οι έλεγχοι πετύχουν %[1]s` + + + milestones.new=Νέο Ορόσημο milestones.open_tab=%d Ανοιχτά diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index a35cffe495..175895e61f 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -1523,6 +1523,7 @@ pulls.squash_merge_pull_request=Crear commit squash pulls.merge_manually=Fusionado manualmente pulls.merge_commit_id=La identificación del commit fusionado pulls.require_signed_wont_sign=Esta rama requiere commits firmados pero esta fusión no será firmada + pulls.invalid_merge_option=No puede utilizar esta opción de combinación para esta solicitud de extracción. pulls.merge_conflict=Fusión fallida: Hubo un conflicto mientras se fusionaba. Pista: Pruebe una estrategia diferente pulls.merge_conflict_summary=Mensaje de error @@ -1554,6 +1555,9 @@ pulls.merge_instruction_hint=`También puede ver ins pulls.merge_instruction_step1_desc=Desde el repositorio de su proyecto, revisa una nueva rama y prueba los cambios. pulls.merge_instruction_step2_desc=Combine los cambios y actualice en Gitea. + + + milestones.new=Nuevo hito milestones.open_tab=%d abiertas milestones.close_tab=%d cerradas diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 9cf067a010..0da69185f1 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -1449,6 +1449,7 @@ pulls.squash_merge_pull_request=ایجاد commit اسکواش pulls.merge_manually=بصورت دستی ادغام شد pulls.merge_commit_id=شماره کامیت ادغام pulls.require_signed_wont_sign=انشعاب نیازمند تغییرات امضا شده است اما این ادغام امضا نخواهد شد + pulls.invalid_merge_option=شما نمی‌توانید از این گزینه برای تقاضای واکشی استفاده کنید. pulls.merge_conflict=ادغام ناموفق بود: در حین ادغام مغایرت وجود داشت. نکته: استراتژی متفاوتی را امتحان کنید pulls.merge_conflict_summary=پیغام خطا @@ -1477,6 +1478,9 @@ pulls.merge_instruction_hint=`همچنین می‌توانید %[2]s
%[3]s
pulls.status_checking=Néhány ellenőrzés függőben van pulls.status_checks_success=Minden ellenőrzés sikeres volt + + + milestones.new=Új mérföldkő milestones.open_tab=%d Nyitott milestones.close_tab=%d Zárt diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index 41a9e84ad7..18f3e20e6f 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -838,8 +838,12 @@ pulls.reopen_to_merge=Tolong buka kembali permintaan tarik ini untuk melaksanaka pulls.merged=Menggabungkan pulls.can_auto_merge_desc=Permintaan tarik ini dapat digabung secara otomatis. + ; %[2]s
%[3]s
+ + + milestones.new=Milestone Baru milestones.open_tab=%d Terbuka milestones.close_tab=%d Tertutup diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index b28196e80c..dfc4827603 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -925,10 +925,14 @@ pulls.waiting_count_1=%d bíður endurskoðunar pulls.waiting_count_n=%d bíða endurskoðunar pulls.merge_manually=Sameinað handvirkt + ; %[2]s
%[3]s
pulls.status_checks_requested=Nauðsynlegt pulls.status_checks_details=Nánar + + + milestones.new=Nýtt tímamót milestones.open_tab=%d Opin milestones.close_tab=%d Lokuð diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index a6bd6ad1bb..a8f4b534df 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -1230,6 +1230,7 @@ pulls.no_merge_wip=Questa pull request non può essere unita perché è contrass pulls.no_merge_not_ready=Questa pull request non è pronta per il merge, controlla lo stato della revisione e i controlli di stato. pulls.no_merge_access=Non sei autorizzato ad effettuare il merge su questa pull request. pulls.require_signed_wont_sign=Il branch richiede commit firmati ma questo merge non verrà firmato + pulls.invalid_merge_option=Non puoi utilizzare questa opzione di merge per questa pull request. pulls.merge_conflict_summary=Messaggio d'errore ; %[2]s
%[3]s
@@ -1247,6 +1248,9 @@ pulls.update_branch_success=Brench aggiornato con successo pulls.update_not_allowed=Non sei abilitato ad aggiornare il branch pulls.outdated_with_base_branch=Questo brench non è aggiornato con il branch di base + + + milestones.new=Nuova Milestone milestones.open_tab=%d Aperti milestones.close_tab=%d Chiusi diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 887f675810..3ac3554888 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -1568,14 +1568,7 @@ pulls.squash_merge_pull_request=スカッシュコミットを作成 pulls.merge_manually=手動マージ済みにする pulls.merge_commit_id=マージコミットID pulls.require_signed_wont_sign=ブランチでは署名されたコミットが必須ですが、このマージでは署名がされません -pulls.merge_pull_request_now=今すぐプルリクエストをマージ -pulls.rebase_merge_pull_request_now=今すぐリベースしてマージ -pulls.rebase_merge_commit_pull_request_now=今すぐリベースしてマージ(--no-ff) -pulls.squash_merge_pull_request_now=今すぐスカッシュしてマージ -pulls.merge_pull_request_on_status_success=すべてのチェックが成功したときにプルリクエストをマージ -pulls.rebase_merge_pull_request_on_status_success=すべてのチェックが成功したときにリベースしてマージ -pulls.rebase_merge_commit_pull_request_on_status_success=すべてのチェックが成功したときにリベースしてマージ(--no-ff) -pulls.squash_merge_pull_request_on_status_success=すべてのチェックが成功したときにスカッシュしてマージ + pulls.invalid_merge_option=このプルリクエストでは、指定したマージ方法は使えません。 pulls.merge_conflict=マージ失敗: マージ中にコンフリクトがありました。 ヒント: 別のストラテジーを試してみてください pulls.merge_conflict_summary=エラーメッセージ @@ -1606,14 +1599,9 @@ pulls.reopened_at=`がプルリクエストを再オープン
コマンドラインの手順も確認できます。` pulls.merge_instruction_step1_desc=あなたのプロジェクトリポジトリで新しいブランチをチェックアウトし、変更内容をテストします。 pulls.merge_instruction_step2_desc=変更内容をマージして、Giteaに反映します。 -pulls.merge_on_status_success=このプルリクエストは、すべてのチェックが成功したときにマージされるようにスケジュールされました。 -pulls.merge_on_status_success_already_scheduled=このプルリクエストは、すべてのチェックが成功したときにマージされるようにスケジュールされています。 -pulls.pr_has_pending_merge_on_success=%[1]s が、すべてのチェックが成功すると自動マージを行うよう、このプルリクエストをスケジュール %[2]s。 -pulls.merge_pull_on_success_cancel=自動マージをキャンセル -pulls.pull_request_not_scheduled=このプルリクエストは自動マージとしてスケジュールされていません。 -pulls.pull_request_schedule_canceled=このプルリクエストの自動マージはキャンセルされました。 -pulls.pull_request_scheduled_auto_merge=`が、すべてのチェックが成功すると自動マージを行うよう、このプルリクエストをスケジュール %[1]s` -pulls.pull_request_canceled_scheduled_auto_merge=`が、すべてのチェックが成功したときのプルリクエストの自動マージをキャンセル %[1]s` + + + milestones.new=新しいマイルストーン milestones.open_tab=%d件 オープン中 diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index ed48ada226..80b598c5be 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -859,9 +859,13 @@ pulls.can_auto_merge_desc=이 풀리퀘스트는 자동적으로 머지될 수 pulls.cannot_auto_merge_helper=충돌을 해결하려면 수동으로 머지하십시오. pulls.no_merge_desc=모든 저장소 머지 옵션이 비활성화 되어있기 때문에 이 풀 리퀘스트를 머지할 수 없습니다. + pulls.invalid_merge_option=이 풀 리퀘스트에서 설정한 머지 옵션을 사용하실 수 없습니다. ; %[2]s
%[3]s
+ + + milestones.new=새로운 마일스톤 milestones.open_tab=%d개 열림 milestones.close_tab=%d개 닫힘 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 13aea77c79..ccc6bd280f 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -1511,6 +1511,7 @@ pulls.squash_merge_pull_request=Izveidot saspiešanas revīziju pulls.merge_manually=Manuāli sapludināts pulls.merge_commit_id=Sapludināšanas revīzijas ID pulls.require_signed_wont_sign=Atzarā var iesūtīt tikai parakstītas revīzijas, bet sapludināšanas revīzijas netiks parakstīta + pulls.invalid_merge_option=Nav iespējams izmantot šādu sapludināšanas veidu šim izmaiņu pieprasījumam. pulls.merge_conflict=Sapludināšana neizdevās: Veicot sapludināšanu, radās konflikts. Mēģiniet izmantot citu sapludināšanas stratēģiju pulls.merge_conflict_summary=Kļūdas paziņojums @@ -1542,6 +1543,9 @@ pulls.merge_instruction_hint=`Varat aplūkot arī ko pulls.merge_instruction_step1_desc=Projekta repozitorijā izveidojiet jaunu jaunu atzaru un pārbaudiet savas izmaiņas. pulls.merge_instruction_step2_desc=Sapludināt izmaiņas un atjaunot tās Gitea. + + + milestones.new=Jauns atskaites punkts milestones.open_tab=%d atvērti milestones.close_tab=%d aizvērti diff --git a/options/locale/locale_ml-IN.ini b/options/locale/locale_ml-IN.ini index 285c7e8e4b..be06680441 100644 --- a/options/locale/locale_ml-IN.ini +++ b/options/locale/locale_ml-IN.ini @@ -723,8 +723,12 @@ issues.dependency.add_error_dep_not_same_repo=രണ്ട് പ്രശ്ന + ; %[2]s
%[3]s
+ + + milestones.filter_sort.most_issues=മിക്ക ഇഷ്യൂകളും milestones.filter_sort.least_issues=കുറഞ്ഞ ഇഷ്യൂകളെങ്കിലും diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index 66c3fee81b..a18f6f6981 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -1253,6 +1253,7 @@ pulls.no_merge_wip=Deze pull-aanvraag kan niet worden samengevoegd omdat hij als pulls.no_merge_not_ready=Deze pull-aanvraag is niet klaar om samen te voegen, controleer de status en status controles. pulls.no_merge_access=Je bent niet gemachtigd om deze pull-aanvraag samen te voegen. pulls.require_signed_wont_sign=De branch heeft ondertekende commits nodig, maar deze merge zal niet worden ondertekend + pulls.invalid_merge_option=Je kan de samenvoegingsoptie niet gebruiken voor deze pull-aanvraag. pulls.merge_conflict=Samenvoegen mislukt: Er was een conflict tijdens het samenvoegen. Hint: Probeer een andere strategie pulls.merge_conflict_summary=Foutmelding @@ -1276,6 +1277,9 @@ pulls.outdated_with_base_branch=Deze branch is verouderd met de basis branch pulls.closed_at=`heeft deze pull request gesloten
%[2]s` pulls.reopened_at=`heropende deze pull request %[2]s` + + + milestones.new=Nieuwe mijlpaal milestones.open_tab=%d geopend milestones.close_tab=%d gesloten diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 2bbf821664..06a306fe30 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -1421,6 +1421,7 @@ pulls.no_merge_not_ready=Ten Pull Request nie jest gotowy do scalenia, sprawdź pulls.no_merge_access=Nie masz uprawnień, aby scalić ten Pull Request. pulls.merge_manually=Ręcznie scalone pulls.require_signed_wont_sign=Ta gałąź wymaga podpisanych commitów, ale to scalenie nie będzie podpisane + pulls.invalid_merge_option=Nie możesz użyć tej opcji scalania dla tego pull request'a. pulls.merge_conflict=Scalenie nie powiodło się: Wystąpił konflikt przy scalaniu. Porada: Wypróbuj innej strategii pulls.merge_conflict_summary=Komunikat o błędzie @@ -1449,6 +1450,9 @@ pulls.merge_instruction_hint=`Możesz także zobaczyć %[2]sinstruções para a linha de comandos.` pulls.merge_instruction_step1_desc=No repositório do seu projeto, crie um novo branch e teste as alterações. pulls.merge_instruction_step2_desc=Faça merge das alterações e atualize no Gitea. -pulls.merge_pull_on_success_cancel=Cancelar merge automático + + + milestones.new=Novo marco milestones.open_tab=%d Aberto diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 14a8d11dc3..611b71bce7 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -1568,14 +1568,7 @@ pulls.squash_merge_pull_request=Criar cometimento de compactação pulls.merge_manually=Integrado manualmente pulls.merge_commit_id=O ID de cometimento da integração pulls.require_signed_wont_sign=O ramo requer que os cometimentos sejam assinados mas esta integração não vai ser assinada -pulls.merge_pull_request_now=Executar agora a integração constante no pedido -pulls.rebase_merge_pull_request_now=Mudar a base e integrar agora -pulls.rebase_merge_commit_pull_request_now=Mudar a base e integrar agora (--no-ff) -pulls.squash_merge_pull_request_now=Compactar e integrar agora -pulls.merge_pull_request_on_status_success=Executar a integração constante no pedido quando todas as verificações forem bem sucedidas -pulls.rebase_merge_pull_request_on_status_success=Mudar a base e integrar quando todas as verificações forem bem sucedidas -pulls.rebase_merge_commit_pull_request_on_status_success=Mudar a base e integrar (--no-ff) quando todas as verificações forem bem sucedidas -pulls.squash_merge_pull_request_on_status_success=Compactar e integrar quando todas as verificações forem bem sucedidas + pulls.invalid_merge_option=Não pode usar esta opção de integração neste pedido de integração. pulls.merge_conflict=A integração falhou: Houve um conflito durante a integração. Dica: tente uma estratégia diferente pulls.merge_conflict_summary=Mensagem de erro @@ -1606,14 +1599,18 @@ pulls.reopened_at=`reabriu este pedido de integração instruções para a linha de comandos.` pulls.merge_instruction_step1_desc=No seu repositório, crie um novo ramo e teste as modificações. pulls.merge_instruction_step2_desc=Integre as modificações e envie para o Gitea. -pulls.merge_on_status_success=O pedido de integração foi agendado para ser executado quando todas as verificações forem bem sucedidas. -pulls.merge_on_status_success_already_scheduled=Este pedido de integração já está agendado para ser executado quando todas as verificações forem bem sucedidas. -pulls.pr_has_pending_merge_on_success=%[1]s agendou este pedido de integração para ser executado automaticamente quando todas as verificações forem bem sucedidas %[2]s. -pulls.merge_pull_on_success_cancel=Cancelar a integração automática -pulls.pull_request_not_scheduled=Este pedido de integração não está agendado para ser executado automaticamente. -pulls.pull_request_schedule_canceled=A integração automática foi cancelada para este pedido de integração. -pulls.pull_request_scheduled_auto_merge=`agendou este pedido de integração para ser executado automaticamente quando todas as verificações forem bem sucedidas %[1]s` -pulls.pull_request_canceled_scheduled_auto_merge=`cancelou a execução automática deste pedido de integração que iria ser executando quando todas as verificações fossem bem sucedidas %[1]s` + +pulls.auto_merge_button_when_succeed=(quando as verificações forem bem-sucedidas) +pulls.auto_merge_when_succeed=Integrar automaticamente quando todas as verificações forem bem-sucedidas +pulls.auto_merge_newly_scheduled=O pedido de integração foi agendado para ser executado quando todas as verificações forem bem-sucedidas. +pulls.auto_merge_has_pending_schedule=%[1]s agendou este pedido de integração para ser executado automaticamente quando todas as verificações forem bem-sucedidas %[2]s. + +pulls.auto_merge_cancel_schedule=Cancelar a integração automática +pulls.auto_merge_not_scheduled=Este pedido de integração não está agendado para ser executado automaticamente. +pulls.auto_merge_canceled_schedule=A integração automática foi cancelada para este pedido de integração. + +pulls.auto_merge_newly_scheduled_comment=`agendou este pedido de integração para ser executado automaticamente quando todas as verificações forem bem-sucedidas %[1]s` +pulls.auto_merge_canceled_schedule_comment=`cancelou a execução automática deste pedido de integração que iria ocorrer quando todas as verificações fossem bem-sucedidas %[1]s` milestones.new=Nova etapa milestones.open_tab=%d abertas diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 377ef1cb31..a3c1c09acb 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -1519,6 +1519,7 @@ pulls.squash_merge_pull_request=Создать объединенный (squash) pulls.merge_manually=Слито вручную pulls.merge_commit_id=ID коммита слияния pulls.require_signed_wont_sign=Данная ветка ожидает подписанные коммиты, однако слияние не будет подписано + pulls.invalid_merge_option=Этот параметр слияния нельзя использовать для этого запроса на слияние. pulls.merge_conflict=Слияние не удалось: Произошел конфликт во время слияния. Совет: попробуйте другую стратегию pulls.merge_conflict_summary=Сообщение об ошибке @@ -1549,6 +1550,9 @@ pulls.merge_instruction_hint=`Вы также можете просмотрет pulls.merge_instruction_step1_desc=В репозитории вашего проекта посмотрите новую ветку и протестируйте изменения. pulls.merge_instruction_step2_desc=Объединить изменения и обновить на Gitea. + + + milestones.new=Новый этап milestones.open_tab=%d открыто(ы) milestones.close_tab=%d закрыто(ы) diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 397a851821..b6c9bc04af 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -1393,6 +1393,7 @@ pulls.squash_merge_pull_request=ස්කොෂ් කැපීමට සාද pulls.merge_manually=අතින් සංයුක්ත කර ඇත pulls.merge_commit_id=ඒකාබද්ධ කිරීමේ හැඳුනුම්පත pulls.require_signed_wont_sign=ශාඛාවට අත්සන් කළ කොපියක් අවශ්ය වුවද මෙම ඒකාබද්ධ කිරීම අත්සන් නොකෙරේ + pulls.invalid_merge_option=ඔබ මෙම අදින්න ඉල්ලීම සඳහා මෙම ඒකාබද්ධ විකල්පය භාවිතා කළ නොහැක. pulls.merge_conflict=ඒකාබද්ධ කිරීම අසමත් විය: ඒකාබද්ධ වන අතර ගැටුමක් ඇති විය. ඉඟිය: වෙනත් උපාය මාර්ගයක් උත්සාහ කරන්න pulls.merge_conflict_summary=දෝෂ පණිවිඩය @@ -1421,6 +1422,9 @@ pulls.merge_instruction_hint=`ඔබට විධා pulls.merge_instruction_step1_desc=ඔබගේ ව්යාපෘති ගබඩාවෙන්, නව ශාඛාවක් පරීක්ෂා කර වෙනස්කම් පරීක්ෂා කරන්න. pulls.merge_instruction_step2_desc=Gitea හි වෙනස්කම් සහ යාවත්කාලීන කිරීම ඒකාබද්ධ කරන්න. + + + milestones.new=නව සන්ධිස්ථානයක් milestones.open_tab=%d විවෘත milestones.close_tab=%d වසා diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index 25bb0aeff2..182d4ca782 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -1158,12 +1158,16 @@ pulls.cannot_auto_merge_helper=Merga manuellt för att lösa konlifterna. pulls.no_merge_desc=Pull-requesten kan inte mergas för alla alternativ för merging är inaktiverade för denna utvecklingskatalog. pulls.no_merge_helper=Aktivera mergealternativ i utvecklingskatalogsinställningarna, eller merga manuellt. + pulls.invalid_merge_option=Du kan inte använda detta mergealternativet för denna pull-request. ; %[2]s
%[3]s
pulls.open_unmerged_pull_exists=`Du kan inte återuppliva denna pull-request då det redan finns en identisk pull-request öppen (#%d).` pulls.update_branch_success=Uppdatering av branchen lyckades pulls.outdated_with_base_branch=Denna branch är föråldrad gentemot bas-branchen + + + milestones.new=Ny milstolpe milestones.open_tab=%d Öppna milestones.close_tab=%d Stängda diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index c7bdb9fc65..93ee7c75db 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -1408,6 +1408,7 @@ pulls.squash_merge_pull_request=Ezme işlemi oluştur pulls.merge_manually=Elle birleştirildi pulls.merge_commit_id=Birleştirme işlemesi kimliği pulls.require_signed_wont_sign=Dal imzalı işlemeler gerektiriyor, ancak bu birleştirme imzalanmayacak + pulls.invalid_merge_option=Bu değişiklik isteği için bu birleştirme seçeneğini kullanamazsınız. pulls.merge_conflict=Birleştirme Başarısız Oldu: Birleştirme sırasında bir çakışma oldu. İpucu: Farklı bir strateji deneyin pulls.merge_conflict_summary=Hata Mesajı @@ -1436,6 +1437,9 @@ pulls.merge_instruction_hint=`
komut satırı talimat pulls.merge_instruction_step1_desc=Proje deponuzdan yeni bir dala göz atın ve değişiklikleri test edin. pulls.merge_instruction_step2_desc=Gitea'daki değişiklikleri ve güncellemeleri birleştirin. + + + milestones.new=Yeni Kilometre Taşı milestones.open_tab=%d Açık milestones.close_tab=%d Kapalı diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 3e83932a2d..c58a5d461f 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -1457,6 +1457,7 @@ pulls.squash_merge_pull_request=Створити зварений (squash) ко pulls.merge_manually=Об’єднано вручну pulls.merge_commit_id=ID коміту злиття pulls.require_signed_wont_sign=Гілка вимагає підписаних комітів, але це злиття не буде підписано + pulls.invalid_merge_option=Цей параметр злиття не можна використовувати для цього Pull Request'а. pulls.merge_conflict=Злиття не вдалося: Був конфлікт при злиття. Підказка: спробуйте іншу стратегію pulls.merge_conflict_summary=Помилка @@ -1485,6 +1486,9 @@ pulls.merge_instruction_hint=`Також можна переглянути %[2]s pulls.merge_instruction_hint=`你也可以查看 命令行指令` pulls.merge_instruction_step1_desc=从你的仓库中签出一个新的分支并测试变更。 pulls.merge_instruction_step2_desc=合并变更并更新到 Gitea 上 -pulls.merge_on_status_success=合并请求计划在所有检查成功时合并。 -pulls.merge_on_status_success_already_scheduled=此拉取请求已安排在所有检查成功时合并。 -pulls.pr_has_pending_merge_on_success=%[1]s 安排此拉取请求在所有检查成功时自动合并 %[2]s。 -pulls.merge_pull_on_success_cancel=取消自动合并 -pulls.pull_request_not_scheduled=此拉取请求没有计划自动合并。 -pulls.pull_request_schedule_canceled=此拉取请求的自动合并已取消。 -pulls.pull_request_scheduled_auto_merge=`已安排此拉取请求在所有检查成功时自动合并 %[1]s` -pulls.pull_request_canceled_scheduled_auto_merge=`已取消当所有检查成功时自动合并此拉取请求 %[1]s` + +pulls.auto_merge_button_when_succeed=(当检查成功时) +pulls.auto_merge_when_succeed=在所有检查成功后自动合并 +pulls.auto_merge_newly_scheduled=合并请求计划在所有检查成功后合并。 +pulls.auto_merge_has_pending_schedule=%[1]s 安排此拉取请求在所有检查成功时自动合并 %[2]s。 + +pulls.auto_merge_cancel_schedule=取消自动合并 +pulls.auto_merge_not_scheduled=此拉取请求没有计划自动合并。 +pulls.auto_merge_canceled_schedule=此拉取请求的自动合并已取消。 + +pulls.auto_merge_newly_scheduled_comment=`已安排此拉取请求在所有检查成功后自动合并 %[1]s` +pulls.auto_merge_canceled_schedule_comment=`已取消当所有检查成功后自动合并此拉取请求 %[1]s` milestones.new=新的里程碑 milestones.open_tab=%d 开启中 diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index 97d3b8984c..48f04d0744 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -431,8 +431,12 @@ pulls.reopen_to_merge=請重新開啟合併請求來完成合併操作。 pulls.merged=已合併 pulls.can_auto_merge_desc=這個拉請求可以自動合併。 + ; %[2]s
%[3]s
+ + + milestones.new=新的里程碑 milestones.open_tab=%d 開啟中 milestones.close_tab=%d 已關閉 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 2cf099fda4..fc87cb315c 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -1495,6 +1495,9 @@ pulls.allow_edits_from_maintainers=允許維護者編輯 pulls.allow_edits_from_maintainers_desc=對基礎分支有寫入權限的使用者也可以推送到此分支 pulls.allow_edits_from_maintainers_err=更新失敗 pulls.compare_changes_desc=選擇合併的目標分支和來源分支。 +pulls.has_viewed_file=已檢視 +pulls.has_changed_since_last_review=您上次審核後有變動 +pulls.viewed_files_label=%[1]d / %[2]d 個檔案已檢視 pulls.compare_base=合併到 pulls.compare_compare=拉取自 pulls.switch_comparison_type=切換比較類型 @@ -1562,6 +1565,7 @@ pulls.squash_merge_pull_request=建立 Squash 提交 pulls.merge_manually=手動合併 pulls.merge_commit_id=合併提交 ID pulls.require_signed_wont_sign=該分支需要經簽署的提交,但此合併將不會被簽署。 + pulls.invalid_merge_option=您無法對此合併請求使用這個合併選項。 pulls.merge_conflict=合併失敗:合併時發生衝突。 提示:請嘗試不同的策略 pulls.merge_conflict_summary=錯誤訊息 @@ -1576,7 +1580,7 @@ pulls.push_rejected_summary=完整的拒絕訊息 pulls.push_rejected_no_message=合併失敗:此推送被拒絕但未提供其他資訊。
請檢查此儲存庫的 Git Hook。 pulls.open_unmerged_pull_exists=`您不能重新開放,因為目前有相同的合併請求 (#%d) 正在進行中。` pulls.status_checking=還在進行一些檢查 -pulls.status_checks_success=所有檢查都通過 +pulls.status_checks_success=已通過所有檢查 pulls.status_checks_warning=一些檢查回報了警告 pulls.status_checks_failure=一些檢查失敗了 pulls.status_checks_error=一些檢查回報了錯誤 @@ -1593,6 +1597,18 @@ pulls.merge_instruction_hint=`您也可以查看命 pulls.merge_instruction_step1_desc=在您的儲存庫中切換到新分支並測試變更。 pulls.merge_instruction_step2_desc=合併變更並更新到 Gitea。 +pulls.auto_merge_button_when_succeed=(當通過檢查後) +pulls.auto_merge_when_succeed=通過所有檢查後自動合併 +pulls.auto_merge_newly_scheduled=合併請求排定於通過所有檢查後合併。 +pulls.auto_merge_has_pending_schedule=%[1]s 排定了在通過所有檢查後自動合併此合併請求 %[2]s。 + +pulls.auto_merge_cancel_schedule=取消自動合併 +pulls.auto_merge_not_scheduled=此合併請求未排定自動合併。 +pulls.auto_merge_canceled_schedule=此合併請求的自動合併已被取消。 + +pulls.auto_merge_newly_scheduled_comment=`排定了在通過所有檢查後自動合併此合併請求 %[1]s` +pulls.auto_merge_canceled_schedule_comment=`取消了在通過所有檢查後自動合併此合併請求 %[1]s` + milestones.new=新增里程碑 milestones.open_tab=%d 個開放中 milestones.close_tab=%d 個已關閉 From 3708ca8e2849ca7e36e6bd15ec6935a2a2d81e55 Mon Sep 17 00:00:00 2001 From: yutotnh <57719497+yutotnh@users.noreply.github.com> Date: Mon, 13 Jun 2022 16:34:46 +0900 Subject: [PATCH 2/7] fix: some typos (#19956) --- cmd/cmd.go | 2 +- docs/content/doc/advanced/logging-documentation.en-us.md | 2 +- models/migrations/migrations.go | 4 ++-- modules/indexer/issues/bleve_test.go | 2 +- routers/api/v1/repo/milestone.go | 2 +- templates/swagger/v1_json.tmpl | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index 3846a86900..36d54bb19f 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -68,7 +68,7 @@ Ensure you are running in the correct environment or set the correct configurati If this is the intended configuration file complete the [database] section.`, setting.CustomConf) } if err := db.InitEngine(ctx); err != nil { - return fmt.Errorf("unable to initialise the database using the configuration in %q. Error: %v", setting.CustomConf, err) + return fmt.Errorf("unable to initialize the database using the configuration in %q. Error: %v", setting.CustomConf, err) } return nil } diff --git a/docs/content/doc/advanced/logging-documentation.en-us.md b/docs/content/doc/advanced/logging-documentation.en-us.md index bdde5bd8c4..b519641591 100644 --- a/docs/content/doc/advanced/logging-documentation.en-us.md +++ b/docs/content/doc/advanced/logging-documentation.en-us.md @@ -349,7 +349,7 @@ recommended that pausing only done for a very short period of time. It is possible to add and remove logging whilst Gitea is running using the `gitea manager logging add` and `remove` subcommands. This functionality can only adjust running log systems and cannot be used to start the access or router loggers if they -were not already initialised. If you wish to start these systems you are advised to adjust the app.ini and (gracefully) restart +were not already initialized. If you wish to start these systems you are advised to adjust the app.ini and (gracefully) restart the Gitea service. The main intention of these commands is to easily add a temporary logger to investigate problems on running systems where a restart diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 5a2297ac0d..1bed4e2bc0 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -419,7 +419,7 @@ func EnsureUpToDate(x *xorm.Engine) error { } if currentDB < 0 { - return fmt.Errorf("Database has not been initialised") + return fmt.Errorf("Database has not been initialized") } if minDBVersion > currentDB { @@ -953,7 +953,7 @@ func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin return nil } -// modifyColumn will modify column's type or other propertity. SQLITE is not supported +// modifyColumn will modify column's type or other property. SQLITE is not supported func modifyColumn(x *xorm.Engine, tableName string, col *schemas.Column) error { var indexes map[string]*schemas.Index var err error diff --git a/modules/indexer/issues/bleve_test.go b/modules/indexer/issues/bleve_test.go index 926c32e242..68a7831a3f 100644 --- a/modules/indexer/issues/bleve_test.go +++ b/modules/indexer/issues/bleve_test.go @@ -26,7 +26,7 @@ func TestBleveIndexAndSearch(t *testing.T) { defer indexer.Close() if _, err := indexer.Init(); err != nil { - assert.Fail(t, "Unable to initialise bleve indexer: %v", err) + assert.Fail(t, "Unable to initialize bleve indexer: %v", err) return } diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index ce6aa7f46f..0e8800510b 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -39,7 +39,7 @@ func ListMilestones(ctx *context.APIContext) { // required: true // - name: state // in: query - // description: Milestone state, Recognised values are open, closed and all. Defaults to "open" + // description: Milestone state, Recognized values are open, closed and all. Defaults to "open" // type: string // - name: name // in: query diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index c23bcb2e9a..ecc17b51c8 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -7223,7 +7223,7 @@ }, { "type": "string", - "description": "Milestone state, Recognised values are open, closed and all. Defaults to \"open\"", + "description": "Milestone state, Recognized values are open, closed and all. Defaults to \"open\"", "name": "state", "in": "query" }, From 1a9821f57a0293db3adc0eab8aff08ca5fa1026c Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 13 Jun 2022 17:37:59 +0800 Subject: [PATCH 3/7] Move issues related files into models/issues (#19931) * Move access and repo permission to models/perm/access * fix test * fix git test * Move functions sequence * Some improvements per @KN4CK3R and @delvh * Move issues related code to models/issues * Move some issues related sub package * Merge * Fix test * Fix test * Fix test * Fix test * Rename some files --- integrations/api_comment_test.go | 50 +-- integrations/api_issue_label_test.go | 22 +- integrations/api_issue_reaction_test.go | 6 +- integrations/api_issue_stopwatch_test.go | 12 +- integrations/api_issue_subscription_test.go | 14 +- integrations/api_issue_test.go | 17 +- integrations/api_issue_tracked_time_test.go | 18 +- integrations/api_pull_commits_test.go | 4 +- integrations/api_pull_review_test.go | 21 +- integrations/api_pull_test.go | 6 +- integrations/delete_user_test.go | 4 +- integrations/git_test.go | 26 +- integrations/issue_test.go | 39 +- integrations/pull_merge_test.go | 21 +- integrations/pull_update_test.go | 13 +- integrations/user_test.go | 6 +- models/action.go | 28 +- models/action_test.go | 43 ++ models/branch.go | 80 ---- models/consistency.go | 214 ---------- models/consistency_test.go | 149 ------- models/db/consistency.go | 27 ++ models/db/index.go | 27 +- models/db/list_options.go | 5 + models/error.go | 376 ----------------- models/git/branches_test.go | 6 +- models/git/main_test.go | 1 + models/issue_label_test.go | 394 ----------------- models/issue_stopwatch_test.go | 78 ---- models/issue_user_test.go | 61 --- .../assignees.go} | 2 +- .../assignees_test.go} | 27 +- .../{issue_comment.go => issues/comment.go} | 106 +++-- .../comment_list.go} | 29 +- .../comment_test.go} | 19 +- models/issues/content_history.go | 6 +- models/issues/content_history_test.go | 43 +- .../dependency.go} | 81 +++- .../dependency_test.go} | 27 +- models/{ => issues}/issue.go | 397 ++++++++---------- models/issues/issue_index.go | 32 ++ models/{ => issues}/issue_list.go | 28 +- models/{ => issues}/issue_list_test.go | 19 +- models/{ => issues}/issue_lock.go | 2 +- models/{ => issues}/issue_project.go | 2 +- models/{ => issues}/issue_test.go | 206 ++++----- models/{ => issues}/issue_user.go | 5 +- models/issues/issue_user_test.go | 62 +++ models/{ => issues}/issue_watch.go | 5 +- models/{ => issues}/issue_watch_test.go | 25 +- models/{ => issues}/issue_xref.go | 26 +- models/{ => issues}/issue_xref_test.go | 69 +-- models/{issue_label.go => issues/label.go} | 156 ++++++- models/issues/label_test.go | 395 +++++++++++++++++ models/issues/main_test.go | 24 +- models/issues/milestone.go | 33 +- models/issues/milestone_test.go | 151 +++++-- models/{ => issues}/pull.go | 155 ++++++- models/{ => issues}/pull_list.go | 2 +- models/{ => issues}/pull_test.go | 94 +++-- models/issues/reaction_test.go | 31 +- models/{ => issues}/review.go | 53 ++- models/{ => issues}/review_test.go | 111 ++--- .../stopwatch.go} | 4 +- models/issues/stopwatch_test.go | 79 ++++ .../tracked_time.go} | 4 +- .../tracked_time_test.go} | 35 +- models/main_test.go | 5 - models/migrate.go | 49 +-- models/migrate_test.go | 28 +- models/migrations/v111.go | 2 +- models/notification.go | 58 +-- models/notification_test.go | 5 +- models/org_team.go | 5 +- models/repo.go | 20 +- models/repo/repo.go | 47 +++ models/repo_activity.go | 21 +- models/repo_collaboration.go | 5 +- models/repo_transfer.go | 3 +- models/statistic.go | 4 +- models/user.go | 18 +- modules/context/repo.go | 7 +- modules/convert/convert.go | 4 +- modules/convert/issue.go | 21 +- modules/convert/issue_comment.go | 14 +- modules/convert/issue_test.go | 3 +- modules/convert/pull.go | 8 +- modules/convert/pull_review.go | 20 +- modules/convert/pull_test.go | 6 +- modules/doctor/dbconsistency.go | 29 +- modules/doctor/mergebase.go | 10 +- modules/eventsource/manager_run.go | 3 +- modules/indexer/issues/db.go | 4 +- modules/indexer/issues/indexer.go | 12 +- modules/notification/action/action.go | 21 +- modules/notification/base/notifier.go | 47 ++- modules/notification/base/null.go | 47 ++- modules/notification/indexer/indexer.go | 24 +- modules/notification/mail/mail.go | 43 +- modules/notification/notification.go | 47 ++- modules/notification/ui/ui.go | 29 +- modules/notification/webhook/webhook.go | 49 +-- modules/repository/init.go | 9 +- modules/templates/helper.go | 3 +- routers/api/v1/misc/nodeinfo.go | 6 +- routers/api/v1/notify/threads.go | 5 +- routers/api/v1/org/label.go | 30 +- routers/api/v1/repo/file.go | 6 +- routers/api/v1/repo/issue.go | 59 ++- routers/api/v1/repo/issue_comment.go | 66 +-- routers/api/v1/repo/issue_label.go | 32 +- routers/api/v1/repo/issue_reaction.go | 17 +- routers/api/v1/repo/issue_stopwatch.go | 20 +- routers/api/v1/repo/issue_subscription.go | 24 +- routers/api/v1/repo/issue_tracked_time.go | 48 +-- routers/api/v1/repo/label.go | 30 +- routers/api/v1/repo/patch.go | 3 +- routers/api/v1/repo/pull.go | 82 ++-- routers/api/v1/repo/pull_review.go | 64 +-- routers/private/hook_post_receive.go | 10 +- routers/private/hook_pre_receive.go | 5 +- routers/web/org/org_labels.go | 16 +- routers/web/repo/branch.go | 5 +- routers/web/repo/compare.go | 5 +- routers/web/repo/issue.go | 276 ++++++------ routers/web/repo/issue_content_history.go | 27 +- routers/web/repo/issue_dependency.go | 26 +- routers/web/repo/issue_label.go | 24 +- routers/web/repo/issue_label_test.go | 24 +- routers/web/repo/issue_lock.go | 6 +- routers/web/repo/issue_stopwatch.go | 14 +- routers/web/repo/issue_test.go | 158 +++---- routers/web/repo/issue_timetrack.go | 8 +- routers/web/repo/issue_watch.go | 4 +- routers/web/repo/projects.go | 14 +- routers/web/repo/pull.go | 65 +-- routers/web/repo/pull_review.go | 24 +- routers/web/user/home.go | 52 +-- routers/web/user/stop_watch.go | 6 +- services/agit/agit.go | 21 +- services/asymkey/sign.go | 6 +- services/automerge/automerge.go | 24 +- services/comments/comments.go | 36 +- services/forms/repo_form.go | 15 +- services/forms/user_form_hidden_comments.go | 58 +-- services/gitdiff/gitdiff.go | 14 +- services/gitdiff/gitdiff_test.go | 10 +- services/gitdiff/main_test.go | 1 + services/issue/assignee.go | 56 +-- services/issue/assignee_test.go | 6 +- services/issue/commit.go | 15 +- services/issue/commit_test.go | 57 +-- services/issue/content.go | 6 +- services/issue/issue.go | 108 ++++- services/issue/issue_test.go | 61 ++- services/issue/label.go | 32 +- services/issue/label_test.go | 16 +- services/issue/milestone.go | 13 +- services/issue/milestone_test.go | 9 +- services/issue/status.go | 14 +- services/mailer/mail.go | 29 +- services/mailer/mail_comment.go | 7 +- services/mailer/mail_issue.go | 17 +- services/mailer/mail_test.go | 17 +- services/migrations/gitea_uploader.go | 82 ++-- services/migrations/gitea_uploader_test.go | 6 +- services/pull/check.go | 31 +- services/pull/check_test.go | 12 +- services/pull/commit_status.go | 12 +- services/pull/edits.go | 6 +- services/pull/lfs.go | 6 +- services/pull/merge.go | 29 +- services/pull/patch.go | 21 +- services/pull/pull.go | 89 ++-- services/pull/pull_test.go | 6 +- services/pull/review.go | 60 +-- services/pull/temp_repo.go | 5 +- services/pull/update.go | 17 +- services/repository/repository.go | 3 +- services/repository/template.go | 7 +- 180 files changed, 3667 insertions(+), 3677 deletions(-) delete mode 100644 models/branch.go delete mode 100644 models/consistency_test.go create mode 100644 models/db/consistency.go delete mode 100644 models/issue_label_test.go delete mode 100644 models/issue_stopwatch_test.go delete mode 100644 models/issue_user_test.go rename models/{issue_assignees.go => issues/assignees.go} (99%) rename models/{issue_assignees_test.go => issues/assignees_test.go} (65%) rename models/{issue_comment.go => issues/comment.go} (92%) rename models/{issue_comment_list.go => issues/comment_list.go} (95%) rename models/{issue_comment_test.go => issues/comment_test.go} (71%) rename models/{issue_dependency.go => issues/dependency.go} (59%) rename models/{issue_dependency_test.go => issues/dependency_test.go} (51%) rename models/{ => issues}/issue.go (89%) create mode 100644 models/issues/issue_index.go rename models/{ => issues}/issue_list.go (96%) rename models/{ => issues}/issue_list_test.go (71%) rename models/{ => issues}/issue_lock.go (98%) rename models/{ => issues}/issue_project.go (99%) rename models/{ => issues}/issue_test.go (73%) rename models/{ => issues}/issue_user.go (94%) create mode 100644 models/issues/issue_user_test.go rename models/{ => issues}/issue_watch.go (96%) rename models/{ => issues}/issue_watch_test.go (53%) rename models/{ => issues}/issue_xref.go (93%) rename models/{ => issues}/issue_xref_test.go (61%) rename models/{issue_label.go => issues/label.go} (79%) create mode 100644 models/issues/label_test.go rename models/{ => issues}/pull.go (80%) rename models/{ => issues}/pull_list.go (99%) rename models/{ => issues}/pull_test.go (58%) rename models/{ => issues}/review.go (94%) rename models/{ => issues}/review_test.go (50%) rename models/{issue_stopwatch.go => issues/stopwatch.go} (99%) create mode 100644 models/issues/stopwatch_test.go rename models/{issue_tracked_time.go => issues/tracked_time.go} (99%) rename models/{issue_tracked_time_test.go => issues/tracked_time_test.go} (56%) diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go index dde51b2d53..7dcc0279fc 100644 --- a/integrations/api_comment_test.go +++ b/integrations/api_comment_test.go @@ -10,7 +10,7 @@ import ( "net/url" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -23,9 +23,9 @@ import ( func TestAPIListRepoComments(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{}, - unittest.Cond("type = ?", models.CommentTypeComment)).(*models.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -38,10 +38,10 @@ func TestAPIListRepoComments(t *testing.T) { DecodeJSON(t, resp, &apiComments) assert.Len(t, apiComments, 2) for _, apiComment := range apiComments { - c := &models.Comment{ID: apiComment.ID} + c := &issues_model.Comment{ID: apiComment.ID} unittest.AssertExistsAndLoadBean(t, c, - unittest.Cond("type = ?", models.CommentTypeComment)) - unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: c.IssueID, RepoID: repo.ID}) + unittest.Cond("type = ?", issues_model.CommentTypeComment)) + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: c.IssueID, RepoID: repo.ID}) } // test before and since filters @@ -69,9 +69,9 @@ func TestAPIListRepoComments(t *testing.T) { func TestAPIListIssueComments(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{}, - unittest.Cond("type = ?", models.CommentTypeComment)).(*models.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -82,8 +82,8 @@ func TestAPIListIssueComments(t *testing.T) { var comments []*api.Comment DecodeJSON(t, resp, &comments) - expectedCount := unittest.GetCount(t, &models.Comment{IssueID: issue.ID}, - unittest.Cond("type = ?", models.CommentTypeComment)) + expectedCount := unittest.GetCount(t, &issues_model.Comment{IssueID: issue.ID}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)) assert.EqualValues(t, expectedCount, len(comments)) } @@ -91,7 +91,7 @@ func TestAPICreateComment(t *testing.T) { defer prepareTestEnv(t)() const commentBody = "Comment body" - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -107,13 +107,13 @@ func TestAPICreateComment(t *testing.T) { var updatedComment api.Comment DecodeJSON(t, resp, &updatedComment) assert.EqualValues(t, commentBody, updatedComment.Body) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) } func TestAPIGetComment(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 2}).(*models.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}).(*issues_model.Comment) assert.NoError(t, comment.LoadIssue()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -141,9 +141,9 @@ func TestAPIEditComment(t *testing.T) { defer prepareTestEnv(t)() const newCommentBody = "This is the new comment body" - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{}, - unittest.Cond("type = ?", models.CommentTypeComment)).(*models.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -160,15 +160,15 @@ func TestAPIEditComment(t *testing.T) { DecodeJSON(t, resp, &updatedComment) assert.EqualValues(t, comment.ID, updatedComment.ID) assert.EqualValues(t, newCommentBody, updatedComment.Body) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) } func TestAPIDeleteComment(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{}, - unittest.Cond("type = ?", models.CommentTypeComment)).(*models.Comment) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: comment.IssueID}).(*models.Issue) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, + unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -178,14 +178,14 @@ func TestAPIDeleteComment(t *testing.T) { repoOwner.Name, repo.Name, comment.ID, token) session.MakeRequest(t, req, http.StatusNoContent) - unittest.AssertNotExistsBean(t, &models.Comment{ID: comment.ID}) + unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID}) } func TestAPIListIssueTimeline(t *testing.T) { defer prepareTestEnv(t)() // load comment - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) @@ -199,6 +199,6 @@ func TestAPIListIssueTimeline(t *testing.T) { // lists extracted directly from DB are the same var comments []*api.TimelineComment DecodeJSON(t, resp, &comments) - expectedCount := unittest.GetCount(t, &models.Comment{IssueID: issue.ID}) + expectedCount := unittest.GetCount(t, &issues_model.Comment{IssueID: issue.ID}) assert.EqualValues(t, expectedCount, len(comments)) } diff --git a/integrations/api_issue_label_test.go b/integrations/api_issue_label_test.go index 94b487377e..9b6333b2a2 100644 --- a/integrations/api_issue_label_test.go +++ b/integrations/api_issue_label_test.go @@ -10,7 +10,7 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -37,7 +37,7 @@ func TestAPIModifyLabels(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusCreated) apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) - dbLabel := unittest.AssertExistsAndLoadBean(t, &models.Label{ID: apiLabel.ID, RepoID: repo.ID}).(*models.Label) + dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, RepoID: repo.ID}).(*issues_model.Label) assert.EqualValues(t, dbLabel.Name, apiLabel.Name) assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) @@ -92,8 +92,8 @@ func TestAPIAddIssueLabels(t *testing.T) { assert.NoError(t, unittest.LoadFixtures()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{RepoID: repo.ID}).(*models.Issue) - _ = unittest.AssertExistsAndLoadBean(t, &models.Label{RepoID: repo.ID, ID: 2}).(*models.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}).(*issues_model.Issue) + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID, ID: 2}).(*issues_model.Label) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) session := loginUser(t, owner.Name) @@ -106,17 +106,17 @@ func TestAPIAddIssueLabels(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiLabels []*api.Label DecodeJSON(t, resp, &apiLabels) - assert.Len(t, apiLabels, unittest.GetCount(t, &models.IssueLabel{IssueID: issue.ID})) + assert.Len(t, apiLabels, unittest.GetCount(t, &issues_model.IssueLabel{IssueID: issue.ID})) - unittest.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: issue.ID, LabelID: 2}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: 2}) } func TestAPIReplaceIssueLabels(t *testing.T) { assert.NoError(t, unittest.LoadFixtures()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{RepoID: repo.ID}).(*models.Issue) - label := unittest.AssertExistsAndLoadBean(t, &models.Label{RepoID: repo.ID}).(*models.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}).(*issues_model.Issue) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID}).(*issues_model.Label) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) session := loginUser(t, owner.Name) @@ -133,8 +133,8 @@ func TestAPIReplaceIssueLabels(t *testing.T) { assert.EqualValues(t, label.ID, apiLabels[0].ID) } - unittest.AssertCount(t, &models.IssueLabel{IssueID: issue.ID}, 1) - unittest.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) + unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issue.ID}, 1) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) } func TestAPIModifyOrgLabels(t *testing.T) { @@ -156,7 +156,7 @@ func TestAPIModifyOrgLabels(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusCreated) apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) - dbLabel := unittest.AssertExistsAndLoadBean(t, &models.Label{ID: apiLabel.ID, OrgID: owner.ID}).(*models.Label) + dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, OrgID: owner.ID}).(*issues_model.Label) assert.EqualValues(t, dbLabel.Name, apiLabel.Name) assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) diff --git a/integrations/api_issue_reaction_test.go b/integrations/api_issue_reaction_test.go index 4a063c8c68..3834af2130 100644 --- a/integrations/api_issue_reaction_test.go +++ b/integrations/api_issue_reaction_test.go @@ -10,8 +10,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/convert" @@ -23,7 +23,7 @@ import ( func TestAPIIssuesReactions(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) @@ -80,7 +80,7 @@ func TestAPIIssuesReactions(t *testing.T) { func TestAPICommentReactions(t *testing.T) { defer prepareTestEnv(t)() - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 2}).(*models.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}).(*issues_model.Comment) _ = comment.LoadIssue() issue := comment.Issue _ = issue.LoadRepo(db.DefaultContext) diff --git a/integrations/api_issue_stopwatch_test.go b/integrations/api_issue_stopwatch_test.go index 90098b9236..0d06447181 100644 --- a/integrations/api_issue_stopwatch_test.go +++ b/integrations/api_issue_stopwatch_test.go @@ -8,8 +8,8 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -30,8 +30,8 @@ func TestAPIListStopWatches(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches) - stopwatch := unittest.AssertExistsAndLoadBean(t, &models.Stopwatch{UserID: owner.ID}).(*models.Stopwatch) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: stopwatch.IssueID}).(*models.Issue) + stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}).(*issues_model.Stopwatch) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}).(*issues_model.Issue) if assert.Len(t, apiWatches, 1) { assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex) @@ -45,7 +45,7 @@ func TestAPIListStopWatches(t *testing.T) { func TestAPIStopStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) @@ -61,7 +61,7 @@ func TestAPIStopStopWatches(t *testing.T) { func TestAPICancelStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) @@ -77,7 +77,7 @@ func TestAPICancelStopWatches(t *testing.T) { func TestAPIStartStopWatches(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) diff --git a/integrations/api_issue_subscription_test.go b/integrations/api_issue_subscription_test.go index e0bb388365..2c6cddcab9 100644 --- a/integrations/api_issue_subscription_test.go +++ b/integrations/api_issue_subscription_test.go @@ -9,7 +9,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -21,18 +21,18 @@ import ( func TestAPIIssueSubscriptions(t *testing.T) { defer prepareTestEnv(t)() - issue1 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1}).(*models.Issue) - issue2 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) - issue3 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) - issue4 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 4}).(*models.Issue) - issue5 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 8}).(*models.Issue) + issue1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) + issue3 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + issue4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue) + issue5 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 8}).(*issues_model.Issue) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue1.PosterID}).(*user_model.User) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session) - testSubscription := func(issue *models.Issue, isWatching bool) { + testSubscription := func(issue *issues_model.Issue, isWatching bool) { issueRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/check?token=%s", issueRepo.OwnerName, issueRepo.Name, issue.Index, token) diff --git a/integrations/api_issue_test.go b/integrations/api_issue_test.go index cc7d8d6bd5..5c802e8d20 100644 --- a/integrations/api_issue_test.go +++ b/integrations/api_issue_test.go @@ -11,7 +11,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -34,9 +35,9 @@ func TestAPIListIssues(t *testing.T) { resp := session.MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) var apiIssues []*api.Issue DecodeJSON(t, resp, &apiIssues) - assert.Len(t, apiIssues, unittest.GetCount(t, &models.Issue{RepoID: repo.ID})) + assert.Len(t, apiIssues, unittest.GetCount(t, &issues_model.Issue{RepoID: repo.ID})) for _, apiIssue := range apiIssues { - unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: apiIssue.ID, RepoID: repo.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: apiIssue.ID, RepoID: repo.ID}) } // test milestone filter @@ -91,7 +92,7 @@ func TestAPICreateIssue(t *testing.T) { assert.Equal(t, body, apiIssue.Body) assert.Equal(t, title, apiIssue.Title) - unittest.AssertExistsAndLoadBean(t, &models.Issue{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ RepoID: repoBefore.ID, AssigneeID: owner.ID, Content: body, @@ -106,10 +107,10 @@ func TestAPICreateIssue(t *testing.T) { func TestAPIEditIssue(t *testing.T) { defer prepareTestEnv(t)() - issueBefore := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User) - assert.NoError(t, issueBefore.LoadAttributes()) + assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix)) assert.Equal(t, api.StateOpen, issueBefore.State()) @@ -137,12 +138,12 @@ func TestAPIEditIssue(t *testing.T) { var apiIssue api.Issue DecodeJSON(t, resp, &apiIssue) - issueAfter := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue) + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) // check deleted user assert.Equal(t, int64(500), issueAfter.PosterID) - assert.NoError(t, issueAfter.LoadAttributes()) + assert.NoError(t, issueAfter.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(-1), issueAfter.PosterID) assert.Equal(t, int64(-1), issueBefore.PosterID) assert.Equal(t, int64(-1), apiIssue.Poster.ID) diff --git a/integrations/api_issue_tracked_time_test.go b/integrations/api_issue_tracked_time_test.go index 7c69d4eb9e..a6846cb786 100644 --- a/integrations/api_issue_tracked_time_test.go +++ b/integrations/api_issue_tracked_time_test.go @@ -10,8 +10,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" @@ -23,7 +23,7 @@ func TestAPIGetTrackedTimes(t *testing.T) { defer prepareTestEnv(t)() user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - issue2 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) session := loginUser(t, user2.Name) @@ -33,7 +33,7 @@ func TestAPIGetTrackedTimes(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiTimes api.TrackedTimeList DecodeJSON(t, resp, &apiTimes) - expect, err := models.GetTrackedTimes(db.DefaultContext, &models.FindTrackedTimesOptions{IssueID: issue2.ID}) + expect, err := issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: issue2.ID}) assert.NoError(t, err) assert.Len(t, apiTimes, 3) @@ -64,8 +64,8 @@ func TestAPIGetTrackedTimes(t *testing.T) { func TestAPIDeleteTrackedTime(t *testing.T) { defer prepareTestEnv(t)() - time6 := unittest.AssertExistsAndLoadBean(t, &models.TrackedTime{ID: 6}).(*models.TrackedTime) - issue2 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + time6 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 6}).(*issues_model.TrackedTime) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) @@ -76,14 +76,14 @@ func TestAPIDeleteTrackedTime(t *testing.T) { req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time6.ID, token) session.MakeRequest(t, req, http.StatusForbidden) - time3 := unittest.AssertExistsAndLoadBean(t, &models.TrackedTime{ID: 3}).(*models.TrackedTime) + time3 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 3}).(*issues_model.TrackedTime) req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time3.ID, token) session.MakeRequest(t, req, http.StatusNoContent) // Delete non existing time session.MakeRequest(t, req, http.StatusNotFound) // Reset time of user 2 on issue 2 - trackedSeconds, err := models.GetTrackedSeconds(db.DefaultContext, models.FindTrackedTimesOptions{IssueID: 2, UserID: 2}) + trackedSeconds, err := issues_model.GetTrackedSeconds(db.DefaultContext, issues_model.FindTrackedTimesOptions{IssueID: 2, UserID: 2}) assert.NoError(t, err) assert.Equal(t, int64(3661), trackedSeconds) @@ -91,7 +91,7 @@ func TestAPIDeleteTrackedTime(t *testing.T) { session.MakeRequest(t, req, http.StatusNoContent) session.MakeRequest(t, req, http.StatusNotFound) - trackedSeconds, err = models.GetTrackedSeconds(db.DefaultContext, models.FindTrackedTimesOptions{IssueID: 2, UserID: 2}) + trackedSeconds, err = issues_model.GetTrackedSeconds(db.DefaultContext, issues_model.FindTrackedTimesOptions{IssueID: 2, UserID: 2}) assert.NoError(t, err) assert.Equal(t, int64(0), trackedSeconds) } @@ -99,7 +99,7 @@ func TestAPIDeleteTrackedTime(t *testing.T) { func TestAPIAddTrackedTimes(t *testing.T) { defer prepareTestEnv(t)() - issue2 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) assert.NoError(t, issue2.LoadRepo(db.DefaultContext)) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) diff --git a/integrations/api_pull_commits_test.go b/integrations/api_pull_commits_test.go index 5e057b05a1..3b75fbcb4a 100644 --- a/integrations/api_pull_commits_test.go +++ b/integrations/api_pull_commits_test.go @@ -8,7 +8,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" api "code.gitea.io/gitea/modules/structs" @@ -18,7 +18,7 @@ import ( func TestAPIPullCommits(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) assert.NoError(t, pullIssue.LoadIssue()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.HeadRepoID}).(*repo_model.Repository) diff --git a/integrations/api_pull_review_test.go b/integrations/api_pull_review_test.go index 3f80dbdf9b..b601ca1d41 100644 --- a/integrations/api_pull_review_test.go +++ b/integrations/api_pull_review_test.go @@ -9,7 +9,8 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/json" @@ -20,8 +21,8 @@ import ( func TestAPIPullReview(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) - assert.NoError(t, pullIssue.LoadAttributes()) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext)) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}).(*repo_model.Repository) // test ListPullReviews @@ -64,7 +65,7 @@ func TestAPIPullReview(t *testing.T) { assert.EqualValues(t, *reviews[5], review) // test GetPullReviewComments - comment := unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 7}).(*models.Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7}).(*issues_model.Comment) req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d/comments?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, 10, token) resp = session.MakeRequest(t, req, http.StatusOK) var reviewComments []*api.PullReviewComment @@ -199,8 +200,8 @@ func TestAPIPullReview(t *testing.T) { // test get review requests // to make it simple, use same api with get review - pullIssue12 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 12}).(*models.Issue) - assert.NoError(t, pullIssue12.LoadAttributes()) + pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}).(*issues_model.Issue) + assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext)) repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}).(*repo_model.Repository) req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token) @@ -223,8 +224,8 @@ func TestAPIPullReview(t *testing.T) { func TestAPIPullReviewRequest(t *testing.T) { defer prepareTestEnv(t)() - pullIssue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 3}).(*models.Issue) - assert.NoError(t, pullIssue.LoadAttributes()) + pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) + assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext)) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}).(*repo_model.Repository) // Test add Review Request @@ -268,8 +269,8 @@ func TestAPIPullReviewRequest(t *testing.T) { session.MakeRequest(t, req, http.StatusNoContent) // Test team review request - pullIssue12 := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 12}).(*models.Issue) - assert.NoError(t, pullIssue12.LoadAttributes()) + pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}).(*issues_model.Issue) + assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext)) repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}).(*repo_model.Repository) // Test add Team Review Request diff --git a/integrations/api_pull_test.go b/integrations/api_pull_test.go index a1c2a4c3e6..0c63ec2c00 100644 --- a/integrations/api_pull_test.go +++ b/integrations/api_pull_test.go @@ -9,7 +9,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -33,7 +33,7 @@ func TestAPIViewPulls(t *testing.T) { var pulls []*api.PullRequest DecodeJSON(t, resp, &pulls) - expectedLen := unittest.GetCount(t, &models.Issue{RepoID: repo.ID}, unittest.Cond("is_pull = ?", true)) + expectedLen := unittest.GetCount(t, &issues_model.Issue{RepoID: repo.ID}, unittest.Cond("is_pull = ?", true)) assert.Len(t, pulls, expectedLen) } @@ -42,7 +42,7 @@ func TestAPIMergePullWIP(t *testing.T) { defer prepareTestEnv(t)() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{Status: models.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false)).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{Status: issues_model.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false)).(*issues_model.PullRequest) pr.LoadIssue() issue_service.ChangeTitle(pr.Issue, owner, setting.Repository.PullRequest.WorkInProgressPrefixes[0]+" "+pr.Issue.Title) diff --git a/integrations/delete_user_test.go b/integrations/delete_user_test.go index cf376f6fcc..8b86780224 100644 --- a/integrations/delete_user_test.go +++ b/integrations/delete_user_test.go @@ -9,7 +9,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -24,7 +24,7 @@ func assertUserDeleted(t *testing.T, userID int64) { unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerID: userID}) unittest.AssertNotExistsBean(t, &access_model.Access{UserID: userID}) unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: userID}) - unittest.AssertNotExistsBean(t, &models.IssueUser{UID: userID}) + unittest.AssertNotExistsBean(t, &issues_model.IssueUser{UID: userID}) unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID}) unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID}) } diff --git a/integrations/git_test.go b/integrations/git_test.go index 63afc7913b..a3ba7b7aa9 100644 --- a/integrations/git_test.go +++ b/integrations/git_test.go @@ -17,8 +17,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -715,7 +715,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB defer gitRepo.Close() var ( - pr1, pr2 *models.PullRequest + pr1, pr2 *issues_model.PullRequest commit string ) repo, err := repo_model.GetRepositoryByOwnerAndName(ctx.Username, ctx.Reponame) @@ -723,7 +723,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB return } - pullNum := unittest.GetCount(t, &models.PullRequest{}) + pullNum := unittest.GetCount(t, &issues_model.PullRequest{}) t.Run("CreateHeadBranch", doGitCreateBranch(dstPath, headBranch)) @@ -759,11 +759,11 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - unittest.AssertCount(t, &models.PullRequest{}, pullNum+1) - pr1 = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ + unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+1) + pr1 = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo.ID, - Flow: models.PullRequestFlowAGit, - }).(*models.PullRequest) + Flow: issues_model.PullRequestFlowAGit, + }).(*issues_model.PullRequest) if !assert.NotEmpty(t, pr1) { return } @@ -780,12 +780,12 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - unittest.AssertCount(t, &models.PullRequest{}, pullNum+2) - pr2 = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ + unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) + pr2 = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo.ID, Index: pr1.Index + 1, - Flow: models.PullRequestFlowAGit, - }).(*models.PullRequest) + Flow: issues_model.PullRequestFlowAGit, + }).(*issues_model.PullRequest) if !assert.NotEmpty(t, pr2) { return } @@ -833,7 +833,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - unittest.AssertCount(t, &models.PullRequest{}, pullNum+2) + unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) prMsg, err := doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index)(t) if !assert.NoError(t, err) { return @@ -845,7 +845,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - unittest.AssertCount(t, &models.PullRequest{}, pullNum+2) + unittest.AssertCount(t, &issues_model.PullRequest{}, pullNum+2) prMsg, err = doAPIGetPullRequest(*ctx, ctx.Username, ctx.Reponame, pr2.Index)(t) if !assert.NoError(t, err) { return diff --git a/integrations/issue_test.go b/integrations/issue_test.go index 8e04b99d5e..7d30d657f5 100644 --- a/integrations/issue_test.go +++ b/integrations/issue_test.go @@ -14,7 +14,8 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -34,16 +35,16 @@ func getIssuesSelection(t testing.TB, htmlDoc *HTMLDoc) *goquery.Selection { return issueList.Find("li").Find(".title") } -func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *models.Issue { +func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *issues_model.Issue { href, exists := issueSelection.Attr("href") assert.True(t, exists) indexStr := href[strings.LastIndexByte(href, '/')+1:] index, err := strconv.Atoi(indexStr) assert.NoError(t, err, "Invalid issue href: %s", href) - return unittest.AssertExistsAndLoadBean(t, &models.Issue{RepoID: repoID, Index: int64(index)}).(*models.Issue) + return unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repoID, Index: int64(index)}).(*issues_model.Issue) } -func assertMatch(t testing.TB, issue *models.Issue, keyword string) { +func assertMatch(t testing.TB, issue *issues_model.Issue, keyword string) { matches := strings.Contains(strings.ToLower(issue.Title), keyword) || strings.Contains(strings.ToLower(issue.Content), keyword) for _, comment := range issue.Comments { @@ -75,7 +76,7 @@ func TestViewIssuesSortByType(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) issuesSelection := getIssuesSelection(t, htmlDoc) expectedNumIssues := unittest.GetCount(t, - &models.Issue{RepoID: repo.ID, PosterID: user.ID}, + &issues_model.Issue{RepoID: repo.ID, PosterID: user.ID}, unittest.Cond("is_closed=?", false), unittest.Cond("is_pull=?", false), ) @@ -94,10 +95,10 @@ func TestViewIssuesKeyword(t *testing.T) { defer prepareTestEnv(t)() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ RepoID: repo.ID, Index: 1, - }).(*models.Issue) + }).(*issues_model.Issue) issues.UpdateIssueIndexer(issue) time.Sleep(time.Second * 1) const keyword = "first" @@ -238,7 +239,7 @@ func TestIssueCrossReference(t *testing.T) { // Ref from issue title issueRefURL, issueRef := testIssueWithBean(t, "user2", 1, fmt.Sprintf("Title ref #%d", issueBase.Index), "Description") - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -249,7 +250,7 @@ func TestIssueCrossReference(t *testing.T) { // Edit title, neuter ref testIssueChangeInfo(t, "user2", issueRefURL, "title", "Title no ref") - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -260,7 +261,7 @@ func TestIssueCrossReference(t *testing.T) { // Ref from issue content issueRefURL, issueRef = testIssueWithBean(t, "user2", 1, "TitleXRef", fmt.Sprintf("Description ref #%d", issueBase.Index)) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -271,7 +272,7 @@ func TestIssueCrossReference(t *testing.T) { // Edit content, neuter ref testIssueChangeInfo(t, "user2", issueRefURL, "content", "Description no ref") - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -283,7 +284,7 @@ func TestIssueCrossReference(t *testing.T) { // Ref from a comment session := loginUser(t, "user2") commentID := testIssueAddComment(t, session, issueRefURL, fmt.Sprintf("Adding ref from comment #%d", issueBase.Index), "") - comment := &models.Comment{ + comment := &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 1, RefIssueID: issueRef.ID, @@ -295,7 +296,7 @@ func TestIssueCrossReference(t *testing.T) { // Ref from a different repository _, issueRef = testIssueWithBean(t, "user12", 10, "TitleXRef", fmt.Sprintf("Description ref user2/repo1#%d", issueBase.Index)) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issueBase.ID, RefRepoID: 10, RefIssueID: issueRef.ID, @@ -305,13 +306,13 @@ func TestIssueCrossReference(t *testing.T) { }) } -func testIssueWithBean(t *testing.T, user string, repoID int64, title, content string) (string, *models.Issue) { +func testIssueWithBean(t *testing.T, user string, repoID int64, title, content string) (string, *issues_model.Issue) { session := loginUser(t, user) issueURL := testNewIssue(t, session, user, fmt.Sprintf("repo%d", repoID), title, content) indexStr := issueURL[strings.LastIndexByte(issueURL, '/')+1:] index, err := strconv.Atoi(indexStr) assert.NoError(t, err, "Invalid issue href: %s", issueURL) - issue := &models.Issue{RepoID: repoID, Index: int64(index)} + issue := &issues_model.Issue{RepoID: repoID, Index: int64(index)} unittest.AssertExistsAndLoadBean(t, issue) return issueURL, issue } @@ -511,10 +512,10 @@ func TestSearchIssuesWithLabels(t *testing.T) { func TestGetIssueInfo(t *testing.T) { defer prepareTestEnv(t)() - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - assert.NoError(t, issue.LoadAttributes()) + assert.NoError(t, issue.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issue.DeadlineUnix)) assert.Equal(t, api.StateOpen, issue.State()) @@ -532,10 +533,10 @@ func TestGetIssueInfo(t *testing.T) { func TestUpdateIssueDeadline(t *testing.T) { defer prepareTestEnv(t)() - issueBefore := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 10}).(*models.Issue) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue) repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User) - assert.NoError(t, issueBefore.LoadAttributes()) + assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext)) assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix)) assert.Equal(t, api.StateOpen, issueBefore.State()) diff --git a/integrations/pull_merge_test.go b/integrations/pull_merge_test.go index 6c5b67caa6..de519094d4 100644 --- a/integrations/pull_merge_test.go +++ b/integrations/pull_merge_test.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -233,12 +234,12 @@ func TestCantMergeConflict(t *testing.T) { Name: "repo1", }).(*repo_model.Repository) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo1.ID, BaseRepoID: repo1.ID, HeadBranch: "conflict", BaseBranch: "base", - }).(*models.PullRequest) + }).(*issues_model.PullRequest) gitRepo, err := git.OpenRepository(git.DefaultContext, repo_model.RepoPath(user1.Name, repo1.Name)) assert.NoError(t, err) @@ -335,12 +336,12 @@ func TestCantMergeUnrelated(t *testing.T) { // Now this PR could be marked conflict - or at least a race may occur - so drop down to pure code at this point... gitRepo, err := git.OpenRepository(git.DefaultContext, path) assert.NoError(t, err) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ HeadRepoID: repo1.ID, BaseRepoID: repo1.ID, HeadBranch: "unrelated", BaseBranch: "base", - }).(*models.PullRequest) + }).(*issues_model.PullRequest) err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "UNRELATED") assert.Error(t, err, "Merge should return an error due to unrelated") @@ -387,7 +388,7 @@ func TestConflictChecking(t *testing.T) { assert.NoError(t, err) // create Pull to merge the important-secrets branch into main branch. - pullIssue := &models.Issue{ + pullIssue := &issues_model.Issue{ RepoID: baseRepo.ID, Title: "PR with conflict!", PosterID: user.ID, @@ -395,26 +396,26 @@ func TestConflictChecking(t *testing.T) { IsPull: true, } - pullRequest := &models.PullRequest{ + pullRequest := &issues_model.PullRequest{ HeadRepoID: baseRepo.ID, BaseRepoID: baseRepo.ID, HeadBranch: "important-secrets", BaseBranch: "main", HeadRepo: baseRepo, BaseRepo: baseRepo, - Type: models.PullRequestGitea, + Type: issues_model.PullRequestGitea, } err = pull.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) assert.NoError(t, err) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{Title: "PR with conflict!"}).(*models.Issue) - conflictingPR, err := models.GetPullRequestByIssueID(db.DefaultContext, issue.ID) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "PR with conflict!"}).(*issues_model.Issue) + conflictingPR, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID) assert.NoError(t, err) // Ensure conflictedFiles is populated. assert.Equal(t, 1, len(conflictingPR.ConflictedFiles)) // Check if status is correct. - assert.Equal(t, models.PullRequestStatusConflict, conflictingPR.Status) + assert.Equal(t, issues_model.PullRequestStatusConflict, conflictingPR.Status) // Ensure that mergeable returns false assert.False(t, conflictingPR.Mergeable()) }) diff --git a/integrations/pull_update_test.go b/integrations/pull_update_test.go index f11eacf144..47ada91e1a 100644 --- a/integrations/pull_update_test.go +++ b/integrations/pull_update_test.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -78,7 +79,7 @@ func TestAPIPullUpdateByRebase(t *testing.T) { }) } -func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.PullRequest { +func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest { baseRepo, err := repo_service.CreateRepository(actor, actor, models.CreateRepoOptions{ Name: "repo-pr-update", Description: "repo-tmp-pr-update description", @@ -146,27 +147,27 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.Pul assert.NoError(t, err) // create Pull - pullIssue := &models.Issue{ + pullIssue := &issues_model.Issue{ RepoID: baseRepo.ID, Title: "Test Pull -to-update-", PosterID: actor.ID, Poster: actor, IsPull: true, } - pullRequest := &models.PullRequest{ + pullRequest := &issues_model.PullRequest{ HeadRepoID: headRepo.ID, BaseRepoID: baseRepo.ID, HeadBranch: "newBranch", BaseBranch: "master", HeadRepo: headRepo, BaseRepo: baseRepo, - Type: models.PullRequestGitea, + Type: issues_model.PullRequestGitea, } err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) assert.NoError(t, err) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{Title: "Test Pull -to-update-"}).(*models.Issue) - pr, err := models.GetPullRequestByIssueID(db.DefaultContext, issue.ID) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Test Pull -to-update-"}).(*issues_model.Issue) + pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID) assert.NoError(t, err) return pr diff --git a/integrations/user_test.go b/integrations/user_test.go index d0523d8b3a..6a3d30472d 100644 --- a/integrations/user_test.go +++ b/integrations/user_test.go @@ -8,7 +8,7 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -237,8 +237,8 @@ func TestListStopWatches(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches) - stopwatch := unittest.AssertExistsAndLoadBean(t, &models.Stopwatch{UserID: owner.ID}).(*models.Stopwatch) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: stopwatch.IssueID}).(*models.Issue) + stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}).(*issues_model.Stopwatch) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}).(*issues_model.Issue) if assert.Len(t, apiWatches, 1) { assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex) diff --git a/models/action.go b/models/action.go index 882bc59d8f..951328070d 100644 --- a/models/action.go +++ b/models/action.go @@ -15,6 +15,7 @@ import ( "time" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -76,7 +77,7 @@ type Action struct { RepoID int64 `xorm:"INDEX"` Repo *repo_model.Repository `xorm:"-"` CommentID int64 `xorm:"INDEX"` - Comment *Comment `xorm:"-"` + Comment *issues_model.Comment `xorm:"-"` IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"` RefName string IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"` @@ -223,7 +224,7 @@ func (a *Action) getCommentLink(ctx context.Context) string { return "#" } if a.Comment == nil && a.CommentID != 0 { - a.Comment, _ = GetCommentByID(ctx, a.CommentID) + a.Comment, _ = issues_model.GetCommentByID(ctx, a.CommentID) } if a.Comment != nil { return a.Comment.HTMLURL() @@ -238,7 +239,7 @@ func (a *Action) getCommentLink(ctx context.Context) string { return "#" } - issue, err := getIssueByID(ctx, issueID) + issue, err := issues_model.GetIssueByID(ctx, issueID) if err != nil { return "#" } @@ -295,7 +296,7 @@ func (a *Action) GetIssueInfos() []string { // with the action. func (a *Action) GetIssueTitle() string { index, _ := strconv.ParseInt(a.GetIssueInfos()[0], 10, 64) - issue, err := GetIssueByIndex(a.RepoID, index) + issue, err := issues_model.GetIssueByIndex(a.RepoID, index) if err != nil { log.Error("GetIssueByIndex: %v", err) return "500 when get issue" @@ -307,7 +308,7 @@ func (a *Action) GetIssueTitle() string { // this action. func (a *Action) GetIssueContent() string { index, _ := strconv.ParseInt(a.GetIssueInfos()[0], 10, 64) - issue, err := GetIssueByIndex(a.RepoID, index) + issue, err := issues_model.GetIssueByIndex(a.RepoID, index) if err != nil { log.Error("GetIssueByIndex: %v", err) return "500 when get issue" @@ -572,3 +573,20 @@ func NotifyWatchersActions(acts []*Action) error { } return committer.Commit() } + +// DeleteIssueActions delete all actions related with issueID +func DeleteIssueActions(ctx context.Context, repoID, issueID int64) error { + // delete actions assigned to this issue + subQuery := builder.Select("`id`"). + From("`comment`"). + Where(builder.Eq{"`issue_id`": issueID}) + if _, err := db.GetEngine(ctx).In("comment_id", subQuery).Delete(&Action{}); err != nil { + return err + } + + _, err := db.GetEngine(ctx).Table("action").Where("repo_id = ?", repoID). + In("op_type", ActionCreateIssue, ActionCreatePullRequest). + Where("content LIKE ?", strconv.FormatInt(issueID, 10)+"|%"). + Delete(&Action{}) + return err +} diff --git a/models/action_test.go b/models/action_test.go index fb8a6c2686..2d46bd3e80 100644 --- a/models/action_test.go +++ b/models/action_test.go @@ -228,3 +228,46 @@ func TestGetFeedsCorrupted(t *testing.T) { assert.NoError(t, err) assert.Len(t, actions, 0) } + +func TestConsistencyUpdateAction(t *testing.T) { + if !setting.Database.UseSQLite3 { + t.Skip("Test is only for SQLite database.") + } + assert.NoError(t, unittest.PrepareTestDatabase()) + id := 8 + unittest.AssertExistsAndLoadBean(t, &Action{ + ID: int64(id), + }) + _, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id) + assert.NoError(t, err) + actions := make([]*Action, 0, 1) + // + // XORM returns an error when created_unix is a string + // + err = db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions) + if assert.Error(t, err) { + assert.Contains(t, err.Error(), "type string to a int64: invalid syntax") + } + // + // Get rid of incorrectly set created_unix + // + count, err := CountActionCreatedUnixString() + assert.NoError(t, err) + assert.EqualValues(t, 1, count) + count, err = FixActionCreatedUnixString() + assert.NoError(t, err) + assert.EqualValues(t, 1, count) + + count, err = CountActionCreatedUnixString() + assert.NoError(t, err) + assert.EqualValues(t, 0, count) + count, err = FixActionCreatedUnixString() + assert.NoError(t, err) + assert.EqualValues(t, 0, count) + + // + // XORM must be happy now + // + assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) + unittest.CheckConsistencyFor(t, &Action{}) +} diff --git a/models/branch.go b/models/branch.go deleted file mode 100644 index 3d6e7d82e2..0000000000 --- a/models/branch.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "context" - - "code.gitea.io/gitea/models/db" - git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/modules/log" -) - -// HasEnoughApprovals returns true if pr has enough granted approvals. -func HasEnoughApprovals(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { - if protectBranch.RequiredApprovals == 0 { - return true - } - return GetGrantedApprovalsCount(ctx, protectBranch, pr) >= protectBranch.RequiredApprovals -} - -// GetGrantedApprovalsCount returns the number of granted approvals for pr. A granted approval must be authored by a user in an approval whitelist. -func GetGrantedApprovalsCount(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) int64 { - sess := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). - And("type = ?", ReviewTypeApprove). - And("official = ?", true). - And("dismissed = ?", false) - if protectBranch.DismissStaleApprovals { - sess = sess.And("stale = ?", false) - } - approvals, err := sess.Count(new(Review)) - if err != nil { - log.Error("GetGrantedApprovalsCount: %v", err) - return 0 - } - - return approvals -} - -// MergeBlockedByRejectedReview returns true if merge is blocked by rejected reviews -func MergeBlockedByRejectedReview(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { - if !protectBranch.BlockOnRejectedReviews { - return false - } - rejectExist, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). - And("type = ?", ReviewTypeReject). - And("official = ?", true). - And("dismissed = ?", false). - Exist(new(Review)) - if err != nil { - log.Error("MergeBlockedByRejectedReview: %v", err) - return true - } - - return rejectExist -} - -// MergeBlockedByOfficialReviewRequests block merge because of some review request to official reviewer -// of from official review -func MergeBlockedByOfficialReviewRequests(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { - if !protectBranch.BlockOnOfficialReviewRequests { - return false - } - has, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). - And("type = ?", ReviewTypeRequest). - And("official = ?", true). - Exist(new(Review)) - if err != nil { - log.Error("MergeBlockedByOfficialReviewRequests: %v", err) - return true - } - - return has -} - -// MergeBlockedByOutdatedBranch returns true if merge is blocked by an outdated head branch -func MergeBlockedByOutdatedBranch(protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { - return protectBranch.BlockOnOutdatedBranch && pr.CommitsBehind > 0 -} diff --git a/models/consistency.go b/models/consistency.go index e817b69176..18ed9195fc 100644 --- a/models/consistency.go +++ b/models/consistency.go @@ -5,7 +5,6 @@ package models import ( - admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -14,151 +13,6 @@ import ( "xorm.io/builder" ) -// CountOrphanedLabels return count of labels witch are broken and not accessible via ui anymore -func CountOrphanedLabels() (int64, error) { - noref, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Count("label.id") - if err != nil { - return 0, err - } - - norepo, err := db.GetEngine(db.DefaultContext).Table("label"). - Where(builder.And( - builder.Gt{"repo_id": 0}, - builder.NotIn("repo_id", builder.Select("id").From("repository")), - )). - Count() - if err != nil { - return 0, err - } - - noorg, err := db.GetEngine(db.DefaultContext).Table("label"). - Where(builder.And( - builder.Gt{"org_id": 0}, - builder.NotIn("org_id", builder.Select("id").From("user")), - )). - Count() - if err != nil { - return 0, err - } - - return noref + norepo + noorg, nil -} - -// DeleteOrphanedLabels delete labels witch are broken and not accessible via ui anymore -func DeleteOrphanedLabels() error { - // delete labels with no reference - if _, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Delete(new(Label)); err != nil { - return err - } - - // delete labels with none existing repos - if _, err := db.GetEngine(db.DefaultContext). - Where(builder.And( - builder.Gt{"repo_id": 0}, - builder.NotIn("repo_id", builder.Select("id").From("repository")), - )). - Delete(Label{}); err != nil { - return err - } - - // delete labels with none existing orgs - if _, err := db.GetEngine(db.DefaultContext). - Where(builder.And( - builder.Gt{"org_id": 0}, - builder.NotIn("org_id", builder.Select("id").From("user")), - )). - Delete(Label{}); err != nil { - return err - } - - return nil -} - -// CountOrphanedIssueLabels return count of IssueLabels witch have no label behind anymore -func CountOrphanedIssueLabels() (int64, error) { - return db.GetEngine(db.DefaultContext).Table("issue_label"). - NotIn("label_id", builder.Select("id").From("label")). - Count() -} - -// DeleteOrphanedIssueLabels delete IssueLabels witch have no label behind anymore -func DeleteOrphanedIssueLabels() error { - _, err := db.GetEngine(db.DefaultContext). - NotIn("label_id", builder.Select("id").From("label")). - Delete(IssueLabel{}) - return err -} - -// CountOrphanedIssues count issues without a repo -func CountOrphanedIssues() (int64, error) { - return db.GetEngine(db.DefaultContext).Table("issue"). - Join("LEFT", "repository", "issue.repo_id=repository.id"). - Where(builder.IsNull{"repository.id"}). - Select("COUNT(`issue`.`id`)"). - Count() -} - -// DeleteOrphanedIssues delete issues without a repo -func DeleteOrphanedIssues() error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - var ids []int64 - - if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id"). - Join("LEFT", "repository", "issue.repo_id=repository.id"). - Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id"). - Find(&ids); err != nil { - return err - } - - var attachmentPaths []string - for i := range ids { - paths, err := deleteIssuesByRepoID(ctx, ids[i]) - if err != nil { - return err - } - attachmentPaths = append(attachmentPaths, paths...) - } - - if err := committer.Commit(); err != nil { - return err - } - committer.Close() - - // Remove issue attachment files. - for i := range attachmentPaths { - admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i]) - } - return nil -} - -// CountOrphanedObjects count subjects with have no existing refobject anymore -func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) { - return db.GetEngine(db.DefaultContext).Table("`"+subject+"`"). - Join("LEFT", "`"+refobject+"`", joinCond). - Where(builder.IsNull{"`" + refobject + "`.id"}). - Select("COUNT(`" + subject + "`.`id`)"). - Count() -} - -// DeleteOrphanedObjects delete subjects with have no existing refobject anymore -func DeleteOrphanedObjects(subject, refobject, joinCond string) error { - subQuery := builder.Select("`"+subject+"`.id"). - From("`"+subject+"`"). - Join("LEFT", "`"+refobject+"`", joinCond). - Where(builder.IsNull{"`" + refobject + "`.id"}) - sql, args, err := builder.Delete(builder.In("id", subQuery)).From("`" + subject + "`").ToSQL() - if err != nil { - return err - } - _, err = db.GetEngine(db.DefaultContext).Exec(append([]interface{}{sql}, args...)...) - return err -} - // CountNullArchivedRepository counts the number of repositories with is_archived is null func CountNullArchivedRepository() (int64, error) { return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(repo_model.Repository)) @@ -181,74 +35,6 @@ func FixWrongUserType() (int64, error) { return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&user_model.User{Type: 1}) } -// CountCommentTypeLabelWithEmptyLabel count label comments with empty label -func CountCommentTypeLabelWithEmptyLabel() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Count(new(Comment)) -} - -// FixCommentTypeLabelWithEmptyLabel count label comments with empty label -func FixCommentTypeLabelWithEmptyLabel() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Delete(new(Comment)) -} - -// CountCommentTypeLabelWithOutsideLabels count label comments with outside label -func CountCommentTypeLabelWithOutsideLabels() (int64, error) { - return db.GetEngine(db.DefaultContext).Where("comment.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))", CommentTypeLabel). - Table("comment"). - Join("inner", "label", "label.id = comment.label_id"). - Join("inner", "issue", "issue.id = comment.issue_id "). - Join("inner", "repository", "issue.repo_id = repository.id"). - Count(new(Comment)) -} - -// FixCommentTypeLabelWithOutsideLabels count label comments with outside label -func FixCommentTypeLabelWithOutsideLabels() (int64, error) { - res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM comment WHERE comment.id IN ( - SELECT il_too.id FROM ( - SELECT com.id - FROM comment AS com - INNER JOIN label ON com.label_id = label.id - INNER JOIN issue on issue.id = com.issue_id - INNER JOIN repository ON issue.repo_id = repository.id - WHERE - com.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)) - ) AS il_too)`, CommentTypeLabel) - if err != nil { - return 0, err - } - - return res.RowsAffected() -} - -// CountIssueLabelWithOutsideLabels count label comments with outside label -func CountIssueLabelWithOutsideLabels() (int64, error) { - return db.GetEngine(db.DefaultContext).Where(builder.Expr("(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)")). - Table("issue_label"). - Join("inner", "label", "issue_label.label_id = label.id "). - Join("inner", "issue", "issue.id = issue_label.issue_id "). - Join("inner", "repository", "issue.repo_id = repository.id"). - Count(new(IssueLabel)) -} - -// FixIssueLabelWithOutsideLabels fix label comments with outside label -func FixIssueLabelWithOutsideLabels() (int64, error) { - res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM issue_label WHERE issue_label.id IN ( - SELECT il_too.id FROM ( - SELECT il_too_too.id - FROM issue_label AS il_too_too - INNER JOIN label ON il_too_too.label_id = label.id - INNER JOIN issue on issue.id = il_too_too.issue_id - INNER JOIN repository on repository.id = issue.repo_id - WHERE - (label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id) - ) AS il_too )`) - if err != nil { - return 0, err - } - - return res.RowsAffected() -} - // CountActionCreatedUnixString count actions where created_unix is an empty string func CountActionCreatedUnixString() (int64, error) { if setting.Database.UseSQLite3 { diff --git a/models/consistency_test.go b/models/consistency_test.go deleted file mode 100644 index fb946b2fb7..0000000000 --- a/models/consistency_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2021 Gitea. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "testing" - - "code.gitea.io/gitea/models/db" - issues_model "code.gitea.io/gitea/models/issues" - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/timeutil" - - "github.com/stretchr/testify/assert" -) - -func TestDeleteOrphanedObjects(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - countBefore, err := db.GetEngine(db.DefaultContext).Count(&PullRequest{}) - assert.NoError(t, err) - - _, err = db.GetEngine(db.DefaultContext).Insert(&PullRequest{IssueID: 1000}, &PullRequest{IssueID: 1001}, &PullRequest{IssueID: 1003}) - assert.NoError(t, err) - - orphaned, err := CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id") - assert.NoError(t, err) - assert.EqualValues(t, 3, orphaned) - - err = DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id") - assert.NoError(t, err) - - countAfter, err := db.GetEngine(db.DefaultContext).Count(&PullRequest{}) - assert.NoError(t, err) - assert.EqualValues(t, countBefore, countAfter) -} - -func TestNewMilestone(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := &issues_model.Milestone{ - RepoID: 1, - Name: "milestoneName", - Content: "milestoneContent", - } - - assert.NoError(t, issues_model.NewMilestone(milestone)) - unittest.AssertExistsAndLoadBean(t, milestone) - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) -} - -func TestChangeMilestoneStatus(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) - - assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, true)) - unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1") - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) - - assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, false)) - unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=0") - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) -} - -func TestDeleteMilestoneByRepoID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, issues_model.DeleteMilestoneByRepoID(1, 1)) - unittest.AssertNotExistsBean(t, &issues_model.Milestone{ID: 1}) - unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}) - - assert.NoError(t, issues_model.DeleteMilestoneByRepoID(unittest.NonexistentID, unittest.NonexistentID)) -} - -func TestUpdateMilestone(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) - milestone.Name = " newMilestoneName " - milestone.Content = "newMilestoneContent" - assert.NoError(t, issues_model.UpdateMilestone(milestone, milestone.IsClosed)) - milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) - assert.EqualValues(t, "newMilestoneName", milestone.Name) - unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) -} - -func TestUpdateMilestoneCounters(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{MilestoneID: 1}, - "is_closed=0").(*Issue) - - issue.IsClosed = true - issue.ClosedUnix = timeutil.TimeStampNow() - _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) - assert.NoError(t, err) - assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) - unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) - - issue.IsClosed = false - issue.ClosedUnix = 0 - _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) - assert.NoError(t, err) - assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) - unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) -} - -func TestConsistencyUpdateAction(t *testing.T) { - if !setting.Database.UseSQLite3 { - t.Skip("Test is only for SQLite database.") - } - assert.NoError(t, unittest.PrepareTestDatabase()) - id := 8 - unittest.AssertExistsAndLoadBean(t, &Action{ - ID: int64(id), - }) - _, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id) - assert.NoError(t, err) - actions := make([]*Action, 0, 1) - // - // XORM returns an error when created_unix is a string - // - err = db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions) - if assert.Error(t, err) { - assert.Contains(t, err.Error(), "type string to a int64: invalid syntax") - } - // - // Get rid of incorrectly set created_unix - // - count, err := CountActionCreatedUnixString() - assert.NoError(t, err) - assert.EqualValues(t, 1, count) - count, err = FixActionCreatedUnixString() - assert.NoError(t, err) - assert.EqualValues(t, 1, count) - - count, err = CountActionCreatedUnixString() - assert.NoError(t, err) - assert.EqualValues(t, 0, count) - count, err = FixActionCreatedUnixString() - assert.NoError(t, err) - assert.EqualValues(t, 0, count) - - // - // XORM must be happy now - // - assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) - unittest.CheckConsistencyFor(t, &Action{}) -} diff --git a/models/db/consistency.go b/models/db/consistency.go new file mode 100644 index 0000000000..7addb174c4 --- /dev/null +++ b/models/db/consistency.go @@ -0,0 +1,27 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package db + +import "xorm.io/builder" + +// CountOrphanedObjects count subjects with have no existing refobject anymore +func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) { + return GetEngine(DefaultContext).Table("`"+subject+"`"). + Join("LEFT", "`"+refobject+"`", joinCond). + Where(builder.IsNull{"`" + refobject + "`.id"}). + Select("COUNT(`" + subject + "`.`id`)"). + Count() +} + +// DeleteOrphanedObjects delete subjects with have no existing refobject anymore +func DeleteOrphanedObjects(subject, refobject, joinCond string) error { + subQuery := builder.Select("`"+subject+"`.id"). + From("`"+subject+"`"). + Join("LEFT", "`"+refobject+"`", joinCond). + Where(builder.IsNull{"`" + refobject + "`.id"}) + b := builder.Delete(builder.In("id", subQuery)).From("`" + subject + "`") + _, err := GetEngine(DefaultContext).Exec(b) + return err +} diff --git a/models/db/index.go b/models/db/index.go index 8598de9498..9b164db1fa 100644 --- a/models/db/index.go +++ b/models/db/index.go @@ -20,21 +20,21 @@ type ResourceIndex struct { } // UpsertResourceIndex the function will not return until it acquires the lock or receives an error. -func UpsertResourceIndex(e Engine, tableName string, groupID int64) (err error) { +func UpsertResourceIndex(ctx context.Context, tableName string, groupID int64) (err error) { // An atomic UPSERT operation (INSERT/UPDATE) is the only operation // that ensures that the key is actually locked. switch { case setting.Database.UseSQLite3 || setting.Database.UsePostgreSQL: - _, err = e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+ + _, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+ "VALUES (?,1) ON CONFLICT (group_id) DO UPDATE SET max_index = %s.max_index+1", tableName, tableName), groupID) case setting.Database.UseMySQL: - _, err = e.Exec(fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+ + _, err = Exec(ctx, fmt.Sprintf("INSERT INTO %s (group_id, max_index) "+ "VALUES (?,1) ON DUPLICATE KEY UPDATE max_index = max_index+1", tableName), groupID) case setting.Database.UseMSSQL: // https://weblogs.sqlteam.com/dang/2009/01/31/upsert-race-condition-with-merge/ - _, err = e.Exec(fmt.Sprintf("MERGE %s WITH (HOLDLOCK) as target "+ + _, err = Exec(ctx, fmt.Sprintf("MERGE %s WITH (HOLDLOCK) as target "+ "USING (SELECT ? AS group_id) AS src "+ "ON src.group_id = target.group_id "+ "WHEN MATCHED THEN UPDATE SET target.max_index = target.max_index+1 "+ @@ -82,30 +82,29 @@ func DeleteResouceIndex(ctx context.Context, tableName string, groupID int64) er // getNextResourceIndex return the next index func getNextResourceIndex(tableName string, groupID int64) (int64, error) { - sess := x.NewSession() - defer sess.Close() - if err := sess.Begin(); err != nil { - return 0, err - } - var preIdx int64 - _, err := sess.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&preIdx) + ctx, commiter, err := TxContext() if err != nil { return 0, err } + defer commiter.Close() + var preIdx int64 + if _, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ?", tableName), groupID).Get(&preIdx); err != nil { + return 0, err + } - if err := UpsertResourceIndex(sess, tableName, groupID); err != nil { + if err := UpsertResourceIndex(ctx, tableName, groupID); err != nil { return 0, err } var curIdx int64 - has, err := sess.SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ? AND max_index=?", tableName), groupID, preIdx+1).Get(&curIdx) + has, err := GetEngine(ctx).SQL(fmt.Sprintf("SELECT max_index FROM %s WHERE group_id = ? AND max_index=?", tableName), groupID, preIdx+1).Get(&curIdx) if err != nil { return 0, err } if !has { return 0, ErrResouceOutdated } - if err := sess.Commit(); err != nil { + if err := commiter.Commit(); err != nil { return 0, err } return curIdx, nil diff --git a/models/db/list_options.go b/models/db/list_options.go index 843e73c8ae..d1d52b6667 100644 --- a/models/db/list_options.go +++ b/models/db/list_options.go @@ -10,6 +10,11 @@ import ( "xorm.io/xorm" ) +const ( + // DefaultMaxInSize represents default variables number on IN () in SQL + DefaultMaxInSize = 50 +) + // Paginator is the base for different ListOptions types type Paginator interface { GetSkipTake() (skip, take int) diff --git a/models/error.go b/models/error.go index 16ae52fc43..3c617904f8 100644 --- a/models/error.go +++ b/models/error.go @@ -405,22 +405,6 @@ func (err ErrFilePathProtected) Error() string { return fmt.Sprintf("path is protected and can not be changed [path: %s]", err.Path) } -// ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo. -type ErrUserDoesNotHaveAccessToRepo struct { - UserID int64 - RepoName string -} - -// IsErrUserDoesNotHaveAccessToRepo checks if an error is a ErrRepoFileAlreadyExists. -func IsErrUserDoesNotHaveAccessToRepo(err error) bool { - _, ok := err.(ErrUserDoesNotHaveAccessToRepo) - return ok -} - -func (err ErrUserDoesNotHaveAccessToRepo) Error() string { - return fmt.Sprintf("user doesn't have access to repo [user_id: %d, repo_name: %s]", err.UserID, err.RepoName) -} - // __________ .__ // \______ \____________ ____ ____ | |__ // | | _/\_ __ \__ \ / \_/ ___\| | \ @@ -580,162 +564,6 @@ func (err ErrSHAOrCommitIDNotProvided) Error() string { return "a SHA or commit ID must be proved when updating a file" } -// .___ -// | | ______ ________ __ ____ -// | |/ ___// ___/ | \_/ __ \ -// | |\___ \ \___ \| | /\ ___/ -// |___/____ >____ >____/ \___ > -// \/ \/ \/ - -// ErrIssueNotExist represents a "IssueNotExist" kind of error. -type ErrIssueNotExist struct { - ID int64 - RepoID int64 - Index int64 -} - -// IsErrIssueNotExist checks if an error is a ErrIssueNotExist. -func IsErrIssueNotExist(err error) bool { - _, ok := err.(ErrIssueNotExist) - return ok -} - -func (err ErrIssueNotExist) Error() string { - return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) -} - -// ErrIssueIsClosed represents a "IssueIsClosed" kind of error. -type ErrIssueIsClosed struct { - ID int64 - RepoID int64 - Index int64 -} - -// IsErrIssueIsClosed checks if an error is a ErrIssueNotExist. -func IsErrIssueIsClosed(err error) bool { - _, ok := err.(ErrIssueIsClosed) - return ok -} - -func (err ErrIssueIsClosed) Error() string { - return fmt.Sprintf("issue is closed [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) -} - -// ErrNewIssueInsert is used when the INSERT statement in newIssue fails -type ErrNewIssueInsert struct { - OriginalError error -} - -// IsErrNewIssueInsert checks if an error is a ErrNewIssueInsert. -func IsErrNewIssueInsert(err error) bool { - _, ok := err.(ErrNewIssueInsert) - return ok -} - -func (err ErrNewIssueInsert) Error() string { - return err.OriginalError.Error() -} - -// ErrIssueWasClosed is used when close a closed issue -type ErrIssueWasClosed struct { - ID int64 - Index int64 -} - -// IsErrIssueWasClosed checks if an error is a ErrIssueWasClosed. -func IsErrIssueWasClosed(err error) bool { - _, ok := err.(ErrIssueWasClosed) - return ok -} - -func (err ErrIssueWasClosed) Error() string { - return fmt.Sprintf("Issue [%d] %d was already closed", err.ID, err.Index) -} - -// ErrPullWasClosed is used close a closed pull request -type ErrPullWasClosed struct { - ID int64 - Index int64 -} - -// IsErrPullWasClosed checks if an error is a ErrErrPullWasClosed. -func IsErrPullWasClosed(err error) bool { - _, ok := err.(ErrPullWasClosed) - return ok -} - -func (err ErrPullWasClosed) Error() string { - return fmt.Sprintf("Pull request [%d] %d was already closed", err.ID, err.Index) -} - -// __________ .__ .__ __________ __ -// \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_ -// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\ -// | | | | / |_| |_| | \ ___< <_| | | /\ ___/ \___ \ | | -// |____| |____/|____/____/____|_ /\___ >__ |____/ \___ >____ > |__| -// \/ \/ |__| \/ \/ - -// ErrPullRequestNotExist represents a "PullRequestNotExist" kind of error. -type ErrPullRequestNotExist struct { - ID int64 - IssueID int64 - HeadRepoID int64 - BaseRepoID int64 - HeadBranch string - BaseBranch string -} - -// IsErrPullRequestNotExist checks if an error is a ErrPullRequestNotExist. -func IsErrPullRequestNotExist(err error) bool { - _, ok := err.(ErrPullRequestNotExist) - return ok -} - -func (err ErrPullRequestNotExist) Error() string { - return fmt.Sprintf("pull request does not exist [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", - err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) -} - -// ErrPullRequestAlreadyExists represents a "PullRequestAlreadyExists"-error -type ErrPullRequestAlreadyExists struct { - ID int64 - IssueID int64 - HeadRepoID int64 - BaseRepoID int64 - HeadBranch string - BaseBranch string -} - -// IsErrPullRequestAlreadyExists checks if an error is a ErrPullRequestAlreadyExists. -func IsErrPullRequestAlreadyExists(err error) bool { - _, ok := err.(ErrPullRequestAlreadyExists) - return ok -} - -// Error does pretty-printing :D -func (err ErrPullRequestAlreadyExists) Error() string { - return fmt.Sprintf("pull request already exists for these targets [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", - err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) -} - -// ErrPullRequestHeadRepoMissing represents a "ErrPullRequestHeadRepoMissing" error -type ErrPullRequestHeadRepoMissing struct { - ID int64 - HeadRepoID int64 -} - -// IsErrErrPullRequestHeadRepoMissing checks if an error is a ErrPullRequestHeadRepoMissing. -func IsErrErrPullRequestHeadRepoMissing(err error) bool { - _, ok := err.(ErrPullRequestHeadRepoMissing) - return ok -} - -// Error does pretty-printing :D -func (err ErrPullRequestHeadRepoMissing) Error() string { - return fmt.Sprintf("pull request head repo missing [id: %d, head_repo_id: %d]", - err.ID, err.HeadRepoID) -} - // ErrInvalidMergeStyle represents an error if merging with disabled merge strategy type ErrInvalidMergeStyle struct { ID int64 @@ -830,29 +658,6 @@ func (err ErrPullRequestHasMerged) Error() string { err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) } -// _________ __ -// \_ ___ \ ____ _____ _____ ____ _____/ |_ -// / \ \/ / _ \ / \ / \_/ __ \ / \ __\ -// \ \___( <_> ) Y Y \ Y Y \ ___/| | \ | -// \______ /\____/|__|_| /__|_| /\___ >___| /__| -// \/ \/ \/ \/ \/ - -// ErrCommentNotExist represents a "CommentNotExist" kind of error. -type ErrCommentNotExist struct { - ID int64 - IssueID int64 -} - -// IsErrCommentNotExist checks if an error is a ErrCommentNotExist. -func IsErrCommentNotExist(err error) bool { - _, ok := err.(ErrCommentNotExist) - return ok -} - -func (err ErrCommentNotExist) Error() string { - return fmt.Sprintf("comment does not exist [id: %d, issue_id: %d]", err.ID, err.IssueID) -} - // _________ __ __ .__ // / _____// |_ ____ ________ _ _______ _/ |_ ____ | |__ // \_____ \\ __\/ _ \\____ \ \/ \/ /\__ \\ __\/ ___\| | \ @@ -897,60 +702,6 @@ func (err ErrTrackedTimeNotExist) Error() string { return fmt.Sprintf("tracked time does not exist [id: %d]", err.ID) } -// .____ ___. .__ -// | | _____ \_ |__ ____ | | -// | | \__ \ | __ \_/ __ \| | -// | |___ / __ \| \_\ \ ___/| |__ -// |_______ (____ /___ /\___ >____/ -// \/ \/ \/ \/ - -// ErrRepoLabelNotExist represents a "RepoLabelNotExist" kind of error. -type ErrRepoLabelNotExist struct { - LabelID int64 - RepoID int64 -} - -// IsErrRepoLabelNotExist checks if an error is a RepoErrLabelNotExist. -func IsErrRepoLabelNotExist(err error) bool { - _, ok := err.(ErrRepoLabelNotExist) - return ok -} - -func (err ErrRepoLabelNotExist) Error() string { - return fmt.Sprintf("label does not exist [label_id: %d, repo_id: %d]", err.LabelID, err.RepoID) -} - -// ErrOrgLabelNotExist represents a "OrgLabelNotExist" kind of error. -type ErrOrgLabelNotExist struct { - LabelID int64 - OrgID int64 -} - -// IsErrOrgLabelNotExist checks if an error is a OrgErrLabelNotExist. -func IsErrOrgLabelNotExist(err error) bool { - _, ok := err.(ErrOrgLabelNotExist) - return ok -} - -func (err ErrOrgLabelNotExist) Error() string { - return fmt.Sprintf("label does not exist [label_id: %d, org_id: %d]", err.LabelID, err.OrgID) -} - -// ErrLabelNotExist represents a "LabelNotExist" kind of error. -type ErrLabelNotExist struct { - LabelID int64 -} - -// IsErrLabelNotExist checks if an error is a ErrLabelNotExist. -func IsErrLabelNotExist(err error) bool { - _, ok := err.(ErrLabelNotExist) - return ok -} - -func (err ErrLabelNotExist) Error() string { - return fmt.Sprintf("label does not exist [label_id: %d]", err.LabelID) -} - // ____ ___ .__ .___ // | | \______ | | _________ __| _/ // | | /\____ \| | / _ \__ \ / __ | @@ -974,130 +725,3 @@ func IsErrUploadNotExist(err error) bool { func (err ErrUploadNotExist) Error() string { return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) } - -// .___ ________ .___ .__ -// | | ______ ________ __ ____ \______ \ ____ ______ ____ ____ __| _/____ ____ ____ |__| ____ ______ -// | |/ ___// ___/ | \_/ __ \ | | \_/ __ \\____ \_/ __ \ / \ / __ |/ __ \ / \_/ ___\| |/ __ \ / ___/ -// | |\___ \ \___ \| | /\ ___/ | ` \ ___/| |_> > ___/| | \/ /_/ \ ___/| | \ \___| \ ___/ \___ \ -// |___/____ >____ >____/ \___ >_______ /\___ > __/ \___ >___| /\____ |\___ >___| /\___ >__|\___ >____ > -// \/ \/ \/ \/ \/|__| \/ \/ \/ \/ \/ \/ \/ \/ - -// ErrDependencyExists represents a "DependencyAlreadyExists" kind of error. -type ErrDependencyExists struct { - IssueID int64 - DependencyID int64 -} - -// IsErrDependencyExists checks if an error is a ErrDependencyExists. -func IsErrDependencyExists(err error) bool { - _, ok := err.(ErrDependencyExists) - return ok -} - -func (err ErrDependencyExists) Error() string { - return fmt.Sprintf("issue dependency does already exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) -} - -// ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error. -type ErrDependencyNotExists struct { - IssueID int64 - DependencyID int64 -} - -// IsErrDependencyNotExists checks if an error is a ErrDependencyExists. -func IsErrDependencyNotExists(err error) bool { - _, ok := err.(ErrDependencyNotExists) - return ok -} - -func (err ErrDependencyNotExists) Error() string { - return fmt.Sprintf("issue dependency does not exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) -} - -// ErrCircularDependency represents a "DependencyCircular" kind of error. -type ErrCircularDependency struct { - IssueID int64 - DependencyID int64 -} - -// IsErrCircularDependency checks if an error is a ErrCircularDependency. -func IsErrCircularDependency(err error) bool { - _, ok := err.(ErrCircularDependency) - return ok -} - -func (err ErrCircularDependency) Error() string { - return fmt.Sprintf("circular dependencies exists (two issues blocking each other) [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) -} - -// ErrDependenciesLeft represents an error where the issue you're trying to close still has dependencies left. -type ErrDependenciesLeft struct { - IssueID int64 -} - -// IsErrDependenciesLeft checks if an error is a ErrDependenciesLeft. -func IsErrDependenciesLeft(err error) bool { - _, ok := err.(ErrDependenciesLeft) - return ok -} - -func (err ErrDependenciesLeft) Error() string { - return fmt.Sprintf("issue has open dependencies [issue id: %d]", err.IssueID) -} - -// ErrUnknownDependencyType represents an error where an unknown dependency type was passed -type ErrUnknownDependencyType struct { - Type DependencyType -} - -// IsErrUnknownDependencyType checks if an error is ErrUnknownDependencyType -func IsErrUnknownDependencyType(err error) bool { - _, ok := err.(ErrUnknownDependencyType) - return ok -} - -func (err ErrUnknownDependencyType) Error() string { - return fmt.Sprintf("unknown dependency type [type: %d]", err.Type) -} - -// __________ .__ -// \______ \ _______ _|__| ______ _ __ -// | _// __ \ \/ / |/ __ \ \/ \/ / -// | | \ ___/\ /| \ ___/\ / -// |____|_ /\___ >\_/ |__|\___ >\/\_/ -// \/ \/ \/ - -// ErrReviewNotExist represents a "ReviewNotExist" kind of error. -type ErrReviewNotExist struct { - ID int64 -} - -// IsErrReviewNotExist checks if an error is a ErrReviewNotExist. -func IsErrReviewNotExist(err error) bool { - _, ok := err.(ErrReviewNotExist) - return ok -} - -func (err ErrReviewNotExist) Error() string { - return fmt.Sprintf("review does not exist [id: %d]", err.ID) -} - -// ErrNotValidReviewRequest an not allowed review request modify -type ErrNotValidReviewRequest struct { - Reason string - UserID int64 - RepoID int64 -} - -// IsErrNotValidReviewRequest checks if an error is a ErrNotValidReviewRequest. -func IsErrNotValidReviewRequest(err error) bool { - _, ok := err.(ErrNotValidReviewRequest) - return ok -} - -func (err ErrNotValidReviewRequest) Error() string { - return fmt.Sprintf("%s [user_id: %d, repo_id: %d]", - err.Reason, - err.UserID, - err.RepoID) -} diff --git a/models/git/branches_test.go b/models/git/branches_test.go index 1e0b1a98b6..8102d28d48 100644 --- a/models/git/branches_test.go +++ b/models/git/branches_test.go @@ -7,9 +7,9 @@ package git_test import ( "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -120,10 +120,10 @@ func TestRenameBranch(t *testing.T) { repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) assert.Equal(t, "main", repo1.DefaultBranch) - pull := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 1}).(*models.PullRequest) // merged + pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) // merged assert.Equal(t, "master", pull.BaseBranch) - pull = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) // open + pull = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) // open assert.Equal(t, "main", pull.BaseBranch) renamedBranch := unittest.AssertExistsAndLoadBean(t, &git_model.RenamedBranch{ID: 2}).(*git_model.RenamedBranch) diff --git a/models/git/main_test.go b/models/git/main_test.go index 02401e5204..dc30dfaad7 100644 --- a/models/git/main_test.go +++ b/models/git/main_test.go @@ -8,6 +8,7 @@ import ( "path/filepath" "testing" + _ "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/unittest" ) diff --git a/models/issue_label_test.go b/models/issue_label_test.go deleted file mode 100644 index 67a09151d8..0000000000 --- a/models/issue_label_test.go +++ /dev/null @@ -1,394 +0,0 @@ -// Copyright 2017 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "html/template" - "testing" - - "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" - - "github.com/stretchr/testify/assert" -) - -// TODO TestGetLabelTemplateFile - -func TestLabel_CalOpenIssues(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - label.CalOpenIssues() - assert.EqualValues(t, 2, label.NumOpenIssues) -} - -func TestLabel_ForegroundColor(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - assert.Equal(t, template.CSS("#000"), label.ForegroundColor()) - - label = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - assert.Equal(t, template.CSS("#fff"), label.ForegroundColor()) -} - -func TestNewLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labels := []*Label{ - {RepoID: 2, Name: "labelName2", Color: "#123456"}, - {RepoID: 3, Name: "labelName3", Color: "#123"}, - {RepoID: 4, Name: "labelName4", Color: "ABCDEF"}, - {RepoID: 5, Name: "labelName5", Color: "DEF"}, - } - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: ""})) - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "#45G"})) - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"})) - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "45G"})) - assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "12345G"})) - for _, label := range labels { - unittest.AssertNotExistsBean(t, label) - } - assert.NoError(t, NewLabels(labels...)) - for _, label := range labels { - unittest.AssertExistsAndLoadBean(t, label, unittest.Cond("id = ?", label.ID)) - } - unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{}) -} - -func TestGetLabelByID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelByID(db.DefaultContext, 1) - assert.NoError(t, err) - assert.EqualValues(t, 1, label.ID) - - _, err = GetLabelByID(db.DefaultContext, unittest.NonexistentID) - assert.True(t, IsErrLabelNotExist(err)) -} - -func TestGetLabelInRepoByName(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelInRepoByName(db.DefaultContext, 1, "label1") - assert.NoError(t, err) - assert.EqualValues(t, 1, label.ID) - assert.Equal(t, "label1", label.Name) - - _, err = GetLabelInRepoByName(db.DefaultContext, 1, "") - assert.True(t, IsErrRepoLabelNotExist(err)) - - _, err = GetLabelInRepoByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") - assert.True(t, IsErrRepoLabelNotExist(err)) -} - -func TestGetLabelInRepoByNames(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labelIDs, err := GetLabelIDsInRepoByNames(1, []string{"label1", "label2"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(1), labelIDs[0]) - assert.Equal(t, int64(2), labelIDs[1]) -} - -func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - // label3 doesn't exists.. See labels.yml - labelIDs, err := GetLabelIDsInRepoByNames(1, []string{"label1", "label2", "label3"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(1), labelIDs[0]) - assert.Equal(t, int64(2), labelIDs[1]) - assert.NoError(t, err) -} - -func TestGetLabelInRepoByID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelInRepoByID(db.DefaultContext, 1, 1) - assert.NoError(t, err) - assert.EqualValues(t, 1, label.ID) - - _, err = GetLabelInRepoByID(db.DefaultContext, 1, -1) - assert.True(t, IsErrRepoLabelNotExist(err)) - - _, err = GetLabelInRepoByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) - assert.True(t, IsErrRepoLabelNotExist(err)) -} - -func TestGetLabelsInRepoByIDs(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := GetLabelsInRepoByIDs(1, []int64{1, 2, unittest.NonexistentID}) - assert.NoError(t, err) - if assert.Len(t, labels, 2) { - assert.EqualValues(t, 1, labels[0].ID) - assert.EqualValues(t, 2, labels[1].ID) - } -} - -func TestGetLabelsByRepoID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) { - labels, err := GetLabelsByRepoID(db.DefaultContext, repoID, sortType, db.ListOptions{}) - assert.NoError(t, err) - assert.Len(t, labels, len(expectedIssueIDs)) - for i, label := range labels { - assert.EqualValues(t, expectedIssueIDs[i], label.ID) - } - } - testSuccess(1, "leastissues", []int64{2, 1}) - testSuccess(1, "mostissues", []int64{1, 2}) - testSuccess(1, "reversealphabetically", []int64{2, 1}) - testSuccess(1, "default", []int64{1, 2}) -} - -// Org versions - -func TestGetLabelInOrgByName(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelInOrgByName(db.DefaultContext, 3, "orglabel3") - assert.NoError(t, err) - assert.EqualValues(t, 3, label.ID) - assert.Equal(t, "orglabel3", label.Name) - - _, err = GetLabelInOrgByName(db.DefaultContext, 3, "") - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByName(db.DefaultContext, 0, "orglabel3") - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByName(db.DefaultContext, -1, "orglabel3") - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") - assert.True(t, IsErrOrgLabelNotExist(err)) -} - -func TestGetLabelInOrgByNames(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labelIDs, err := GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(3), labelIDs[0]) - assert.Equal(t, int64(4), labelIDs[1]) -} - -func TestGetLabelInOrgByNamesDiscardsNonExistentLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - // orglabel99 doesn't exists.. See labels.yml - labelIDs, err := GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4", "orglabel99"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(3), labelIDs[0]) - assert.Equal(t, int64(4), labelIDs[1]) - assert.NoError(t, err) -} - -func TestGetLabelInOrgByID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label, err := GetLabelInOrgByID(db.DefaultContext, 3, 3) - assert.NoError(t, err) - assert.EqualValues(t, 3, label.ID) - - _, err = GetLabelInOrgByID(db.DefaultContext, 3, -1) - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByID(db.DefaultContext, 0, 3) - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByID(db.DefaultContext, -1, 3) - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelInOrgByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) - assert.True(t, IsErrOrgLabelNotExist(err)) -} - -func TestGetLabelsInOrgByIDs(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := GetLabelsInOrgByIDs(3, []int64{3, 4, unittest.NonexistentID}) - assert.NoError(t, err) - if assert.Len(t, labels, 2) { - assert.EqualValues(t, 3, labels[0].ID) - assert.EqualValues(t, 4, labels[1].ID) - } -} - -func TestGetLabelsByOrgID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - testSuccess := func(orgID int64, sortType string, expectedIssueIDs []int64) { - labels, err := GetLabelsByOrgID(db.DefaultContext, orgID, sortType, db.ListOptions{}) - assert.NoError(t, err) - assert.Len(t, labels, len(expectedIssueIDs)) - for i, label := range labels { - assert.EqualValues(t, expectedIssueIDs[i], label.ID) - } - } - testSuccess(3, "leastissues", []int64{3, 4}) - testSuccess(3, "mostissues", []int64{4, 3}) - testSuccess(3, "reversealphabetically", []int64{4, 3}) - testSuccess(3, "default", []int64{3, 4}) - - var err error - _, err = GetLabelsByOrgID(db.DefaultContext, 0, "leastissues", db.ListOptions{}) - assert.True(t, IsErrOrgLabelNotExist(err)) - - _, err = GetLabelsByOrgID(db.DefaultContext, -1, "leastissues", db.ListOptions{}) - assert.True(t, IsErrOrgLabelNotExist(err)) -} - -// - -func TestGetLabelsByIssueID(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labels, err := GetLabelsByIssueID(db.DefaultContext, 1) - assert.NoError(t, err) - if assert.Len(t, labels, 1) { - assert.EqualValues(t, 1, labels[0].ID) - } - - labels, err = GetLabelsByIssueID(db.DefaultContext, unittest.NonexistentID) - assert.NoError(t, err) - assert.Len(t, labels, 0) -} - -func TestUpdateLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - // make sure update wont overwrite it - update := &Label{ - ID: label.ID, - Color: "#ffff00", - Name: "newLabelName", - Description: label.Description, - } - label.Color = update.Color - label.Name = update.Name - assert.NoError(t, UpdateLabel(update)) - newLabel := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - assert.EqualValues(t, label.ID, newLabel.ID) - assert.EqualValues(t, label.Color, newLabel.Color) - assert.EqualValues(t, label.Name, newLabel.Name) - assert.EqualValues(t, label.Description, newLabel.Description) - unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{}) -} - -func TestDeleteLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - assert.NoError(t, DeleteLabel(label.RepoID, label.ID)) - unittest.AssertNotExistsBean(t, &Label{ID: label.ID, RepoID: label.RepoID}) - - assert.NoError(t, DeleteLabel(label.RepoID, label.ID)) - unittest.AssertNotExistsBean(t, &Label{ID: label.ID}) - - assert.NoError(t, DeleteLabel(unittest.NonexistentID, unittest.NonexistentID)) - unittest.CheckConsistencyFor(t, &Label{}, &repo_model.Repository{}) -} - -func TestHasIssueLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - assert.True(t, HasIssueLabel(db.DefaultContext, 1, 1)) - assert.False(t, HasIssueLabel(db.DefaultContext, 1, 2)) - assert.False(t, HasIssueLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) -} - -func TestNewIssueLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - - // add new IssueLabel - prevNumIssues := label.NumIssues - assert.NoError(t, NewIssueLabel(issue, label, doer)) - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label.ID}) - unittest.AssertExistsAndLoadBean(t, &Comment{ - Type: CommentTypeLabel, - PosterID: doer.ID, - IssueID: issue.ID, - LabelID: label.ID, - Content: "1", - }) - label = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - assert.EqualValues(t, prevNumIssues+1, label.NumIssues) - - // re-add existing IssueLabel - assert.NoError(t, NewIssueLabel(issue, label, doer)) - unittest.CheckConsistencyFor(t, &Issue{}, &Label{}) -} - -func TestNewIssueLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - label1 := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - label2 := unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 5}).(*Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - - assert.NoError(t, NewIssueLabels(issue, []*Label{label1, label2}, doer)) - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) - unittest.AssertExistsAndLoadBean(t, &Comment{ - Type: CommentTypeLabel, - PosterID: doer.ID, - IssueID: issue.ID, - LabelID: label1.ID, - Content: "1", - }) - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) - label1 = unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) - assert.EqualValues(t, 3, label1.NumIssues) - assert.EqualValues(t, 1, label1.NumClosedIssues) - label2 = unittest.AssertExistsAndLoadBean(t, &Label{ID: 2}).(*Label) - assert.EqualValues(t, 1, label2.NumIssues) - assert.EqualValues(t, 1, label2.NumClosedIssues) - - // corner case: test empty slice - assert.NoError(t, NewIssueLabels(issue, []*Label{}, doer)) - - unittest.CheckConsistencyFor(t, &Issue{}, &Label{}) -} - -func TestDeleteIssueLabel(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - testSuccess := func(labelID, issueID, doerID int64) { - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issueID}).(*Issue) - doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID}).(*user_model.User) - - expectedNumIssues := label.NumIssues - expectedNumClosedIssues := label.NumClosedIssues - if unittest.BeanExists(t, &IssueLabel{IssueID: issueID, LabelID: labelID}) { - expectedNumIssues-- - if issue.IsClosed { - expectedNumClosedIssues-- - } - } - - ctx, committer, err := db.TxContext() - defer committer.Close() - assert.NoError(t, err) - assert.NoError(t, DeleteIssueLabel(ctx, issue, label, doer)) - assert.NoError(t, committer.Commit()) - - unittest.AssertNotExistsBean(t, &IssueLabel{IssueID: issueID, LabelID: labelID}) - unittest.AssertExistsAndLoadBean(t, &Comment{ - Type: CommentTypeLabel, - PosterID: doerID, - IssueID: issueID, - LabelID: labelID, - }, `content=""`) - label = unittest.AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label) - assert.EqualValues(t, expectedNumIssues, label.NumIssues) - assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues) - } - testSuccess(1, 1, 2) - testSuccess(2, 5, 2) - testSuccess(1, 1, 2) // delete non-existent IssueLabel - - unittest.CheckConsistencyFor(t, &Issue{}, &Label{}) -} diff --git a/models/issue_stopwatch_test.go b/models/issue_stopwatch_test.go deleted file mode 100644 index 15d5f234fd..0000000000 --- a/models/issue_stopwatch_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "testing" - - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/timeutil" - - "github.com/stretchr/testify/assert" -) - -func TestCancelStopwatch(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - user1, err := user_model.GetUserByID(1) - assert.NoError(t, err) - - issue1, err := GetIssueByID(1) - assert.NoError(t, err) - issue2, err := GetIssueByID(2) - assert.NoError(t, err) - - err = CancelStopwatch(user1, issue1) - assert.NoError(t, err) - unittest.AssertNotExistsBean(t, &Stopwatch{UserID: user1.ID, IssueID: issue1.ID}) - - _ = unittest.AssertExistsAndLoadBean(t, &Comment{Type: CommentTypeCancelTracking, PosterID: user1.ID, IssueID: issue1.ID}) - - assert.Nil(t, CancelStopwatch(user1, issue2)) -} - -func TestStopwatchExists(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - assert.True(t, StopwatchExists(1, 1)) - assert.False(t, StopwatchExists(1, 2)) -} - -func TestHasUserStopwatch(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - exists, sw, err := HasUserStopwatch(db.DefaultContext, 1) - assert.NoError(t, err) - assert.True(t, exists) - assert.Equal(t, int64(1), sw.ID) - - exists, _, err = HasUserStopwatch(db.DefaultContext, 3) - assert.NoError(t, err) - assert.False(t, exists) -} - -func TestCreateOrStopIssueStopwatch(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - user2, err := user_model.GetUserByID(2) - assert.NoError(t, err) - user3, err := user_model.GetUserByID(3) - assert.NoError(t, err) - - issue1, err := GetIssueByID(1) - assert.NoError(t, err) - issue2, err := GetIssueByID(2) - assert.NoError(t, err) - - assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1)) - sw := unittest.AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch) - assert.LessOrEqual(t, sw.CreatedUnix, timeutil.TimeStampNow()) - - assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2)) - unittest.AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2}) - unittest.AssertExistsAndLoadBean(t, &TrackedTime{UserID: 2, IssueID: 2}) -} diff --git a/models/issue_user_test.go b/models/issue_user_test.go deleted file mode 100644 index 946da6e18d..0000000000 --- a/models/issue_user_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2017 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "testing" - - "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/models/unittest" - - "github.com/stretchr/testify/assert" -) - -func Test_newIssueUsers(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - newIssue := &Issue{ - RepoID: repo.ID, - PosterID: 4, - Index: 6, - Title: "newTestIssueTitle", - Content: "newTestIssueContent", - } - - // artificially insert new issue - unittest.AssertSuccessfulInsert(t, newIssue) - - assert.NoError(t, newIssueUsers(db.DefaultContext, repo, newIssue)) - - // issue_user table should now have entries for new issue - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: newIssue.ID, UID: newIssue.PosterID}) - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: newIssue.ID, UID: repo.OwnerID}) -} - -func TestUpdateIssueUserByRead(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) - - assert.NoError(t, UpdateIssueUserByRead(4, issue.ID)) - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") - - assert.NoError(t, UpdateIssueUserByRead(4, issue.ID)) - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") - - assert.NoError(t, UpdateIssueUserByRead(unittest.NonexistentID, unittest.NonexistentID)) -} - -func TestUpdateIssueUsersByMentions(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) - - uids := []int64{2, 5} - assert.NoError(t, UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids)) - for _, uid := range uids { - unittest.AssertExistsAndLoadBean(t, &IssueUser{IssueID: issue.ID, UID: uid}, "is_mentioned=1") - } -} diff --git a/models/issue_assignees.go b/models/issues/assignees.go similarity index 99% rename from models/issue_assignees.go rename to models/issues/assignees.go index c6ccb6e9d2..5921112fea 100644 --- a/models/issue_assignees.go +++ b/models/issues/assignees.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" diff --git a/models/issue_assignees_test.go b/models/issues/assignees_test.go similarity index 65% rename from models/issue_assignees_test.go rename to models/issues/assignees_test.go index 80317e1604..37d966f140 100644 --- a/models/issue_assignees_test.go +++ b/models/issues/assignees_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -18,27 +19,27 @@ func TestUpdateAssignee(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Fake issue with assignees - issue, err := GetIssueWithAttrsByID(1) + issue, err := issues_model.GetIssueWithAttrsByID(1) assert.NoError(t, err) // Assign multiple users user2, err := user_model.GetUserByID(2) assert.NoError(t, err) - _, _, err = ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user2.ID) + _, _, err = issues_model.ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user2.ID) assert.NoError(t, err) user3, err := user_model.GetUserByID(3) assert.NoError(t, err) - _, _, err = ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user3.ID) + _, _, err = issues_model.ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user3.ID) assert.NoError(t, err) user1, err := user_model.GetUserByID(1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him assert.NoError(t, err) - _, _, err = ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user1.ID) + _, _, err = issues_model.ToggleIssueAssignee(issue, &user_model.User{ID: 1}, user1.ID) assert.NoError(t, err) // Check if he got removed - isAssigned, err := IsUserAssignedToIssue(db.DefaultContext, issue, user1) + isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user1) assert.NoError(t, err) assert.False(t, isAssigned) @@ -54,12 +55,12 @@ func TestUpdateAssignee(t *testing.T) { } // Check if the user is assigned - isAssigned, err = IsUserAssignedToIssue(db.DefaultContext, issue, user2) + isAssigned, err = issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user2) assert.NoError(t, err) assert.True(t, isAssigned) // This user should not be assigned - isAssigned, err = IsUserAssignedToIssue(db.DefaultContext, issue, &user_model.User{ID: 4}) + isAssigned, err = issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, &user_model.User{ID: 4}) assert.NoError(t, err) assert.False(t, isAssigned) } @@ -70,22 +71,22 @@ func TestMakeIDsFromAPIAssigneesToAdd(t *testing.T) { _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - IDs, err := MakeIDsFromAPIAssigneesToAdd("", []string{""}) + IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{""}) assert.NoError(t, err) assert.Equal(t, []int64{}, IDs) - _, err = MakeIDsFromAPIAssigneesToAdd("", []string{"none_existing_user"}) + _, err = issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{"none_existing_user"}) assert.Error(t, err) - IDs, err = MakeIDsFromAPIAssigneesToAdd("user1", []string{"user1"}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("user1", []string{"user1"}) assert.NoError(t, err) assert.Equal(t, []int64{1}, IDs) - IDs, err = MakeIDsFromAPIAssigneesToAdd("user2", []string{""}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("user2", []string{""}) assert.NoError(t, err) assert.Equal(t, []int64{2}, IDs) - IDs, err = MakeIDsFromAPIAssigneesToAdd("", []string{"user1", "user2"}) + IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{"user1", "user2"}) assert.NoError(t, err) assert.Equal(t, []int64{1, 2}, IDs) } diff --git a/models/issue_comment.go b/models/issues/comment.go similarity index 92% rename from models/issue_comment.go rename to models/issues/comment.go index 21cd87108d..a4e69e7118 100644 --- a/models/issue_comment.go +++ b/models/issues/comment.go @@ -4,7 +4,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -16,7 +16,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/models/organization" project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo" @@ -34,6 +33,22 @@ import ( "xorm.io/xorm" ) +// ErrCommentNotExist represents a "CommentNotExist" kind of error. +type ErrCommentNotExist struct { + ID int64 + IssueID int64 +} + +// IsErrCommentNotExist checks if an error is a ErrCommentNotExist. +func IsErrCommentNotExist(err error) bool { + _, ok := err.(ErrCommentNotExist) + return ok +} + +func (err ErrCommentNotExist) Error() string { + return fmt.Sprintf("comment does not exist [id: %d, issue_id: %d]", err.ID, err.IssueID) +} + // CommentType defines whether a comment is just a simple comment, an action (like close) or a reference. type CommentType int @@ -216,8 +231,8 @@ type Comment struct { Project *project_model.Project `xorm:"-"` OldMilestoneID int64 MilestoneID int64 - OldMilestone *issues_model.Milestone `xorm:"-"` - Milestone *issues_model.Milestone `xorm:"-"` + OldMilestone *Milestone `xorm:"-"` + Milestone *Milestone `xorm:"-"` TimeID int64 Time *TrackedTime `xorm:"-"` AssigneeID int64 @@ -250,8 +265,8 @@ type Comment struct { // Reference issue in commit message CommitSHA string `xorm:"VARCHAR(40)"` - Attachments []*repo_model.Attachment `xorm:"-"` - Reactions issues_model.ReactionList `xorm:"-"` + Attachments []*repo_model.Attachment `xorm:"-"` + Reactions ReactionList `xorm:"-"` // For view issue page. ShowRole RoleDescriptor `xorm:"-"` @@ -299,7 +314,7 @@ func (c *Comment) LoadIssueCtx(ctx context.Context) (err error) { if c.Issue != nil { return nil } - c.Issue, err = getIssueByID(ctx, c.IssueID) + c.Issue, err = GetIssueByID(ctx, c.IssueID) return } @@ -503,7 +518,7 @@ func (c *Comment) LoadProject() error { // LoadMilestone if comment.Type is CommentTypeMilestone, then load milestone func (c *Comment) LoadMilestone() error { if c.OldMilestoneID > 0 { - var oldMilestone issues_model.Milestone + var oldMilestone Milestone has, err := db.GetEngine(db.DefaultContext).ID(c.OldMilestoneID).Get(&oldMilestone) if err != nil { return err @@ -513,7 +528,7 @@ func (c *Comment) LoadMilestone() error { } if c.MilestoneID > 0 { - var milestone issues_model.Milestone + var milestone Milestone has, err := db.GetEngine(db.DefaultContext).ID(c.MilestoneID).Get(&milestone) if err != nil { return err @@ -625,7 +640,7 @@ func (c *Comment) LoadDepIssueDetails() (err error) { if c.DependentIssueID <= 0 || c.DependentIssue != nil { return nil } - c.DependentIssue, err = getIssueByID(db.DefaultContext, c.DependentIssueID) + c.DependentIssue, err = GetIssueByID(db.DefaultContext, c.DependentIssueID) return err } @@ -643,7 +658,7 @@ func (c *Comment) loadReactions(ctx context.Context, repo *repo_model.Repository if c.Reactions != nil { return nil } - c.Reactions, _, err = issues_model.FindReactions(ctx, issues_model.FindReactionsOptions{ + c.Reactions, _, err = FindReactions(ctx, FindReactionsOptions{ IssueID: c.IssueID, CommentID: c.ID, }) @@ -823,7 +838,7 @@ func CreateCommentCtx(ctx context.Context, opts *CreateCommentOptions) (_ *Comme return nil, err } - if err = comment.addCrossReferences(ctx, opts.Doer, false); err != nil { + if err = comment.AddCrossReferences(ctx, opts.Doer, false); err != nil { return nil, err } @@ -1128,7 +1143,7 @@ func UpdateComment(c *Comment, doer *user_model.User) error { if err := c.LoadIssueCtx(ctx); err != nil { return err } - if err := c.addCrossReferences(ctx, doer, true); err != nil { + if err := c.AddCrossReferences(ctx, doer, true); err != nil { return err } if err := committer.Commit(); err != nil { @@ -1139,27 +1154,13 @@ func UpdateComment(c *Comment, doer *user_model.User) error { } // DeleteComment deletes the comment -func DeleteComment(comment *Comment) error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err := deleteComment(ctx, comment); err != nil { - return err - } - - return committer.Commit() -} - -func deleteComment(ctx context.Context, comment *Comment) error { +func DeleteComment(ctx context.Context, comment *Comment) error { e := db.GetEngine(ctx) if _, err := e.ID(comment.ID).NoAutoCondition().Delete(comment); err != nil { return err } - if _, err := db.DeleteByBean(ctx, &issues_model.ContentHistory{ + if _, err := db.DeleteByBean(ctx, &ContentHistory{ CommentID: comment.ID, }); err != nil { return err @@ -1170,7 +1171,11 @@ func deleteComment(ctx context.Context, comment *Comment) error { return err } } - if _, err := e.Where("comment_id = ?", comment.ID).Cols("is_deleted").Update(&Action{IsDeleted: true}); err != nil { + if _, err := e.Table("action"). + Where("comment_id = ?", comment.ID). + Update(map[string]interface{}{ + "is_deleted": true, + }); err != nil { return err } @@ -1178,7 +1183,7 @@ func deleteComment(ctx context.Context, comment *Comment) error { return err } - return issues_model.DeleteReaction(ctx, &issues_model.ReactionOptions{CommentID: comment.ID}) + return DeleteReaction(ctx, &ReactionOptions{CommentID: comment.ID}) } // CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS @@ -1500,3 +1505,42 @@ func (c *Comment) GetExternalName() string { return c.OriginalAuthor } // GetExternalID ExternalUserRemappable interface func (c *Comment) GetExternalID() int64 { return c.OriginalAuthorID } + +// CountCommentTypeLabelWithEmptyLabel count label comments with empty label +func CountCommentTypeLabelWithEmptyLabel() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Count(new(Comment)) +} + +// FixCommentTypeLabelWithEmptyLabel count label comments with empty label +func FixCommentTypeLabelWithEmptyLabel() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": CommentTypeLabel, "label_id": 0}).Delete(new(Comment)) +} + +// CountCommentTypeLabelWithOutsideLabels count label comments with outside label +func CountCommentTypeLabelWithOutsideLabels() (int64, error) { + return db.GetEngine(db.DefaultContext).Where("comment.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id))", CommentTypeLabel). + Table("comment"). + Join("inner", "label", "label.id = comment.label_id"). + Join("inner", "issue", "issue.id = comment.issue_id "). + Join("inner", "repository", "issue.repo_id = repository.id"). + Count() +} + +// FixCommentTypeLabelWithOutsideLabels count label comments with outside label +func FixCommentTypeLabelWithOutsideLabels() (int64, error) { + res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM comment WHERE comment.id IN ( + SELECT il_too.id FROM ( + SELECT com.id + FROM comment AS com + INNER JOIN label ON com.label_id = label.id + INNER JOIN issue on issue.id = com.issue_id + INNER JOIN repository ON issue.repo_id = repository.id + WHERE + com.type = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)) + ) AS il_too)`, CommentTypeLabel) + if err != nil { + return 0, err + } + + return res.RowsAffected() +} diff --git a/models/issue_comment_list.go b/models/issues/comment_list.go similarity index 95% rename from models/issue_comment_list.go rename to models/issues/comment_list.go index d62984c1e6..e3406a5cbe 100644 --- a/models/issue_comment_list.go +++ b/models/issues/comment_list.go @@ -2,13 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" "code.gitea.io/gitea/models/db" - issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" @@ -36,7 +35,7 @@ func (comments CommentList) loadPosters(ctx context.Context) error { posterMaps := make(map[int64]*user_model.User, len(posterIDs)) left := len(posterIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -80,7 +79,7 @@ func (comments CommentList) getLabelIDs() []int64 { return container.KeysInt64(ids) } -func (comments CommentList) loadLabels(ctx context.Context) error { +func (comments CommentList) loadLabels(ctx context.Context) error { //nolint if len(comments) == 0 { return nil } @@ -89,7 +88,7 @@ func (comments CommentList) loadLabels(ctx context.Context) error { commentLabels := make(map[int64]*Label, len(labelIDs)) left := len(labelIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -140,10 +139,10 @@ func (comments CommentList) loadMilestones(ctx context.Context) error { return nil } - milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -183,10 +182,10 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error { return nil } - milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -225,7 +224,7 @@ func (comments CommentList) loadAssignees(ctx context.Context) error { assignees := make(map[int64]*user_model.User, len(assigneeIDs)) left := len(assigneeIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -299,7 +298,7 @@ func (comments CommentList) loadIssues(ctx context.Context) error { issues := make(map[int64]*Issue, len(issueIDs)) left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -357,7 +356,7 @@ func (comments CommentList) loadDependentIssues(ctx context.Context) error { issues := make(map[int64]*Issue, len(issueIDs)) left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -406,7 +405,7 @@ func (comments CommentList) loadAttachments(ctx context.Context) (err error) { commentsIDs := comments.getCommentIDs() left := len(commentsIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -449,7 +448,7 @@ func (comments CommentList) getReviewIDs() []int64 { return container.KeysInt64(ids) } -func (comments CommentList) loadReviews(ctx context.Context) error { +func (comments CommentList) loadReviews(ctx context.Context) error { //nolint if len(comments) == 0 { return nil } @@ -458,7 +457,7 @@ func (comments CommentList) loadReviews(ctx context.Context) error { reviews := make(map[int64]*Review, len(reviewIDs)) left := len(reviewIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } diff --git a/models/issue_comment_test.go b/models/issues/comment_test.go similarity index 71% rename from models/issue_comment_test.go rename to models/issues/comment_test.go index d323a08167..06b0b85e3c 100644 --- a/models/issue_comment_test.go +++ b/models/issues/comment_test.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "time" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -19,13 +20,13 @@ import ( func TestCreateComment(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) now := time.Now().Unix() - comment, err := CreateComment(&CreateCommentOptions{ - Type: CommentTypeComment, + comment, err := issues_model.CreateComment(&issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeComment, Doer: doer, Repo: repo, Issue: issue, @@ -34,23 +35,23 @@ func TestCreateComment(t *testing.T) { assert.NoError(t, err) then := time.Now().Unix() - assert.EqualValues(t, CommentTypeComment, comment.Type) + assert.EqualValues(t, issues_model.CommentTypeComment, comment.Type) assert.EqualValues(t, "Hello", comment.Content) assert.EqualValues(t, issue.ID, comment.IssueID) assert.EqualValues(t, doer.ID, comment.PosterID) unittest.AssertInt64InRange(t, now, then, int64(comment.CreatedUnix)) unittest.AssertExistsAndLoadBean(t, comment) // assert actually added to DB - updatedIssue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) + updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}).(*issues_model.Issue) unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) } func TestFetchCodeComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - res, err := FetchCodeComments(db.DefaultContext, issue, user) + res, err := issues_model.FetchCodeComments(db.DefaultContext, issue, user) assert.NoError(t, err) assert.Contains(t, res, "README.md") assert.Contains(t, res["README.md"], int64(4)) @@ -58,7 +59,7 @@ func TestFetchCodeComments(t *testing.T) { assert.Equal(t, int64(4), res["README.md"][4][0].ID) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - res, err = FetchCodeComments(db.DefaultContext, issue, user2) + res, err = issues_model.FetchCodeComments(db.DefaultContext, issue, user2) assert.NoError(t, err) assert.Len(t, res, 1) } diff --git a/models/issues/content_history.go b/models/issues/content_history.go index 4c5af13db7..3e321784bd 100644 --- a/models/issues/content_history.go +++ b/models/issues/content_history.go @@ -53,13 +53,13 @@ func SaveIssueContentHistory(ctx context.Context, posterID, issueID, commentID i } // We only keep at most 20 history revisions now. It is enough in most cases. // If there is a special requirement to keep more, we can consider introducing a new setting option then, but not now. - keepLimitedContentHistory(ctx, issueID, commentID, 20) + KeepLimitedContentHistory(ctx, issueID, commentID, 20) return nil } -// keepLimitedContentHistory keeps at most `limit` history revisions, it will hard delete out-dated revisions, sorting by revision interval +// KeepLimitedContentHistory keeps at most `limit` history revisions, it will hard delete out-dated revisions, sorting by revision interval // we can ignore all errors in this function, so we just log them -func keepLimitedContentHistory(ctx context.Context, issueID, commentID int64, limit int) { +func KeepLimitedContentHistory(ctx context.Context, issueID, commentID int64, limit int) { type IDEditTime struct { ID int64 EditedUnix timeutil.TimeStamp diff --git a/models/issues/content_history_test.go b/models/issues/content_history_test.go index 3cbc0ad5e0..1218d871d0 100644 --- a/models/issues/content_history_test.go +++ b/models/issues/content_history_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package issues +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/timeutil" @@ -20,20 +21,20 @@ func TestContentHistory(t *testing.T) { dbCtx := db.DefaultContext timeStampNow := timeutil.TimeStampNow() - _ = SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow, "i-a", true) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow.Add(2), "i-b", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow.Add(7), "i-c", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow, "i-a", true) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow.Add(2), "i-b", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 0, timeStampNow.Add(7), "i-c", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow, "c-a", true) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(5), "c-b", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(20), "c-c", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(50), "c-d", false) - _ = SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(51), "c-e", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow, "c-a", true) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(5), "c-b", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(20), "c-c", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(50), "c-d", false) + _ = issues_model.SaveIssueContentHistory(dbCtx, 1, 10, 100, timeStampNow.Add(51), "c-e", false) - h1, _ := GetIssueContentHistoryByID(dbCtx, 1) + h1, _ := issues_model.GetIssueContentHistoryByID(dbCtx, 1) assert.EqualValues(t, 1, h1.ID) - m, _ := QueryIssueContentHistoryEditedCountMap(dbCtx, 10) + m, _ := issues_model.QueryIssueContentHistoryEditedCountMap(dbCtx, 10) assert.Equal(t, 3, m[0]) assert.Equal(t, 5, m[100]) @@ -48,31 +49,31 @@ func TestContentHistory(t *testing.T) { } _ = db.GetEngine(dbCtx).Sync2(&User{}) - list1, _ := FetchIssueContentHistoryList(dbCtx, 10, 0) + list1, _ := issues_model.FetchIssueContentHistoryList(dbCtx, 10, 0) assert.Len(t, list1, 3) - list2, _ := FetchIssueContentHistoryList(dbCtx, 10, 100) + list2, _ := issues_model.FetchIssueContentHistoryList(dbCtx, 10, 100) assert.Len(t, list2, 5) - hasHistory1, _ := HasIssueContentHistory(dbCtx, 10, 0) + hasHistory1, _ := issues_model.HasIssueContentHistory(dbCtx, 10, 0) assert.True(t, hasHistory1) - hasHistory2, _ := HasIssueContentHistory(dbCtx, 10, 1) + hasHistory2, _ := issues_model.HasIssueContentHistory(dbCtx, 10, 1) assert.False(t, hasHistory2) - h6, h6Prev, _ := GetIssueContentHistoryAndPrev(dbCtx, 6) + h6, h6Prev, _ := issues_model.GetIssueContentHistoryAndPrev(dbCtx, 6) assert.EqualValues(t, 6, h6.ID) assert.EqualValues(t, 5, h6Prev.ID) // soft-delete - _ = SoftDeleteIssueContentHistory(dbCtx, 5) - h6, h6Prev, _ = GetIssueContentHistoryAndPrev(dbCtx, 6) + _ = issues_model.SoftDeleteIssueContentHistory(dbCtx, 5) + h6, h6Prev, _ = issues_model.GetIssueContentHistoryAndPrev(dbCtx, 6) assert.EqualValues(t, 6, h6.ID) assert.EqualValues(t, 4, h6Prev.ID) // only keep 3 history revisions for comment_id=100, the first and the last should never be deleted - keepLimitedContentHistory(dbCtx, 10, 100, 3) - list1, _ = FetchIssueContentHistoryList(dbCtx, 10, 0) + issues_model.KeepLimitedContentHistory(dbCtx, 10, 100, 3) + list1, _ = issues_model.FetchIssueContentHistoryList(dbCtx, 10, 0) assert.Len(t, list1, 3) - list2, _ = FetchIssueContentHistoryList(dbCtx, 10, 100) + list2, _ = issues_model.FetchIssueContentHistoryList(dbCtx, 10, 100) assert.Len(t, list2, 3) assert.EqualValues(t, 8, list2[0].HistoryID) assert.EqualValues(t, 7, list2[1].HistoryID) diff --git a/models/issue_dependency.go b/models/issues/dependency.go similarity index 59% rename from models/issue_dependency.go rename to models/issues/dependency.go index af40aa45d3..d664c0758e 100644 --- a/models/issue_dependency.go +++ b/models/issues/dependency.go @@ -2,16 +2,95 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" + "fmt" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/timeutil" ) +// ErrDependencyExists represents a "DependencyAlreadyExists" kind of error. +type ErrDependencyExists struct { + IssueID int64 + DependencyID int64 +} + +// IsErrDependencyExists checks if an error is a ErrDependencyExists. +func IsErrDependencyExists(err error) bool { + _, ok := err.(ErrDependencyExists) + return ok +} + +func (err ErrDependencyExists) Error() string { + return fmt.Sprintf("issue dependency does already exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) +} + +// ErrDependencyNotExists represents a "DependencyAlreadyExists" kind of error. +type ErrDependencyNotExists struct { + IssueID int64 + DependencyID int64 +} + +// IsErrDependencyNotExists checks if an error is a ErrDependencyExists. +func IsErrDependencyNotExists(err error) bool { + _, ok := err.(ErrDependencyNotExists) + return ok +} + +func (err ErrDependencyNotExists) Error() string { + return fmt.Sprintf("issue dependency does not exist [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) +} + +// ErrCircularDependency represents a "DependencyCircular" kind of error. +type ErrCircularDependency struct { + IssueID int64 + DependencyID int64 +} + +// IsErrCircularDependency checks if an error is a ErrCircularDependency. +func IsErrCircularDependency(err error) bool { + _, ok := err.(ErrCircularDependency) + return ok +} + +func (err ErrCircularDependency) Error() string { + return fmt.Sprintf("circular dependencies exists (two issues blocking each other) [issue id: %d, dependency id: %d]", err.IssueID, err.DependencyID) +} + +// ErrDependenciesLeft represents an error where the issue you're trying to close still has dependencies left. +type ErrDependenciesLeft struct { + IssueID int64 +} + +// IsErrDependenciesLeft checks if an error is a ErrDependenciesLeft. +func IsErrDependenciesLeft(err error) bool { + _, ok := err.(ErrDependenciesLeft) + return ok +} + +func (err ErrDependenciesLeft) Error() string { + return fmt.Sprintf("issue has open dependencies [issue id: %d]", err.IssueID) +} + +// ErrUnknownDependencyType represents an error where an unknown dependency type was passed +type ErrUnknownDependencyType struct { + Type DependencyType +} + +// IsErrUnknownDependencyType checks if an error is ErrUnknownDependencyType +func IsErrUnknownDependencyType(err error) bool { + _, ok := err.(ErrUnknownDependencyType) + return ok +} + +func (err ErrUnknownDependencyType) Error() string { + return fmt.Sprintf("unknown dependency type [type: %d]", err.Type) +} + // IssueDependency represents an issue dependency type IssueDependency struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/issue_dependency_test.go b/models/issues/dependency_test.go similarity index 51% rename from models/issue_dependency_test.go rename to models/issues/dependency_test.go index 345a9077cd..3ea0b4ff5c 100644 --- a/models/issue_dependency_test.go +++ b/models/issues/dependency_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -21,42 +22,42 @@ func TestCreateIssueDependency(t *testing.T) { user1, err := user_model.GetUserByID(1) assert.NoError(t, err) - issue1, err := GetIssueByID(1) + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) assert.NoError(t, err) - issue2, err := GetIssueByID(2) + issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) assert.NoError(t, err) // Create a dependency and check if it was successful - err = CreateIssueDependency(user1, issue1, issue2) + err = issues_model.CreateIssueDependency(user1, issue1, issue2) assert.NoError(t, err) // Do it again to see if it will check if the dependency already exists - err = CreateIssueDependency(user1, issue1, issue2) + err = issues_model.CreateIssueDependency(user1, issue1, issue2) assert.Error(t, err) - assert.True(t, IsErrDependencyExists(err)) + assert.True(t, issues_model.IsErrDependencyExists(err)) // Check for circular dependencies - err = CreateIssueDependency(user1, issue2, issue1) + err = issues_model.CreateIssueDependency(user1, issue2, issue1) assert.Error(t, err) - assert.True(t, IsErrCircularDependency(err)) + assert.True(t, issues_model.IsErrCircularDependency(err)) - _ = unittest.AssertExistsAndLoadBean(t, &Comment{Type: CommentTypeAddDependency, PosterID: user1.ID, IssueID: issue1.ID}) + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddDependency, PosterID: user1.ID, IssueID: issue1.ID}) // Check if dependencies left is correct - left, err := IssueNoDependenciesLeft(db.DefaultContext, issue1) + left, err := issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) assert.NoError(t, err) assert.False(t, left) // Close #2 and check again - _, err = ChangeIssueStatus(db.DefaultContext, issue2, user1, true) + _, err = issues_model.ChangeIssueStatus(db.DefaultContext, issue2, user1, true) assert.NoError(t, err) - left, err = IssueNoDependenciesLeft(db.DefaultContext, issue1) + left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) assert.NoError(t, err) assert.True(t, left) // Test removing the dependency - err = RemoveIssueDependency(user1, issue1, issue2, DependencyTypeBlockedBy) + err = issues_model.RemoveIssueDependency(user1, issue1, issue2, issues_model.DependencyTypeBlockedBy) assert.NoError(t, err) } diff --git a/models/issue.go b/models/issues/issue.go similarity index 89% rename from models/issue.go rename to models/issues/issue.go index a22c115523..0f4af3e84f 100644 --- a/models/issue.go +++ b/models/issues/issue.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -16,7 +16,6 @@ import ( admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/foreignreference" - issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -29,7 +28,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/references" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/storage" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -38,6 +36,71 @@ import ( "xorm.io/xorm" ) +// ErrIssueNotExist represents a "IssueNotExist" kind of error. +type ErrIssueNotExist struct { + ID int64 + RepoID int64 + Index int64 +} + +// IsErrIssueNotExist checks if an error is a ErrIssueNotExist. +func IsErrIssueNotExist(err error) bool { + _, ok := err.(ErrIssueNotExist) + return ok +} + +func (err ErrIssueNotExist) Error() string { + return fmt.Sprintf("issue does not exist [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) +} + +// ErrIssueIsClosed represents a "IssueIsClosed" kind of error. +type ErrIssueIsClosed struct { + ID int64 + RepoID int64 + Index int64 +} + +// IsErrIssueIsClosed checks if an error is a ErrIssueNotExist. +func IsErrIssueIsClosed(err error) bool { + _, ok := err.(ErrIssueIsClosed) + return ok +} + +func (err ErrIssueIsClosed) Error() string { + return fmt.Sprintf("issue is closed [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) +} + +// ErrNewIssueInsert is used when the INSERT statement in newIssue fails +type ErrNewIssueInsert struct { + OriginalError error +} + +// IsErrNewIssueInsert checks if an error is a ErrNewIssueInsert. +func IsErrNewIssueInsert(err error) bool { + _, ok := err.(ErrNewIssueInsert) + return ok +} + +func (err ErrNewIssueInsert) Error() string { + return err.OriginalError.Error() +} + +// ErrIssueWasClosed is used when close a closed issue +type ErrIssueWasClosed struct { + ID int64 + Index int64 +} + +// IsErrIssueWasClosed checks if an error is a ErrIssueWasClosed. +func IsErrIssueWasClosed(err error) bool { + _, ok := err.(ErrIssueWasClosed) + return ok +} + +func (err ErrIssueWasClosed) Error() string { + return fmt.Sprintf("Issue [%d] %d was already closed", err.ID, err.Index) +} + // Issue represents an issue or pull request of repository. type Issue struct { ID int64 `xorm:"pk autoincr"` @@ -47,14 +110,14 @@ type Issue struct { PosterID int64 `xorm:"INDEX"` Poster *user_model.User `xorm:"-"` OriginalAuthor string - OriginalAuthorID int64 `xorm:"index"` - Title string `xorm:"name"` - Content string `xorm:"LONGTEXT"` - RenderedContent string `xorm:"-"` - Labels []*Label `xorm:"-"` - MilestoneID int64 `xorm:"INDEX"` - Milestone *issues_model.Milestone `xorm:"-"` - Project *project_model.Project `xorm:"-"` + OriginalAuthorID int64 `xorm:"index"` + Title string `xorm:"name"` + Content string `xorm:"LONGTEXT"` + RenderedContent string `xorm:"-"` + Labels []*Label `xorm:"-"` + MilestoneID int64 `xorm:"INDEX"` + Milestone *Milestone `xorm:"-"` + Project *project_model.Project `xorm:"-"` Priority int AssigneeID int64 `xorm:"-"` Assignee *user_model.User `xorm:"-"` @@ -73,7 +136,7 @@ type Issue struct { Attachments []*repo_model.Attachment `xorm:"-"` Comments []*Comment `xorm:"-"` - Reactions issues_model.ReactionList `xorm:"-"` + Reactions ReactionList `xorm:"-"` TotalTrackedTime int64 `xorm:"-"` Assignees []*user_model.User `xorm:"-"` ForeignReference *foreignreference.ForeignReference `xorm:"-"` @@ -107,7 +170,8 @@ func init() { db.RegisterModel(new(IssueIndex)) } -func (issue *Issue) loadTotalTimes(ctx context.Context) (err error) { +// LoadTotalTimes load total tracked time +func (issue *Issue) LoadTotalTimes(ctx context.Context) (err error) { opts := FindTrackedTimesOptions{IssueID: issue.ID} issue.TotalTrackedTime, err = opts.toSession(db.GetEngine(ctx)).SumInt(&TrackedTime{}, "time") if err != nil { @@ -237,7 +301,7 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) { if issue.Reactions != nil { return nil } - reactions, _, err := issues_model.FindReactions(ctx, issues_model.FindReactionsOptions{ + reactions, _, err := FindReactions(ctx, FindReactionsOptions{ IssueID: issue.ID, }) if err != nil { @@ -247,7 +311,7 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) { return err } // Load reaction user data - if _, err := issues_model.ReactionList(reactions).LoadUsers(ctx, issue.Repo); err != nil { + if _, err := ReactionList(reactions).LoadUsers(ctx, issue.Repo); err != nil { return err } @@ -292,15 +356,16 @@ func (issue *Issue) loadForeignReference(ctx context.Context) (err error) { func (issue *Issue) loadMilestone(ctx context.Context) (err error) { if (issue.Milestone == nil || issue.Milestone.ID != issue.MilestoneID) && issue.MilestoneID > 0 { - issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID) - if err != nil && !issues_model.IsErrMilestoneNotExist(err) { + issue.Milestone, err = GetMilestoneByRepoID(ctx, issue.RepoID, issue.MilestoneID) + if err != nil && !IsErrMilestoneNotExist(err) { return fmt.Errorf("getMilestoneByRepoID [repo_id: %d, milestone_id: %d]: %v", issue.RepoID, issue.MilestoneID, err) } } return nil } -func (issue *Issue) loadAttributes(ctx context.Context) (err error) { +// LoadAttributes loads the attribute of this issue. +func (issue *Issue) LoadAttributes(ctx context.Context) (err error) { if err = issue.LoadRepo(ctx); err != nil { return } @@ -345,7 +410,7 @@ func (issue *Issue) loadAttributes(ctx context.Context) (err error) { return err } if issue.isTimetrackerEnabled(ctx) { - if err = issue.loadTotalTimes(ctx); err != nil { + if err = issue.LoadTotalTimes(ctx); err != nil { return err } } @@ -357,11 +422,6 @@ func (issue *Issue) loadAttributes(ctx context.Context) (err error) { return issue.loadReactions(ctx) } -// LoadAttributes loads the attribute of this issue. -func (issue *Issue) LoadAttributes() error { - return issue.loadAttributes(db.DefaultContext) -} - // LoadMilestone load milestone of this issue. func (issue *Issue) LoadMilestone() error { return issue.loadMilestone(db.DefaultContext) @@ -590,15 +650,6 @@ func ReplaceIssueLabels(issue *Issue, labels []*Label, doer *user_model.User) (e return committer.Commit() } -// ReadBy sets issue to be read by given user. -func (issue *Issue) ReadBy(ctx context.Context, userID int64) error { - if err := UpdateIssueUserByRead(userID, issue.ID); err != nil { - return err - } - - return setIssueNotificationStatusReadIfUnread(ctx, userID, issue.ID) -} - // UpdateIssueCols updates cols of issue func UpdateIssueCols(ctx context.Context, issue *Issue, cols ...string) error { if _, err := db.GetEngine(ctx).ID(issue.ID).Cols(cols...).Update(issue); err != nil { @@ -609,7 +660,7 @@ func UpdateIssueCols(ctx context.Context, issue *Issue, cols ...string) error { func changeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isClosed, isMergePull bool) (*Comment, error) { // Reload the issue - currentIssue, err := getIssueByID(ctx, issue.ID) + currentIssue, err := GetIssueByID(ctx, issue.ID) if err != nil { return nil, err } @@ -666,7 +717,7 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use // Update issue count of milestone if issue.MilestoneID > 0 { - if err := issues_model.UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil { + if err := UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil { return nil, err } } @@ -730,7 +781,7 @@ func ChangeIssueTitle(issue *Issue, doer *user_model.User, oldTitle string) (err if _, err = CreateCommentCtx(ctx, opts); err != nil { return fmt.Errorf("createComment: %v", err) } - if err = issue.addCrossReferences(ctx, doer, true); err != nil { + if err = issue.AddCrossReferences(ctx, doer, true); err != nil { return err } @@ -772,7 +823,7 @@ func ChangeIssueRef(issue *Issue, doer *user_model.User, oldRef string) (err err // AddDeletePRBranchComment adds delete branch comment for pull request issue func AddDeletePRBranchComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issueID int64, branchName string) error { - issue, err := getIssueByID(ctx, issueID) + issue, err := GetIssueByID(ctx, issueID) if err != nil { return err } @@ -815,12 +866,12 @@ func ChangeIssueContent(issue *Issue, doer *user_model.User, content string) (er } defer committer.Close() - hasContentHistory, err := issues_model.HasIssueContentHistory(ctx, issue.ID, 0) + hasContentHistory, err := HasIssueContentHistory(ctx, issue.ID, 0) if err != nil { return fmt.Errorf("HasIssueContentHistory: %v", err) } if !hasContentHistory { - if err = issues_model.SaveIssueContentHistory(ctx, issue.PosterID, issue.ID, 0, + if err = SaveIssueContentHistory(ctx, issue.PosterID, issue.ID, 0, issue.CreatedUnix, issue.Content, true); err != nil { return fmt.Errorf("SaveIssueContentHistory: %v", err) } @@ -832,12 +883,12 @@ func ChangeIssueContent(issue *Issue, doer *user_model.User, content string) (er return fmt.Errorf("UpdateIssueCols: %v", err) } - if err = issues_model.SaveIssueContentHistory(ctx, doer.ID, issue.ID, 0, + if err = SaveIssueContentHistory(ctx, doer.ID, issue.ID, 0, timeutil.TimeStampNow(), issue.Content, false); err != nil { return fmt.Errorf("SaveIssueContentHistory: %v", err) } - if err = issue.addCrossReferences(ctx, doer, true); err != nil { + if err = issue.AddCrossReferences(ctx, doer, true); err != nil { return fmt.Errorf("addCrossReferences: %v", err) } @@ -907,13 +958,14 @@ type NewIssueOptions struct { IsPull bool } -func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) (err error) { +// NewIssueWithIndex creates issue with given index +func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssueOptions) (err error) { e := db.GetEngine(ctx) opts.Issue.Title = strings.TrimSpace(opts.Issue.Title) if opts.Issue.MilestoneID > 0 { - milestone, err := issues_model.GetMilestoneByRepoID(ctx, opts.Issue.RepoID, opts.Issue.MilestoneID) - if err != nil && !issues_model.IsErrMilestoneNotExist(err) { + milestone, err := GetMilestoneByRepoID(ctx, opts.Issue.RepoID, opts.Issue.MilestoneID) + if err != nil && !IsErrMilestoneNotExist(err) { return fmt.Errorf("getMilestoneByID: %v", err) } @@ -937,7 +989,7 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) } if opts.Issue.MilestoneID > 0 { - if err := issues_model.UpdateMilestoneCounters(ctx, opts.Issue.MilestoneID); err != nil { + if err := UpdateMilestoneCounters(ctx, opts.Issue.MilestoneID); err != nil { return err } @@ -987,7 +1039,7 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) } } - if err = newIssueUsers(ctx, opts.Repo, opts.Issue); err != nil { + if err = NewIssueUsers(ctx, opts.Repo, opts.Issue); err != nil { return err } @@ -1004,36 +1056,11 @@ func newIssue(ctx context.Context, doer *user_model.User, opts NewIssueOptions) } } } - if err = opts.Issue.loadAttributes(ctx); err != nil { + if err = opts.Issue.LoadAttributes(ctx); err != nil { return err } - return opts.Issue.addCrossReferences(ctx, doer, false) -} - -// RecalculateIssueIndexForRepo create issue_index for repo if not exist and -// update it based on highest index of existing issues assigned to a repo -func RecalculateIssueIndexForRepo(repoID int64) error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err := db.UpsertResourceIndex(db.GetEngine(ctx), "issue_index", repoID); err != nil { - return err - } - - var max int64 - if _, err := db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil { - return err - } - - if _, err := db.GetEngine(ctx).Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil { - return err - } - - return committer.Commit() + return opts.Issue.AddCrossReferences(ctx, doer, false) } // NewIssue creates new issue with labels for repository. @@ -1051,13 +1078,13 @@ func NewIssue(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids } defer committer.Close() - if err = newIssue(ctx, issue.Poster, NewIssueOptions{ + if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ Repo: repo, Issue: issue, LabelIDs: labelIDs, Attachments: uuids, }); err != nil { - if IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { return err } return fmt.Errorf("newIssue: %v", err) @@ -1114,10 +1141,11 @@ func GetIssueWithAttrsByIndex(repoID, index int64) (*Issue, error) { if err != nil { return nil, err } - return issue, issue.LoadAttributes() + return issue, issue.LoadAttributes(db.DefaultContext) } -func getIssueByID(ctx context.Context, id int64) (*Issue, error) { +// GetIssueByID returns an issue by given ID. +func GetIssueByID(ctx context.Context, id int64) (*Issue, error) { issue := new(Issue) has, err := db.GetEngine(ctx).ID(id).Get(issue) if err != nil { @@ -1130,16 +1158,11 @@ func getIssueByID(ctx context.Context, id int64) (*Issue, error) { // GetIssueWithAttrsByID returns an issue with attributes by given ID. func GetIssueWithAttrsByID(id int64) (*Issue, error) { - issue, err := getIssueByID(db.DefaultContext, id) + issue, err := GetIssueByID(db.DefaultContext, id) if err != nil { return nil, err } - return issue, issue.loadAttributes(db.DefaultContext) -} - -// GetIssueByID returns an issue by given ID. -func GetIssueByID(id int64) (*Issue, error) { - return getIssueByID(db.DefaultContext, id) + return issue, issue.LoadAttributes(db.DefaultContext) } // GetIssuesByIDs return issues with the given IDs. @@ -1156,7 +1179,7 @@ func GetIssueIDsByRepoID(ctx context.Context, repoID int64) ([]int64, error) { } // IssuesOptions represents options of an issue. -type IssuesOptions struct { +type IssuesOptions struct { //nolint db.ListOptions RepoID int64 // overwrites RepoCond if not 0 RepoCond builder.Cond @@ -1534,7 +1557,7 @@ func GetParticipantsIDsByIssueID(issueID int64) ([]int64, error) { // IsUserParticipantsOfIssue return true if user is participants of an issue func IsUserParticipantsOfIssue(user *user_model.User, issue *Issue) bool { - userIDs, err := issue.getParticipantIDsByIssue(db.DefaultContext) + userIDs, err := issue.GetParticipantIDsByIssue(db.DefaultContext) if err != nil { log.Error(err.Error()) return false @@ -1577,17 +1600,6 @@ const ( FilterModeYourRepositories ) -func parseCountResult(results []map[string][]byte) int64 { - if len(results) == 0 { - return 0 - } - for _, result := range results[0] { - c, _ := strconv.ParseInt(string(result), 10, 64) - return c - } - return 0 -} - // IssueStatsOptions contains parameters accepted by GetIssueStats. type IssueStatsOptions struct { RepoID int64 @@ -1602,14 +1614,15 @@ type IssueStatsOptions struct { } const ( + // MaxQueryParameters represents the max query parameters // When queries are broken down in parts because of the number // of parameters, attempt to break by this amount - maxQueryParameters = 300 + MaxQueryParameters = 300 ) // GetIssueStats returns issue statistic information by given conditions. func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) { - if len(opts.IssueIDs) <= maxQueryParameters { + if len(opts.IssueIDs) <= MaxQueryParameters { return getIssueStatsChunk(opts, opts.IssueIDs) } @@ -1619,7 +1632,7 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) { // ids in a temporary table and join from them. accum := &IssueStats{} for i := 0; i < len(opts.IssueIDs); { - chunk := i + maxQueryParameters + chunk := i + MaxQueryParameters if chunk > len(opts.IssueIDs) { chunk = len(opts.IssueIDs) } @@ -1950,7 +1963,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment } // Reload the issue - currentIssue, err := getIssueByID(ctx, issue.ID) + currentIssue, err := GetIssueByID(ctx, issue.ID) if err != nil { return nil, false, err } @@ -1985,7 +1998,7 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment } } - if err := issue.addCrossReferences(ctx, doer, true); err != nil { + if err := issue.AddCrossReferences(ctx, doer, true); err != nil { return nil, false, err } return statusChangeComment, titleChanged, committer.Commit() @@ -2016,22 +2029,8 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *us return committer.Commit() } -// DeleteIssue deletes the issue -func DeleteIssue(issue *Issue) error { - ctx, committer, err := db.TxContext() - if err != nil { - return err - } - defer committer.Close() - - if err := deleteIssue(ctx, issue); err != nil { - return err - } - - return committer.Commit() -} - -func deleteInIssue(ctx context.Context, issueID int64, beans ...interface{}) error { +// DeleteInIssue delete records in beans with external key issue_id = ? +func DeleteInIssue(ctx context.Context, issueID int64, beans ...interface{}) error { e := db.GetEngine(ctx) for _, bean := range beans { if _, err := e.In("issue_id", issueID).Delete(bean); err != nil { @@ -2041,103 +2040,14 @@ func deleteInIssue(ctx context.Context, issueID int64, beans ...interface{}) err return nil } -func deleteIssue(ctx context.Context, issue *Issue) error { - e := db.GetEngine(ctx) - if _, err := e.ID(issue.ID).NoAutoCondition().Delete(issue); err != nil { - return err - } - - if issue.IsPull { - if _, err := e.ID(issue.RepoID).Decr("num_pulls").Update(new(repo_model.Repository)); err != nil { - return err - } - if issue.IsClosed { - if _, err := e.ID(issue.RepoID).Decr("num_closed_pulls").Update(new(repo_model.Repository)); err != nil { - return err - } - } - } else { - if _, err := e.ID(issue.RepoID).Decr("num_issues").Update(new(repo_model.Repository)); err != nil { - return err - } - if issue.IsClosed { - if _, err := e.ID(issue.RepoID).Decr("num_closed_issues").Update(new(repo_model.Repository)); err != nil { - return err - } - } - } - - // delete actions assigned to this issue - subQuery := builder.Select("`id`"). - From("`comment`"). - Where(builder.Eq{"`issue_id`": issue.ID}) - if _, err := e.In("comment_id", subQuery).Delete(&Action{}); err != nil { - return err - } - - if _, err := e.Table("action").Where("repo_id = ?", issue.RepoID). - In("op_type", ActionCreateIssue, ActionCreatePullRequest). - Where("content LIKE ?", strconv.FormatInt(issue.ID, 10)+"|%"). - Delete(&Action{}); err != nil { - return err - } - - // find attachments related to this issue and remove them - var attachments []*repo_model.Attachment - if err := e.In("issue_id", issue.ID).Find(&attachments); err != nil { - return err - } - - for i := range attachments { - admin_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", attachments[i].RelativePath()) - } - - // delete all database data still assigned to this issue - if err := deleteInIssue(ctx, issue.ID, - &issues_model.ContentHistory{}, - &Comment{}, - &IssueLabel{}, - &IssueDependency{}, - &IssueAssignees{}, - &IssueUser{}, - &Notification{}, - &issues_model.Reaction{}, - &IssueWatch{}, - &Stopwatch{}, - &TrackedTime{}, - &project_model.ProjectIssue{}, - &repo_model.Attachment{}, - &PullRequest{}, - ); err != nil { - return err - } - - // References to this issue in other issues - if _, err := e.In("ref_issue_id", issue.ID).Delete(&Comment{}); err != nil { - return err - } - - // Delete dependencies for issues in other repositories - if _, err := e.In("dependency_id", issue.ID).Delete(&IssueDependency{}); err != nil { - return err - } - - // delete from dependent issues - if _, err := e.In("dependent_issue_id", issue.ID).Delete(&Comment{}); err != nil { - return err - } - - return nil -} - // DependencyInfo represents high level information about an issue which is a dependency of another issue. type DependencyInfo struct { Issue `xorm:"extends"` repo_model.Repository `xorm:"extends"` } -// getParticipantIDsByIssue returns all userIDs who are participated in comments of an issue and issue author -func (issue *Issue) getParticipantIDsByIssue(ctx context.Context) ([]int64, error) { +// GetParticipantIDsByIssue returns all userIDs who are participated in comments of an issue and issue author +func (issue *Issue) GetParticipantIDsByIssue(ctx context.Context) ([]int64, error) { if issue == nil { return nil, nil } @@ -2196,9 +2106,9 @@ func (issue *Issue) BlockingDependencies(ctx context.Context) (issueDeps []*Depe func updateIssueClosedNum(ctx context.Context, issue *Issue) (err error) { if issue.IsPull { - err = repoStatsCorrectNumClosed(ctx, issue.RepoID, true, "num_closed_pulls") + err = repo_model.StatsCorrectNumClosed(ctx, issue.RepoID, true, "num_closed_pulls") } else { - err = repoStatsCorrectNumClosed(ctx, issue.RepoID, false, "num_closed_issues") + err = repo_model.StatsCorrectNumClosed(ctx, issue.RepoID, false, "num_closed_issues") } return } @@ -2363,6 +2273,17 @@ func UpdateIssuesMigrationsByType(gitServiceType api.GitServiceType, originalAut return err } +func migratedIssueCond(tp api.GitServiceType) builder.Cond { + return builder.In("issue_id", + builder.Select("issue.id"). + From("issue"). + InnerJoin("repository", "issue.repo_id = repository.id"). + Where(builder.Eq{ + "repository.original_service_type": tp, + }), + ) +} + // UpdateReactionsMigrationsByType updates all migrated repositories' reactions from gitServiceType to replace originalAuthorID to posterID func UpdateReactionsMigrationsByType(gitServiceType api.GitServiceType, originalAuthorID string, userID int64) error { _, err := db.GetEngine(db.DefaultContext).Table("reaction"). @@ -2376,13 +2297,14 @@ func UpdateReactionsMigrationsByType(gitServiceType api.GitServiceType, original return err } -func deleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths []string, err error) { +// DeleteIssuesByRepoID deletes issues by repositories id +func DeleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths []string, err error) { deleteCond := builder.Select("id").From("issue").Where(builder.Eq{"issue.repo_id": repoID}) sess := db.GetEngine(ctx) // Delete content histories if _, err = sess.In("issue_id", deleteCond). - Delete(&issues_model.ContentHistory{}); err != nil { + Delete(&ContentHistory{}); err != nil { return } @@ -2410,7 +2332,7 @@ func deleteIssuesByRepoID(ctx context.Context, repoID int64) (attachmentPaths [] } if _, err = sess.In("issue_id", deleteCond). - Delete(&issues_model.Reaction{}); err != nil { + Delete(&Reaction{}); err != nil { return } @@ -2477,3 +2399,50 @@ func (issue *Issue) GetExternalName() string { return issue.OriginalAuthor } // GetExternalID ExternalUserRemappable interface func (issue *Issue) GetExternalID() int64 { return issue.OriginalAuthorID } + +// CountOrphanedIssues count issues without a repo +func CountOrphanedIssues() (int64, error) { + return db.GetEngine(db.DefaultContext).Table("issue"). + Join("LEFT", "repository", "issue.repo_id=repository.id"). + Where(builder.IsNull{"repository.id"}). + Select("COUNT(`issue`.`id`)"). + Count() +} + +// DeleteOrphanedIssues delete issues without a repo +func DeleteOrphanedIssues() error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + var ids []int64 + + if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id"). + Join("LEFT", "repository", "issue.repo_id=repository.id"). + Where(builder.IsNull{"repository.id"}).GroupBy("issue.repo_id"). + Find(&ids); err != nil { + return err + } + + var attachmentPaths []string + for i := range ids { + paths, err := DeleteIssuesByRepoID(ctx, ids[i]) + if err != nil { + return err + } + attachmentPaths = append(attachmentPaths, paths...) + } + + if err := committer.Commit(); err != nil { + return err + } + committer.Close() + + // Remove issue attachment files. + for i := range attachmentPaths { + admin_model.RemoveAllWithNotice(db.DefaultContext, "Delete issue attachment", attachmentPaths[i]) + } + return nil +} diff --git a/models/issues/issue_index.go b/models/issues/issue_index.go new file mode 100644 index 0000000000..100e814317 --- /dev/null +++ b/models/issues/issue_index.go @@ -0,0 +1,32 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package issues + +import "code.gitea.io/gitea/models/db" + +// RecalculateIssueIndexForRepo create issue_index for repo if not exist and +// update it based on highest index of existing issues assigned to a repo +func RecalculateIssueIndexForRepo(repoID int64) error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + if err := db.UpsertResourceIndex(ctx, "issue_index", repoID); err != nil { + return err + } + + var max int64 + if _, err := db.GetEngine(ctx).Select(" MAX(`index`)").Table("issue").Where("repo_id=?", repoID).Get(&max); err != nil { + return err + } + + if _, err := db.GetEngine(ctx).Exec("UPDATE `issue_index` SET max_index=? WHERE group_id=?", max, repoID); err != nil { + return err + } + + return committer.Commit() +} diff --git a/models/issue_list.go b/models/issues/issue_list.go similarity index 96% rename from models/issue_list.go rename to models/issues/issue_list.go index a5fc095e12..20e9949b66 100644 --- a/models/issue_list.go +++ b/models/issues/issue_list.go @@ -2,14 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" "fmt" "code.gitea.io/gitea/models/db" - issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" @@ -20,11 +19,6 @@ import ( // IssueList defines a list of issues type IssueList []*Issue -const ( - // default variables number on IN () in SQL - defaultMaxInSize = 50 -) - // get the repo IDs to be loaded later, these IDs are for issue.Repo and issue.PullRequest.HeadRepo func (issues IssueList) getRepoIDs() []int64 { repoIDs := make(map[int64]struct{}, len(issues)) @@ -48,7 +42,7 @@ func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Rep repoMaps := make(map[int64]*repo_model.Repository, len(repoIDs)) left := len(repoIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -102,7 +96,7 @@ func (issues IssueList) loadPosters(ctx context.Context) error { posterMaps := make(map[int64]*user_model.User, len(posterIDs)) left := len(posterIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -150,7 +144,7 @@ func (issues IssueList) loadLabels(ctx context.Context) error { issueIDs := issues.getIssueIDs() left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -205,10 +199,10 @@ func (issues IssueList) loadMilestones(ctx context.Context) error { return nil } - milestoneMaps := make(map[int64]*issues_model.Milestone, len(milestoneIDs)) + milestoneMaps := make(map[int64]*Milestone, len(milestoneIDs)) left := len(milestoneIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -242,7 +236,7 @@ func (issues IssueList) loadAssignees(ctx context.Context) error { issueIDs := issues.getIssueIDs() left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -298,7 +292,7 @@ func (issues IssueList) loadPullRequests(ctx context.Context) error { pullRequestMaps := make(map[int64]*PullRequest, len(issuesIDs)) left := len(issuesIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -342,7 +336,7 @@ func (issues IssueList) loadAttachments(ctx context.Context) (err error) { issuesIDs := issues.getIssueIDs() left := len(issuesIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -387,7 +381,7 @@ func (issues IssueList) loadComments(ctx context.Context, cond builder.Cond) (er issuesIDs := issues.getIssueIDs() left := len(issuesIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -443,7 +437,7 @@ func (issues IssueList) loadTotalTrackedTimes(ctx context.Context) (err error) { left := len(ids) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } diff --git a/models/issue_list_test.go b/models/issues/issue_list_test.go similarity index 71% rename from models/issue_list_test.go rename to models/issues/issue_list_test.go index 2916a7302f..6b978f9ae6 100644 --- a/models/issue_list_test.go +++ b/models/issues/issue_list_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" @@ -16,10 +17,10 @@ import ( func TestIssueList_LoadRepositories(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issueList := IssueList{ - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue), - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue), - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 4}).(*Issue), + issueList := issues_model.IssueList{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue), } repos, err := issueList.LoadRepositories() @@ -33,9 +34,9 @@ func TestIssueList_LoadRepositories(t *testing.T) { func TestIssueList_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) setting.Service.EnableTimetracking = true - issueList := IssueList{ - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue), - unittest.AssertExistsAndLoadBean(t, &Issue{ID: 4}).(*Issue), + issueList := issues_model.IssueList{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue), + unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue), } assert.NoError(t, issueList.LoadAttributes()) @@ -43,7 +44,7 @@ func TestIssueList_LoadAttributes(t *testing.T) { assert.EqualValues(t, issue.RepoID, issue.Repo.ID) for _, label := range issue.Labels { assert.EqualValues(t, issue.RepoID, label.RepoID) - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issue.ID, LabelID: label.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) } if issue.PosterID > 0 { assert.EqualValues(t, issue.PosterID, issue.Poster.ID) diff --git a/models/issue_lock.go b/models/issues/issue_lock.go similarity index 98% rename from models/issue_lock.go rename to models/issues/issue_lock.go index a122f618d0..7b52429ef7 100644 --- a/models/issue_lock.go +++ b/models/issues/issue_lock.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "code.gitea.io/gitea/models/db" diff --git a/models/issue_project.go b/models/issues/issue_project.go similarity index 99% rename from models/issue_project.go rename to models/issues/issue_project.go index 0f8c61977b..5e0a337f7d 100644 --- a/models/issue_project.go +++ b/models/issues/issue_project.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" diff --git a/models/issue_test.go b/models/issues/issue_test.go similarity index 73% rename from models/issue_test.go rename to models/issues/issue_test.go index 5b2f461a84..019e578da8 100644 --- a/models/issue_test.go +++ b/models/issues/issue_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "context" @@ -29,18 +29,18 @@ func TestIssue_ReplaceLabels(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(issueID int64, labelIDs []int64) { - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issueID}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}).(*issues_model.Issue) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - labels := make([]*Label, len(labelIDs)) + labels := make([]*issues_model.Label, len(labelIDs)) for i, labelID := range labelIDs { - labels[i] = unittest.AssertExistsAndLoadBean(t, &Label{ID: labelID, RepoID: repo.ID}).(*Label) + labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID, RepoID: repo.ID}).(*issues_model.Label) } - assert.NoError(t, ReplaceIssueLabels(issue, labels, doer)) - unittest.AssertCount(t, &IssueLabel{IssueID: issueID}, len(labelIDs)) + assert.NoError(t, issues_model.ReplaceIssueLabels(issue, labels, doer)) + unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issueID}, len(labelIDs)) for _, labelID := range labelIDs { - unittest.AssertExistsAndLoadBean(t, &IssueLabel{IssueID: issueID, LabelID: labelID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) } } @@ -52,15 +52,15 @@ func TestIssue_ReplaceLabels(t *testing.T) { func Test_GetIssueIDsByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - ids, err := GetIssueIDsByRepoID(db.DefaultContext, 1) + ids, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) assert.NoError(t, err) assert.Len(t, ids, 5) } func TestIssueAPIURL(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) - err := issue.LoadAttributes() + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + err := issue.LoadAttributes(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/issues/1", issue.APIURL()) @@ -69,7 +69,7 @@ func TestIssueAPIURL(t *testing.T) { func TestGetIssuesByIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(expectedIssueIDs, nonExistentIssueIDs []int64) { - issues, err := GetIssuesByIDs(db.DefaultContext, append(expectedIssueIDs, nonExistentIssueIDs...)) + issues, err := issues_model.GetIssuesByIDs(db.DefaultContext, append(expectedIssueIDs, nonExistentIssueIDs...)) assert.NoError(t, err) actualIssueIDs := make([]int64, len(issues)) for i, issue := range issues { @@ -85,9 +85,9 @@ func TestGetParticipantIDsByIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) checkParticipants := func(issueID int64, userIDs []int) { - issue, err := GetIssueByID(issueID) + issue, err := issues_model.GetIssueByID(db.DefaultContext, issueID) assert.NoError(t, err) - participants, err := issue.getParticipantIDsByIssue(db.DefaultContext) + participants, err := issue.GetParticipantIDsByIssue(db.DefaultContext) if assert.NoError(t, err) { participantsIDs := make([]int, len(participants)) for i, uid := range participants { @@ -117,16 +117,16 @@ func TestIssue_ClearLabels(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: test.issueID}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) - assert.NoError(t, ClearIssueLabels(issue, doer)) - unittest.AssertNotExistsBean(t, &IssueLabel{IssueID: test.issueID}) + assert.NoError(t, issues_model.ClearIssueLabels(issue, doer)) + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: test.issueID}) } } func TestUpdateIssueCols(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue) const newTitle = "New Title for unit test" issue.Title = newTitle @@ -135,10 +135,10 @@ func TestUpdateIssueCols(t *testing.T) { issue.Content = "This should have no effect" now := time.Now().Unix() - assert.NoError(t, UpdateIssueCols(db.DefaultContext, issue, "name")) + assert.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "name")) then := time.Now().Unix() - updatedIssue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) + updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}).(*issues_model.Issue) assert.EqualValues(t, newTitle, updatedIssue.Title) assert.EqualValues(t, prevContent, updatedIssue.Content) unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) @@ -147,18 +147,18 @@ func TestUpdateIssueCols(t *testing.T) { func TestIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) for _, test := range []struct { - Opts IssuesOptions + Opts issues_model.IssuesOptions ExpectedIssueIDs []int64 }{ { - IssuesOptions{ + issues_model.IssuesOptions{ AssigneeID: 1, SortType: "oldest", }, []int64{1, 6}, }, { - IssuesOptions{ + issues_model.IssuesOptions{ RepoCond: builder.In("repo_id", 1, 3), SortType: "oldest", ListOptions: db.ListOptions{ @@ -169,7 +169,7 @@ func TestIssues(t *testing.T) { []int64{1, 2, 3, 5}, }, { - IssuesOptions{ + issues_model.IssuesOptions{ LabelIDs: []int64{1}, ListOptions: db.ListOptions{ Page: 1, @@ -179,7 +179,7 @@ func TestIssues(t *testing.T) { []int64{2, 1}, }, { - IssuesOptions{ + issues_model.IssuesOptions{ LabelIDs: []int64{1, 2}, ListOptions: db.ListOptions{ Page: 1, @@ -189,7 +189,7 @@ func TestIssues(t *testing.T) { []int64{}, // issues with **both** label 1 and 2, none of these issues matches, TODO: add more tests }, } { - issues, err := Issues(&test.Opts) + issues, err := issues_model.Issues(&test.Opts) assert.NoError(t, err) if assert.Len(t, issues, len(test.ExpectedIssueIDs)) { for i, issue := range issues { @@ -202,16 +202,16 @@ func TestIssues(t *testing.T) { func TestGetUserIssueStats(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) for _, test := range []struct { - Opts UserIssueStatsOptions - ExpectedIssueStats IssueStats + Opts issues_model.UserIssueStatsOptions + ExpectedIssueStats issues_model.IssueStats }{ { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, RepoIDs: []int64{1}, - FilterMode: FilterModeAll, + FilterMode: issues_model.FilterModeAll, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 1, // 6 CreateCount: 1, // 6 @@ -220,13 +220,13 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, RepoIDs: []int64{1}, - FilterMode: FilterModeAll, + FilterMode: issues_model.FilterModeAll, IsClosed: true, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 0, CreateCount: 0, @@ -235,11 +235,11 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, - FilterMode: FilterModeAssign, + FilterMode: issues_model.FilterModeAssign, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 1, // 6 CreateCount: 1, // 6 @@ -248,11 +248,11 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, - FilterMode: FilterModeCreate, + FilterMode: issues_model.FilterModeCreate, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 1, // 6 CreateCount: 1, // 6 @@ -261,11 +261,11 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, - FilterMode: FilterModeMention, + FilterMode: issues_model.FilterModeMention, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 6 AssignCount: 1, // 6 CreateCount: 1, // 6 @@ -275,12 +275,12 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 1, - FilterMode: FilterModeCreate, + FilterMode: issues_model.FilterModeCreate, IssueIDs: []int64{1}, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 1, // 1 AssignCount: 1, // 1 CreateCount: 1, // 1 @@ -289,13 +289,13 @@ func TestGetUserIssueStats(t *testing.T) { }, }, { - UserIssueStatsOptions{ + issues_model.UserIssueStatsOptions{ UserID: 2, Org: unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization), Team: unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 7}).(*organization.Team), - FilterMode: FilterModeAll, + FilterMode: issues_model.FilterModeAll, }, - IssueStats{ + issues_model.IssueStats{ YourRepositoriesCount: 2, AssignCount: 1, CreateCount: 1, @@ -304,7 +304,7 @@ func TestGetUserIssueStats(t *testing.T) { }, } { t.Run(fmt.Sprintf("%#v", test.Opts), func(t *testing.T) { - stats, err := GetUserIssueStats(test.Opts) + stats, err := issues_model.GetUserIssueStats(test.Opts) if !assert.NoError(t, err) { return } @@ -315,31 +315,31 @@ func TestGetUserIssueStats(t *testing.T) { func TestIssue_loadTotalTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - ms, err := GetIssueByID(2) + ms, err := issues_model.GetIssueByID(db.DefaultContext, 2) assert.NoError(t, err) - assert.NoError(t, ms.loadTotalTimes(db.DefaultContext)) + assert.NoError(t, ms.LoadTotalTimes(db.DefaultContext)) assert.Equal(t, int64(3682), ms.TotalTrackedTime) } func TestIssue_SearchIssueIDsByKeyword(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - total, ids, err := SearchIssueIDsByKeyword(context.TODO(), "issue2", []int64{1}, 10, 0) + total, ids, err := issues_model.SearchIssueIDsByKeyword(context.TODO(), "issue2", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{2}, ids) - total, ids, err = SearchIssueIDsByKeyword(context.TODO(), "first", []int64{1}, 10, 0) + total, ids, err = issues_model.SearchIssueIDsByKeyword(context.TODO(), "first", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{1}, ids) - total, ids, err = SearchIssueIDsByKeyword(context.TODO(), "for", []int64{1}, 10, 0) + total, ids, err = issues_model.SearchIssueIDsByKeyword(context.TODO(), "for", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 5, total) assert.ElementsMatch(t, []int64{1, 2, 3, 5, 11}, ids) // issue1's comment id 2 - total, ids, err = SearchIssueIDsByKeyword(context.TODO(), "good", []int64{1}, 10, 0) + total, ids, err = issues_model.SearchIssueIDsByKeyword(context.TODO(), "good", []int64{1}, 10, 0) assert.NoError(t, err) assert.EqualValues(t, 1, total) assert.EqualValues(t, []int64{1}, ids) @@ -349,23 +349,23 @@ func TestGetRepoIDsForIssuesOptions(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) for _, test := range []struct { - Opts IssuesOptions + Opts issues_model.IssuesOptions ExpectedRepoIDs []int64 }{ { - IssuesOptions{ + issues_model.IssuesOptions{ AssigneeID: 2, }, []int64{3, 32}, }, { - IssuesOptions{ + issues_model.IssuesOptions{ RepoCond: builder.In("repo_id", 1, 2), }, []int64{1, 2}, }, } { - repoIDs, err := GetRepoIDsForIssuesOptions(&test.Opts, user) + repoIDs, err := issues_model.GetRepoIDsForIssuesOptions(&test.Opts, user) assert.NoError(t, err) if assert.Len(t, repoIDs, len(test.ExpectedRepoIDs)) { for i, repoID := range repoIDs { @@ -375,20 +375,20 @@ func TestGetRepoIDsForIssuesOptions(t *testing.T) { } } -func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *Issue { - var newIssue Issue +func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *issues_model.Issue { + var newIssue issues_model.Issue t.Run(title, func(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) - issue := Issue{ + issue := issues_model.Issue{ RepoID: repo.ID, PosterID: user.ID, Poster: user, Title: title, Content: content, } - err := NewIssue(repo, &issue, nil, nil) + err := issues_model.NewIssue(repo, &issue, nil, nil) assert.NoError(t, err) has, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Get(&newIssue) @@ -408,75 +408,23 @@ func TestIssue_InsertIssue(t *testing.T) { // there are 5 issues and max index is 5 on repository 1, so this one should 6 issue := testInsertIssue(t, "my issue1", "special issue's comments?", 6) - _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Delete(new(Issue)) + _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Delete(new(issues_model.Issue)) assert.NoError(t, err) issue = testInsertIssue(t, `my issue2, this is my son's love \n \r \ `, "special issue's '' comments?", 7) - _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Delete(new(Issue)) + _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Delete(new(issues_model.Issue)) assert.NoError(t, err) } -func TestIssue_DeleteIssue(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - issueIDs, err := GetIssueIDsByRepoID(db.DefaultContext, 1) - assert.NoError(t, err) - assert.EqualValues(t, 5, len(issueIDs)) - - issue := &Issue{ - RepoID: 1, - ID: issueIDs[2], - } - - err = DeleteIssue(issue) - assert.NoError(t, err) - issueIDs, err = GetIssueIDsByRepoID(db.DefaultContext, 1) - assert.NoError(t, err) - assert.EqualValues(t, 4, len(issueIDs)) - - // check attachment removal - attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 4) - assert.NoError(t, err) - issue, err = GetIssueByID(4) - assert.NoError(t, err) - err = DeleteIssue(issue) - assert.NoError(t, err) - assert.EqualValues(t, 2, len(attachments)) - for i := range attachments { - attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attachments[i].UUID) - assert.Error(t, err) - assert.True(t, repo_model.IsErrAttachmentNotExist(err)) - assert.Nil(t, attachment) - } - - // check issue dependencies - user, err := user_model.GetUserByID(1) - assert.NoError(t, err) - issue1, err := GetIssueByID(1) - assert.NoError(t, err) - issue2, err := GetIssueByID(2) - assert.NoError(t, err) - err = CreateIssueDependency(user, issue1, issue2) - assert.NoError(t, err) - left, err := IssueNoDependenciesLeft(db.DefaultContext, issue1) - assert.NoError(t, err) - assert.False(t, left) - err = DeleteIssue(&Issue{ID: 2}) - assert.NoError(t, err) - left, err = IssueNoDependenciesLeft(db.DefaultContext, issue1) - assert.NoError(t, err) - assert.True(t, left) -} - func TestIssue_ResolveMentions(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) testSuccess := func(owner, repo, doer string, mentions []string, expected []int64) { o := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: owner}).(*user_model.User) r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: o.ID, LowerName: repo}).(*repo_model.Repository) - issue := &Issue{RepoID: r.ID} + issue := &issues_model.Issue{RepoID: r.ID} d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer}).(*user_model.User) - resolved, err := ResolveIssueMentionsByVisibility(db.DefaultContext, issue, d, mentions) + resolved, err := issues_model.ResolveIssueMentionsByVisibility(db.DefaultContext, issue, d, mentions) assert.NoError(t, err) ids := make([]int64, len(resolved)) for i, user := range resolved { @@ -523,7 +471,7 @@ func TestCorrectIssueStats(t *testing.T) { // Each new issues will have a constant description "Bugs are nasty" // Which will be used later on. - issueAmount := maxQueryParameters + 10 + issueAmount := issues_model.MaxQueryParameters + 10 var wg sync.WaitGroup for i := 0; i < issueAmount; i++ { @@ -536,7 +484,7 @@ func TestCorrectIssueStats(t *testing.T) { wg.Wait() // Now we will get all issueID's that match the "Bugs are nasty" query. - total, ids, err := SearchIssueIDsByKeyword(context.TODO(), "Bugs are nasty", []int64{1}, issueAmount, 0) + total, ids, err := issues_model.SearchIssueIDsByKeyword(context.TODO(), "Bugs are nasty", []int64{1}, issueAmount, 0) // Just to be sure. assert.NoError(t, err) @@ -544,7 +492,7 @@ func TestCorrectIssueStats(t *testing.T) { // Now we will call the GetIssueStats with these IDs and if working, // get the correct stats back. - issueStats, err := GetIssueStats(&IssueStatsOptions{ + issueStats, err := issues_model.GetIssueStats(&issues_model.IssueStatsOptions{ RepoID: 1, IssueIDs: ids, }) @@ -556,19 +504,19 @@ func TestCorrectIssueStats(t *testing.T) { func TestIssueForeignReference(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 4}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue) assert.NotEqualValues(t, issue.Index, issue.ID) // make sure they are different to avoid false positive // it is fine for an issue to not have a foreign reference - err := issue.LoadAttributes() + err := issue.LoadAttributes(db.DefaultContext) assert.NoError(t, err) assert.Nil(t, issue.ForeignReference) var foreignIndex int64 = 12345 - _, err = GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex) + _, err = issues_model.GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex) assert.True(t, foreignreference.IsErrLocalIndexNotExist(err)) - _, err = db.GetEngine(db.DefaultContext).Insert(&foreignreference.ForeignReference{ + err = db.Insert(db.DefaultContext, &foreignreference.ForeignReference{ LocalIndex: issue.Index, ForeignIndex: strconv.FormatInt(foreignIndex, 10), RepoID: issue.RepoID, @@ -576,12 +524,12 @@ func TestIssueForeignReference(t *testing.T) { }) assert.NoError(t, err) - err = issue.LoadAttributes() + err = issue.LoadAttributes(db.DefaultContext) assert.NoError(t, err) assert.EqualValues(t, issue.ForeignReference.ForeignIndex, strconv.FormatInt(foreignIndex, 10)) - found, err := GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex) + found, err := issues_model.GetIssueByForeignIndex(context.Background(), issue.RepoID, foreignIndex) assert.NoError(t, err) assert.EqualValues(t, found.Index, issue.Index) } @@ -608,7 +556,7 @@ func TestLoadTotalTrackedTime(t *testing.T) { func TestCountIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - count, err := CountIssues(&IssuesOptions{}) + count, err := issues_model.CountIssues(&issues_model.IssuesOptions{}) assert.NoError(t, err) assert.EqualValues(t, 17, count) } diff --git a/models/issue_user.go b/models/issues/issue_user.go similarity index 94% rename from models/issue_user.go rename to models/issues/issue_user.go index 19c64094a1..f5d22589af 100644 --- a/models/issue_user.go +++ b/models/issues/issue_user.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -25,7 +25,8 @@ func init() { db.RegisterModel(new(IssueUser)) } -func newIssueUsers(ctx context.Context, repo *repo_model.Repository, issue *Issue) error { +// NewIssueUsers inserts an issue related users +func NewIssueUsers(ctx context.Context, repo *repo_model.Repository, issue *Issue) error { assignees, err := repo_model.GetRepoAssignees(ctx, repo) if err != nil { return fmt.Errorf("getAssignees: %v", err) diff --git a/models/issues/issue_user_test.go b/models/issues/issue_user_test.go new file mode 100644 index 0000000000..33e9f98ecc --- /dev/null +++ b/models/issues/issue_user_test.go @@ -0,0 +1,62 @@ +// Copyright 2017 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package issues_test + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + + "github.com/stretchr/testify/assert" +) + +func Test_NewIssueUsers(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) + newIssue := &issues_model.Issue{ + RepoID: repo.ID, + PosterID: 4, + Index: 6, + Title: "newTestIssueTitle", + Content: "newTestIssueContent", + } + + // artificially insert new issue + unittest.AssertSuccessfulInsert(t, newIssue) + + assert.NoError(t, issues_model.NewIssueUsers(db.DefaultContext, repo, newIssue)) + + // issue_user table should now have entries for new issue + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: newIssue.ID, UID: newIssue.PosterID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: newIssue.ID, UID: repo.OwnerID}) +} + +func TestUpdateIssueUserByRead(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + + assert.NoError(t, issues_model.UpdateIssueUserByRead(4, issue.ID)) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") + + assert.NoError(t, issues_model.UpdateIssueUserByRead(4, issue.ID)) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") + + assert.NoError(t, issues_model.UpdateIssueUserByRead(unittest.NonexistentID, unittest.NonexistentID)) +} + +func TestUpdateIssueUsersByMentions(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + + uids := []int64{2, 5} + assert.NoError(t, issues_model.UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids)) + for _, uid := range uids { + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: uid}, "is_mentioned=1") + } +} diff --git a/models/issue_watch.go b/models/issues/issue_watch.go similarity index 96% rename from models/issue_watch.go rename to models/issues/issue_watch.go index 9f41d36e19..bf907aa8fd 100644 --- a/models/issue_watch.go +++ b/models/issues/issue_watch.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -125,7 +125,8 @@ func CountIssueWatchers(ctx context.Context, issueID int64) (int64, error) { Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id").Count(new(IssueWatch)) } -func removeIssueWatchersByRepoID(ctx context.Context, userID, repoID int64) error { +// RemoveIssueWatchersByRepoID remove issue watchers by repoID +func RemoveIssueWatchersByRepoID(ctx context.Context, userID, repoID int64) error { _, err := db.GetEngine(ctx). Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", repoID). Where("`issue_watch`.user_id = ?", userID). diff --git a/models/issue_watch_test.go b/models/issues/issue_watch_test.go similarity index 53% rename from models/issue_watch_test.go rename to models/issues/issue_watch_test.go index b686196ae1..c6b6416d9b 100644 --- a/models/issue_watch_test.go +++ b/models/issues/issue_watch_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -16,28 +17,28 @@ import ( func TestCreateOrUpdateIssueWatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - assert.NoError(t, CreateOrUpdateIssueWatch(3, 1, true)) - iw := unittest.AssertExistsAndLoadBean(t, &IssueWatch{UserID: 3, IssueID: 1}).(*IssueWatch) + assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(3, 1, true)) + iw := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 3, IssueID: 1}).(*issues_model.IssueWatch) assert.True(t, iw.IsWatching) - assert.NoError(t, CreateOrUpdateIssueWatch(1, 1, false)) - iw = unittest.AssertExistsAndLoadBean(t, &IssueWatch{UserID: 1, IssueID: 1}).(*IssueWatch) + assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(1, 1, false)) + iw = unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 1, IssueID: 1}).(*issues_model.IssueWatch) assert.False(t, iw.IsWatching) } func TestGetIssueWatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - _, exists, err := GetIssueWatch(db.DefaultContext, 9, 1) + _, exists, err := issues_model.GetIssueWatch(db.DefaultContext, 9, 1) assert.True(t, exists) assert.NoError(t, err) - iw, exists, err := GetIssueWatch(db.DefaultContext, 2, 2) + iw, exists, err := issues_model.GetIssueWatch(db.DefaultContext, 2, 2) assert.True(t, exists) assert.NoError(t, err) assert.False(t, iw.IsWatching) - _, exists, err = GetIssueWatch(db.DefaultContext, 3, 1) + _, exists, err = issues_model.GetIssueWatch(db.DefaultContext, 3, 1) assert.False(t, exists) assert.NoError(t, err) } @@ -45,22 +46,22 @@ func TestGetIssueWatch(t *testing.T) { func TestGetIssueWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - iws, err := GetIssueWatchers(db.DefaultContext, 1, db.ListOptions{}) + iws, err := issues_model.GetIssueWatchers(db.DefaultContext, 1, db.ListOptions{}) assert.NoError(t, err) // Watcher is inactive, thus 0 assert.Len(t, iws, 0) - iws, err = GetIssueWatchers(db.DefaultContext, 2, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 2, db.ListOptions{}) assert.NoError(t, err) // Watcher is explicit not watching assert.Len(t, iws, 0) - iws, err = GetIssueWatchers(db.DefaultContext, 5, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 5, db.ListOptions{}) assert.NoError(t, err) // Issue has no Watchers assert.Len(t, iws, 0) - iws, err = GetIssueWatchers(db.DefaultContext, 7, db.ListOptions{}) + iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 7, db.ListOptions{}) assert.NoError(t, err) // Issue has one watcher assert.Len(t, iws, 1) diff --git a/models/issue_xref.go b/models/issues/issue_xref.go similarity index 93% rename from models/issue_xref.go rename to models/issues/issue_xref.go index 0c1623b5a4..f4380a02ec 100644 --- a/models/issue_xref.go +++ b/models/issues/issue_xref.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -55,15 +55,8 @@ func neuterCrossReferencesIds(ctx context.Context, ids []int64) error { return err } -// .___ -// | | ______ ________ __ ____ -// | |/ ___// ___/ | \_/ __ \ -// | |\___ \ \___ \| | /\ ___/ -// |___/____ >____ >____/ \___ > -// \/ \/ \/ -// - -func (issue *Issue) addCrossReferences(stdCtx context.Context, doer *user_model.User, removeOld bool) error { +// AddCrossReferences add cross repositories references. +func (issue *Issue) AddCrossReferences(stdCtx context.Context, doer *user_model.User, removeOld bool) error { var commentType CommentType if issue.IsPull { commentType = CommentTypePullRef @@ -237,15 +230,8 @@ func (issue *Issue) verifyReferencedIssue(stdCtx context.Context, ctx *crossRefe return refIssue, refAction, nil } -// _________ __ -// \_ ___ \ ____ _____ _____ ____ _____/ |_ -// / \ \/ / _ \ / \ / \_/ __ \ / \ __\ -// \ \___( <_> ) Y Y \ Y Y \ ___/| | \ | -// \______ /\____/|__|_| /__|_| /\___ >___| /__| -// \/ \/ \/ \/ \/ -// - -func (comment *Comment) addCrossReferences(stdCtx context.Context, doer *user_model.User, removeOld bool) error { +// AddCrossReferences add cross references +func (comment *Comment) AddCrossReferences(stdCtx context.Context, doer *user_model.User, removeOld bool) error { if comment.Type != CommentTypeCode && comment.Type != CommentTypeComment { return nil } @@ -280,7 +266,7 @@ func (comment *Comment) LoadRefIssue() (err error) { if comment.RefIssue != nil { return nil } - comment.RefIssue, err = GetIssueByID(comment.RefIssueID) + comment.RefIssue, err = GetIssueByID(db.DefaultContext, comment.RefIssueID) if err == nil { err = comment.RefIssue.LoadRepo(db.DefaultContext) } diff --git a/models/issue_xref_test.go b/models/issues/issue_xref_test.go similarity index 61% rename from models/issue_xref_test.go rename to models/issues/issue_xref_test.go index b4ad5b2708..6bb19d5328 100644 --- a/models/issue_xref_test.go +++ b/models/issues/issue_xref_test.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "fmt" "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -26,8 +27,8 @@ func TestXRef_AddCrossReferences(t *testing.T) { // PR to close issue #1 content := fmt.Sprintf("content2, closes #%d", itarget.Index) pr := testCreateIssue(t, 1, 2, "title2", content, true) - ref := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypePullRef, ref.Type) + ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypePullRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.True(t, ref.RefIsPull) assert.Equal(t, references.XRefActionCloses, ref.RefAction) @@ -35,8 +36,8 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Comment on PR to reopen issue #1 content = fmt.Sprintf("content2, reopens #%d", itarget.Index) c := testCreateComment(t, 1, 2, pr.ID, content) - ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}).(*Comment) - assert.Equal(t, CommentTypeCommentRef, ref.Type) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.True(t, ref.RefIsPull) assert.Equal(t, references.XRefActionReopens, ref.RefAction) @@ -44,8 +45,8 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Issue mentioning issue #1 content = fmt.Sprintf("content3, mentions #%d", itarget.Index) i := testCreateIssue(t, 1, 2, "title3", content, false) - ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypeIssueRef, ref.Type) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, pr.RepoID, ref.RefRepoID) assert.False(t, ref.RefIsPull) assert.Equal(t, references.XRefActionNone, ref.RefAction) @@ -56,8 +57,8 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Cross-reference to issue #4 by admin content = fmt.Sprintf("content5, mentions user3/repo3#%d", itarget.Index) i = testCreateIssue(t, 2, 1, "title5", content, false) - ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypeIssueRef, ref.Type) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, i.RepoID, ref.RefRepoID) assert.False(t, ref.RefIsPull) assert.Equal(t, references.XRefActionNone, ref.RefAction) @@ -65,7 +66,7 @@ func TestXRef_AddCrossReferences(t *testing.T) { // Cross-reference to issue #4 with no permission content = fmt.Sprintf("content6, mentions user3/repo3#%d", itarget.Index) i = testCreateIssue(t, 4, 5, "title6", content, false) - unittest.AssertNotExistsBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) + unittest.AssertNotExistsBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}) } func TestXRef_NeuterCrossReferences(t *testing.T) { @@ -77,16 +78,16 @@ func TestXRef_NeuterCrossReferences(t *testing.T) { // Issue mentioning issue #1 title := fmt.Sprintf("title2, mentions #%d", itarget.Index) i := testCreateIssue(t, 1, 2, title, "content2", false) - ref := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypeIssueRef, ref.Type) + ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, references.XRefActionNone, ref.RefAction) d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) i.Title = "title2, no mentions" - assert.NoError(t, ChangeIssueTitle(i, d, title)) + assert.NoError(t, issues_model.ChangeIssueTitle(i, d, title)) - ref = unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*Comment) - assert.Equal(t, CommentTypeIssueRef, ref.Type) + ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment) + assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type) assert.Equal(t, references.XRefActionNeutered, ref.RefAction) } @@ -98,25 +99,25 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { i1 := testCreateIssue(t, 1, 2, "title1", "content1", false) i2 := testCreateIssue(t, 1, 2, "title2", "content2", false) i3 := testCreateIssue(t, 1, 2, "title3", "content3", false) - _, err := ChangeIssueStatus(db.DefaultContext, i3, d, true) + _, err := issues_model.ChangeIssueStatus(db.DefaultContext, i3, d, true) assert.NoError(t, err) pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index)) - rp := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}).(*Comment) + rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}).(*issues_model.Comment) c1 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i2.Index)) - r1 := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}).(*Comment) + r1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}).(*issues_model.Comment) // Must be ignored c2 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("mentions #%d", i2.Index)) - unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c2.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c2.ID}) // Must be superseded by c4/r4 c3 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("reopens #%d", i3.Index)) - unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID}) c4 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index)) - r4 := unittest.AssertExistsAndLoadBean(t, &Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}).(*Comment) + r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}).(*issues_model.Comment) refs, err := pr.ResolveCrossReferences(db.DefaultContext) assert.NoError(t, err) @@ -126,13 +127,13 @@ func TestXRef_ResolveCrossReferences(t *testing.T) { assert.Equal(t, r4.ID, refs[2].ID, "bad ref r4: %+v", refs[2]) } -func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *Issue { +func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *issues_model.Issue { r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository) d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) idx, err := db.GetNextResourceIndex("issue_index", r.ID) assert.NoError(t, err) - i := &Issue{ + i := &issues_model.Issue{ RepoID: r.ID, PosterID: d.ID, Poster: d, @@ -145,39 +146,39 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu ctx, committer, err := db.TxContext() assert.NoError(t, err) defer committer.Close() - err = newIssue(ctx, d, NewIssueOptions{ + err = issues_model.NewIssueWithIndex(ctx, d, issues_model.NewIssueOptions{ Repo: r, Issue: i, }) assert.NoError(t, err) - i, err = getIssueByID(ctx, i.ID) + i, err = issues_model.GetIssueByID(ctx, i.ID) assert.NoError(t, err) - assert.NoError(t, i.addCrossReferences(ctx, d, false)) + assert.NoError(t, i.AddCrossReferences(ctx, d, false)) assert.NoError(t, committer.Commit()) return i } -func testCreatePR(t *testing.T, repo, doer int64, title, content string) *PullRequest { +func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues_model.PullRequest { r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository) d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) - i := &Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true} - pr := &PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: PullRequestStatusMergeable} - assert.NoError(t, NewPullRequest(db.DefaultContext, r, i, nil, nil, pr)) + i := &issues_model.Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true} + pr := &issues_model.PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: issues_model.PullRequestStatusMergeable} + assert.NoError(t, issues_model.NewPullRequest(db.DefaultContext, r, i, nil, nil, pr)) pr.Issue = i return pr } -func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *Comment { +func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *issues_model.Comment { d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User) - i := unittest.AssertExistsAndLoadBean(t, &Issue{ID: issue}).(*Issue) - c := &Comment{Type: CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} + i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue}).(*issues_model.Issue) + c := &issues_model.Comment{Type: issues_model.CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content} ctx, committer, err := db.TxContext() assert.NoError(t, err) defer committer.Close() err = db.Insert(ctx, c) assert.NoError(t, err) - assert.NoError(t, c.addCrossReferences(ctx, d, false)) + assert.NoError(t, c.AddCrossReferences(ctx, d, false)) assert.NoError(t, committer.Commit()) return c } diff --git a/models/issue_label.go b/models/issues/label.go similarity index 79% rename from models/issue_label.go rename to models/issues/label.go index 48a48dbb7c..98e2e43961 100644 --- a/models/issue_label.go +++ b/models/issues/label.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -21,6 +21,53 @@ import ( "xorm.io/builder" ) +// ErrRepoLabelNotExist represents a "RepoLabelNotExist" kind of error. +type ErrRepoLabelNotExist struct { + LabelID int64 + RepoID int64 +} + +// IsErrRepoLabelNotExist checks if an error is a RepoErrLabelNotExist. +func IsErrRepoLabelNotExist(err error) bool { + _, ok := err.(ErrRepoLabelNotExist) + return ok +} + +func (err ErrRepoLabelNotExist) Error() string { + return fmt.Sprintf("label does not exist [label_id: %d, repo_id: %d]", err.LabelID, err.RepoID) +} + +// ErrOrgLabelNotExist represents a "OrgLabelNotExist" kind of error. +type ErrOrgLabelNotExist struct { + LabelID int64 + OrgID int64 +} + +// IsErrOrgLabelNotExist checks if an error is a OrgErrLabelNotExist. +func IsErrOrgLabelNotExist(err error) bool { + _, ok := err.(ErrOrgLabelNotExist) + return ok +} + +func (err ErrOrgLabelNotExist) Error() string { + return fmt.Sprintf("label does not exist [label_id: %d, org_id: %d]", err.LabelID, err.OrgID) +} + +// ErrLabelNotExist represents a "LabelNotExist" kind of error. +type ErrLabelNotExist struct { + LabelID int64 +} + +// IsErrLabelNotExist checks if an error is a ErrLabelNotExist. +func IsErrLabelNotExist(err error) bool { + _, ok := err.(ErrLabelNotExist) + return ok +} + +func (err ErrLabelNotExist) Error() string { + return fmt.Sprintf("label does not exist [label_id: %d]", err.LabelID) +} + // LabelColorPattern is a regexp witch can validate LabelColor var LabelColorPattern = regexp.MustCompile("^#?(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})$") @@ -671,7 +718,8 @@ func DeleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *use return issue.LoadLabels(ctx) } -func deleteLabelsByRepoID(ctx context.Context, repoID int64) error { +// DeleteLabelsByRepoID deletes labels of some repository +func DeleteLabelsByRepoID(ctx context.Context, repoID int64) error { deleteCond := builder.Select("id").From("label").Where(builder.Eq{"label.repo_id": repoID}) if _, err := db.GetEngine(ctx).In("label_id", deleteCond). @@ -682,3 +730,107 @@ func deleteLabelsByRepoID(ctx context.Context, repoID int64) error { _, err := db.DeleteByBean(ctx, &Label{RepoID: repoID}) return err } + +// CountOrphanedLabels return count of labels witch are broken and not accessible via ui anymore +func CountOrphanedLabels() (int64, error) { + noref, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Count("label.id") + if err != nil { + return 0, err + } + + norepo, err := db.GetEngine(db.DefaultContext).Table("label"). + Where(builder.And( + builder.Gt{"repo_id": 0}, + builder.NotIn("repo_id", builder.Select("id").From("repository")), + )). + Count() + if err != nil { + return 0, err + } + + noorg, err := db.GetEngine(db.DefaultContext).Table("label"). + Where(builder.And( + builder.Gt{"org_id": 0}, + builder.NotIn("org_id", builder.Select("id").From("user")), + )). + Count() + if err != nil { + return 0, err + } + + return noref + norepo + noorg, nil +} + +// DeleteOrphanedLabels delete labels witch are broken and not accessible via ui anymore +func DeleteOrphanedLabels() error { + // delete labels with no reference + if _, err := db.GetEngine(db.DefaultContext).Table("label").Where("repo_id=? AND org_id=?", 0, 0).Delete(new(Label)); err != nil { + return err + } + + // delete labels with none existing repos + if _, err := db.GetEngine(db.DefaultContext). + Where(builder.And( + builder.Gt{"repo_id": 0}, + builder.NotIn("repo_id", builder.Select("id").From("repository")), + )). + Delete(Label{}); err != nil { + return err + } + + // delete labels with none existing orgs + if _, err := db.GetEngine(db.DefaultContext). + Where(builder.And( + builder.Gt{"org_id": 0}, + builder.NotIn("org_id", builder.Select("id").From("user")), + )). + Delete(Label{}); err != nil { + return err + } + + return nil +} + +// CountOrphanedIssueLabels return count of IssueLabels witch have no label behind anymore +func CountOrphanedIssueLabels() (int64, error) { + return db.GetEngine(db.DefaultContext).Table("issue_label"). + NotIn("label_id", builder.Select("id").From("label")). + Count() +} + +// DeleteOrphanedIssueLabels delete IssueLabels witch have no label behind anymore +func DeleteOrphanedIssueLabels() error { + _, err := db.GetEngine(db.DefaultContext). + NotIn("label_id", builder.Select("id").From("label")). + Delete(IssueLabel{}) + return err +} + +// CountIssueLabelWithOutsideLabels count label comments with outside label +func CountIssueLabelWithOutsideLabels() (int64, error) { + return db.GetEngine(db.DefaultContext).Where(builder.Expr("(label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id)")). + Table("issue_label"). + Join("inner", "label", "issue_label.label_id = label.id "). + Join("inner", "issue", "issue.id = issue_label.issue_id "). + Join("inner", "repository", "issue.repo_id = repository.id"). + Count(new(IssueLabel)) +} + +// FixIssueLabelWithOutsideLabels fix label comments with outside label +func FixIssueLabelWithOutsideLabels() (int64, error) { + res, err := db.GetEngine(db.DefaultContext).Exec(`DELETE FROM issue_label WHERE issue_label.id IN ( + SELECT il_too.id FROM ( + SELECT il_too_too.id + FROM issue_label AS il_too_too + INNER JOIN label ON il_too_too.label_id = label.id + INNER JOIN issue on issue.id = il_too_too.issue_id + INNER JOIN repository on repository.id = issue.repo_id + WHERE + (label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != repository.owner_id) + ) AS il_too )`) + if err != nil { + return 0, err + } + + return res.RowsAffected() +} diff --git a/models/issues/label_test.go b/models/issues/label_test.go new file mode 100644 index 0000000000..33f114b5fe --- /dev/null +++ b/models/issues/label_test.go @@ -0,0 +1,395 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package issues_test + +import ( + "html/template" + "testing" + + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + + "github.com/stretchr/testify/assert" +) + +// TODO TestGetLabelTemplateFile + +func TestLabel_CalOpenIssues(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label.CalOpenIssues() + assert.EqualValues(t, 2, label.NumOpenIssues) +} + +func TestLabel_ForegroundColor(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + assert.Equal(t, template.CSS("#000"), label.ForegroundColor()) + + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + assert.Equal(t, template.CSS("#fff"), label.ForegroundColor()) +} + +func TestNewLabels(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labels := []*issues_model.Label{ + {RepoID: 2, Name: "labelName2", Color: "#123456"}, + {RepoID: 3, Name: "labelName3", Color: "#123"}, + {RepoID: 4, Name: "labelName4", Color: "ABCDEF"}, + {RepoID: 5, Name: "labelName5", Color: "DEF"}, + } + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: ""})) + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#45G"})) + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"})) + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "45G"})) + assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "12345G"})) + for _, label := range labels { + unittest.AssertNotExistsBean(t, label) + } + assert.NoError(t, issues_model.NewLabels(labels...)) + for _, label := range labels { + unittest.AssertExistsAndLoadBean(t, label, unittest.Cond("id = ?", label.ID)) + } + unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{}) +} + +func TestGetLabelByID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelByID(db.DefaultContext, 1) + assert.NoError(t, err) + assert.EqualValues(t, 1, label.ID) + + _, err = issues_model.GetLabelByID(db.DefaultContext, unittest.NonexistentID) + assert.True(t, issues_model.IsErrLabelNotExist(err)) +} + +func TestGetLabelInRepoByName(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelInRepoByName(db.DefaultContext, 1, "label1") + assert.NoError(t, err) + assert.EqualValues(t, 1, label.ID) + assert.Equal(t, "label1", label.Name) + + _, err = issues_model.GetLabelInRepoByName(db.DefaultContext, 1, "") + assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) + + _, err = issues_model.GetLabelInRepoByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") + assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) +} + +func TestGetLabelInRepoByNames(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labelIDs, err := issues_model.GetLabelIDsInRepoByNames(1, []string{"label1", "label2"}) + assert.NoError(t, err) + + assert.Len(t, labelIDs, 2) + + assert.Equal(t, int64(1), labelIDs[0]) + assert.Equal(t, int64(2), labelIDs[1]) +} + +func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + // label3 doesn't exists.. See labels.yml + labelIDs, err := issues_model.GetLabelIDsInRepoByNames(1, []string{"label1", "label2", "label3"}) + assert.NoError(t, err) + + assert.Len(t, labelIDs, 2) + + assert.Equal(t, int64(1), labelIDs[0]) + assert.Equal(t, int64(2), labelIDs[1]) + assert.NoError(t, err) +} + +func TestGetLabelInRepoByID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelInRepoByID(db.DefaultContext, 1, 1) + assert.NoError(t, err) + assert.EqualValues(t, 1, label.ID) + + _, err = issues_model.GetLabelInRepoByID(db.DefaultContext, 1, -1) + assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) + + _, err = issues_model.GetLabelInRepoByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + assert.True(t, issues_model.IsErrRepoLabelNotExist(err)) +} + +func TestGetLabelsInRepoByIDs(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labels, err := issues_model.GetLabelsInRepoByIDs(1, []int64{1, 2, unittest.NonexistentID}) + assert.NoError(t, err) + if assert.Len(t, labels, 2) { + assert.EqualValues(t, 1, labels[0].ID) + assert.EqualValues(t, 2, labels[1].ID) + } +} + +func TestGetLabelsByRepoID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) { + labels, err := issues_model.GetLabelsByRepoID(db.DefaultContext, repoID, sortType, db.ListOptions{}) + assert.NoError(t, err) + assert.Len(t, labels, len(expectedIssueIDs)) + for i, label := range labels { + assert.EqualValues(t, expectedIssueIDs[i], label.ID) + } + } + testSuccess(1, "leastissues", []int64{2, 1}) + testSuccess(1, "mostissues", []int64{1, 2}) + testSuccess(1, "reversealphabetically", []int64{2, 1}) + testSuccess(1, "default", []int64{1, 2}) +} + +// Org versions + +func TestGetLabelInOrgByName(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelInOrgByName(db.DefaultContext, 3, "orglabel3") + assert.NoError(t, err) + assert.EqualValues(t, 3, label.ID) + assert.Equal(t, "orglabel3", label.Name) + + _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, 3, "") + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, 0, "orglabel3") + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, -1, "orglabel3") + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByName(db.DefaultContext, unittest.NonexistentID, "nonexistent") + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) +} + +func TestGetLabelInOrgByNames(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labelIDs, err := issues_model.GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4"}) + assert.NoError(t, err) + + assert.Len(t, labelIDs, 2) + + assert.Equal(t, int64(3), labelIDs[0]) + assert.Equal(t, int64(4), labelIDs[1]) +} + +func TestGetLabelInOrgByNamesDiscardsNonExistentLabels(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + // orglabel99 doesn't exists.. See labels.yml + labelIDs, err := issues_model.GetLabelIDsInOrgByNames(3, []string{"orglabel3", "orglabel4", "orglabel99"}) + assert.NoError(t, err) + + assert.Len(t, labelIDs, 2) + + assert.Equal(t, int64(3), labelIDs[0]) + assert.Equal(t, int64(4), labelIDs[1]) + assert.NoError(t, err) +} + +func TestGetLabelInOrgByID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label, err := issues_model.GetLabelInOrgByID(db.DefaultContext, 3, 3) + assert.NoError(t, err) + assert.EqualValues(t, 3, label.ID) + + _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, 3, -1) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, 0, 3) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, -1, 3) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelInOrgByID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) +} + +func TestGetLabelsInOrgByIDs(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labels, err := issues_model.GetLabelsInOrgByIDs(3, []int64{3, 4, unittest.NonexistentID}) + assert.NoError(t, err) + if assert.Len(t, labels, 2) { + assert.EqualValues(t, 3, labels[0].ID) + assert.EqualValues(t, 4, labels[1].ID) + } +} + +func TestGetLabelsByOrgID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + testSuccess := func(orgID int64, sortType string, expectedIssueIDs []int64) { + labels, err := issues_model.GetLabelsByOrgID(db.DefaultContext, orgID, sortType, db.ListOptions{}) + assert.NoError(t, err) + assert.Len(t, labels, len(expectedIssueIDs)) + for i, label := range labels { + assert.EqualValues(t, expectedIssueIDs[i], label.ID) + } + } + testSuccess(3, "leastissues", []int64{3, 4}) + testSuccess(3, "mostissues", []int64{4, 3}) + testSuccess(3, "reversealphabetically", []int64{4, 3}) + testSuccess(3, "default", []int64{3, 4}) + + var err error + _, err = issues_model.GetLabelsByOrgID(db.DefaultContext, 0, "leastissues", db.ListOptions{}) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) + + _, err = issues_model.GetLabelsByOrgID(db.DefaultContext, -1, "leastissues", db.ListOptions{}) + assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) +} + +// + +func TestGetLabelsByIssueID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + labels, err := issues_model.GetLabelsByIssueID(db.DefaultContext, 1) + assert.NoError(t, err) + if assert.Len(t, labels, 1) { + assert.EqualValues(t, 1, labels[0].ID) + } + + labels, err = issues_model.GetLabelsByIssueID(db.DefaultContext, unittest.NonexistentID) + assert.NoError(t, err) + assert.Len(t, labels, 0) +} + +func TestUpdateLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + // make sure update wont overwrite it + update := &issues_model.Label{ + ID: label.ID, + Color: "#ffff00", + Name: "newLabelName", + Description: label.Description, + } + label.Color = update.Color + label.Name = update.Name + assert.NoError(t, issues_model.UpdateLabel(update)) + newLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + assert.EqualValues(t, label.ID, newLabel.ID) + assert.EqualValues(t, label.Color, newLabel.Color) + assert.EqualValues(t, label.Name, newLabel.Name) + assert.EqualValues(t, label.Description, newLabel.Description) + unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{}) +} + +func TestDeleteLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + assert.NoError(t, issues_model.DeleteLabel(label.RepoID, label.ID)) + unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID, RepoID: label.RepoID}) + + assert.NoError(t, issues_model.DeleteLabel(label.RepoID, label.ID)) + unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID}) + + assert.NoError(t, issues_model.DeleteLabel(unittest.NonexistentID, unittest.NonexistentID)) + unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{}) +} + +func TestHasIssueLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + assert.True(t, issues_model.HasIssueLabel(db.DefaultContext, 1, 1)) + assert.False(t, issues_model.HasIssueLabel(db.DefaultContext, 1, 2)) + assert.False(t, issues_model.HasIssueLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) +} + +func TestNewIssueLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + + // add new IssueLabel + prevNumIssues := label.NumIssues + assert.NoError(t, issues_model.NewIssueLabel(issue, label, doer)) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ + Type: issues_model.CommentTypeLabel, + PosterID: doer.ID, + IssueID: issue.ID, + LabelID: label.ID, + Content: "1", + }) + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + assert.EqualValues(t, prevNumIssues+1, label.NumIssues) + + // re-add existing IssueLabel + assert.NoError(t, issues_model.NewIssueLabel(issue, label, doer)) + unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{}) +} + +func TestNewIssueLabels(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5}).(*issues_model.Issue) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) + + assert.NoError(t, issues_model.NewIssueLabels(issue, []*issues_model.Label{label1, label2}, doer)) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ + Type: issues_model.CommentTypeLabel, + PosterID: doer.ID, + IssueID: issue.ID, + LabelID: label1.ID, + Content: "1", + }) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) + label1 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) + assert.EqualValues(t, 3, label1.NumIssues) + assert.EqualValues(t, 1, label1.NumClosedIssues) + label2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label) + assert.EqualValues(t, 1, label2.NumIssues) + assert.EqualValues(t, 1, label2.NumClosedIssues) + + // corner case: test empty slice + assert.NoError(t, issues_model.NewIssueLabels(issue, []*issues_model.Label{}, doer)) + + unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{}) +} + +func TestDeleteIssueLabel(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + testSuccess := func(labelID, issueID, doerID int64) { + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}).(*issues_model.Issue) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID}).(*user_model.User) + + expectedNumIssues := label.NumIssues + expectedNumClosedIssues := label.NumClosedIssues + if unittest.BeanExists(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) { + expectedNumIssues-- + if issue.IsClosed { + expectedNumClosedIssues-- + } + } + + ctx, committer, err := db.TxContext() + defer committer.Close() + assert.NoError(t, err) + assert.NoError(t, issues_model.DeleteIssueLabel(ctx, issue, label, doer)) + assert.NoError(t, committer.Commit()) + + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ + Type: issues_model.CommentTypeLabel, + PosterID: doerID, + IssueID: issueID, + LabelID: labelID, + }, `content=""`) + label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) + assert.EqualValues(t, expectedNumIssues, label.NumIssues) + assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues) + } + testSuccess(1, 1, 2) + testSuccess(2, 5, 2) + testSuccess(1, 1, 2) // delete non-existent IssueLabel + + unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{}) +} diff --git a/models/issues/main_test.go b/models/issues/main_test.go index 30f6ff02fb..e34bef62ca 100644 --- a/models/issues/main_test.go +++ b/models/issues/main_test.go @@ -2,14 +2,20 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package issues +package issues_test import ( "path/filepath" "testing" + _ "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" + _ "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" + _ "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" + + "github.com/stretchr/testify/assert" ) func init() { @@ -17,14 +23,18 @@ func init() { setting.LoadForTest() } +func TestFixturesAreConsistent(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + unittest.CheckConsistencyFor(t, + &issues_model.Issue{}, + &issues_model.PullRequest{}, + &issues_model.Milestone{}, + &issues_model.Label{}, + ) +} + func TestMain(m *testing.M) { unittest.MainTest(m, &unittest.TestOptions{ GiteaRootPath: filepath.Join("..", ".."), - FixtureFiles: []string{ - "reaction.yml", - "user.yml", - "repository.yml", - "milestone.yml", - }, }) } diff --git a/models/issues/milestone.go b/models/issues/milestone.go index f7172f6448..6c10959108 100644 --- a/models/issues/milestone.go +++ b/models/issues/milestone.go @@ -292,11 +292,17 @@ func DeleteMilestoneByRepoID(repoID, id int64) error { return err } - numMilestones, err := countRepoMilestones(ctx, repo.ID) + numMilestones, err := CountMilestones(ctx, GetMilestonesOption{ + RepoID: repo.ID, + State: api.StateAll, + }) if err != nil { return err } - numClosedMilestones, err := countRepoClosedMilestones(ctx, repo.ID) + numClosedMilestones, err := CountMilestones(ctx, GetMilestonesOption{ + RepoID: repo.ID, + State: api.StateClosed, + }) if err != nil { return err } @@ -428,13 +434,6 @@ func GetMilestonesByRepoIDs(repoIDs []int64, page int, isClosed bool, sortType s ) } -// ____ _ _ -// / ___|| |_ __ _| |_ ___ -// \___ \| __/ _` | __/ __| -// ___) | || (_| | |_\__ \ -// |____/ \__\__,_|\__|___/ -// - // MilestonesStats represents milestone statistic information. type MilestonesStats struct { OpenCount, ClosedCount int64 @@ -503,23 +502,13 @@ func GetMilestonesStatsByRepoCondAndKw(repoCond builder.Cond, keyword string) (* return stats, nil } -func countRepoMilestones(ctx context.Context, repoID int64) (int64, error) { +// CountMilestones returns number of milestones in given repository with other options +func CountMilestones(ctx context.Context, opts GetMilestonesOption) (int64, error) { return db.GetEngine(ctx). - Where("repo_id=?", repoID). + Where(opts.toCond()). Count(new(Milestone)) } -func countRepoClosedMilestones(ctx context.Context, repoID int64) (int64, error) { - return db.GetEngine(ctx). - Where("repo_id=? AND is_closed=?", repoID, true). - Count(new(Milestone)) -} - -// CountRepoClosedMilestones returns number of closed milestones in given repository. -func CountRepoClosedMilestones(repoID int64) (int64, error) { - return countRepoClosedMilestones(db.DefaultContext, repoID) -} - // CountMilestonesByRepoCond map from repo conditions to number of milestones matching the options` func CountMilestonesByRepoCond(repoCond builder.Cond, isClosed bool) (map[int64]int64, error) { sess := db.GetEngine(db.DefaultContext).Where("is_closed = ?", isClosed) diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index e087318320..a6fbf9c23b 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -2,44 +2,46 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package issues +package issues_test import ( "sort" "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/timeutil" "github.com/stretchr/testify/assert" "xorm.io/builder" ) func TestMilestone_State(t *testing.T) { - assert.Equal(t, api.StateOpen, (&Milestone{IsClosed: false}).State()) - assert.Equal(t, api.StateClosed, (&Milestone{IsClosed: true}).State()) + assert.Equal(t, api.StateOpen, (&issues_model.Milestone{IsClosed: false}).State()) + assert.Equal(t, api.StateClosed, (&issues_model.Milestone{IsClosed: true}).State()) } func TestGetMilestoneByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - milestone, err := GetMilestoneByRepoID(db.DefaultContext, 1, 1) + milestone, err := issues_model.GetMilestoneByRepoID(db.DefaultContext, 1, 1) assert.NoError(t, err) assert.EqualValues(t, 1, milestone.ID) assert.EqualValues(t, 1, milestone.RepoID) - _, err = GetMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) - assert.True(t, IsErrMilestoneNotExist(err)) + _, err = issues_model.GetMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID) + assert.True(t, issues_model.IsErrMilestoneNotExist(err)) } func TestGetMilestonesByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64, state api.StateType) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) - milestones, _, err := GetMilestones(GetMilestonesOption{ + milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{ RepoID: repo.ID, State: state, }) @@ -76,7 +78,7 @@ func TestGetMilestonesByRepoID(t *testing.T) { test(3, api.StateClosed) test(3, api.StateAll) - milestones, _, err := GetMilestones(GetMilestonesOption{ + milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{ RepoID: unittest.NonexistentID, State: api.StateOpen, }) @@ -87,9 +89,9 @@ func TestGetMilestonesByRepoID(t *testing.T) { func TestGetMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - test := func(sortType string, sortCond func(*Milestone) int) { + test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - milestones, _, err := GetMilestones(GetMilestonesOption{ + milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, @@ -106,7 +108,7 @@ func TestGetMilestones(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - milestones, _, err = GetMilestones(GetMilestonesOption{ + milestones, _, err = issues_model.GetMilestones(issues_model.GetMilestonesOption{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, @@ -125,22 +127,22 @@ func TestGetMilestones(t *testing.T) { assert.True(t, sort.IntsAreSorted(values)) } } - test("furthestduedate", func(milestone *Milestone) int { + test("furthestduedate", func(milestone *issues_model.Milestone) int { return -int(milestone.DeadlineUnix) }) - test("leastcomplete", func(milestone *Milestone) int { + test("leastcomplete", func(milestone *issues_model.Milestone) int { return milestone.Completeness }) - test("mostcomplete", func(milestone *Milestone) int { + test("mostcomplete", func(milestone *issues_model.Milestone) int { return -milestone.Completeness }) - test("leastissues", func(milestone *Milestone) int { + test("leastissues", func(milestone *issues_model.Milestone) int { return milestone.NumIssues }) - test("mostissues", func(milestone *Milestone) int { + test("mostissues", func(milestone *issues_model.Milestone) int { return -milestone.NumIssues }) - test("soonestduedate", func(milestone *Milestone) int { + test("soonestduedate", func(milestone *issues_model.Milestone) int { return int(milestone.DeadlineUnix) }) } @@ -149,7 +151,10 @@ func TestCountRepoMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) - count, err := countRepoMilestones(db.DefaultContext, repoID) + count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + RepoID: repoID, + State: api.StateAll, + }) assert.NoError(t, err) assert.EqualValues(t, repo.NumMilestones, count) } @@ -157,7 +162,10 @@ func TestCountRepoMilestones(t *testing.T) { test(2) test(3) - count, err := countRepoMilestones(db.DefaultContext, unittest.NonexistentID) + count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + RepoID: unittest.NonexistentID, + State: api.StateAll, + }) assert.NoError(t, err) assert.EqualValues(t, 0, count) } @@ -166,7 +174,10 @@ func TestCountRepoClosedMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) - count, err := CountRepoClosedMilestones(repoID) + count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + RepoID: repoID, + State: api.StateClosed, + }) assert.NoError(t, err) assert.EqualValues(t, repo.NumClosedMilestones, count) } @@ -174,7 +185,10 @@ func TestCountRepoClosedMilestones(t *testing.T) { test(2) test(3) - count, err := CountRepoClosedMilestones(unittest.NonexistentID) + count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + RepoID: unittest.NonexistentID, + State: api.StateClosed, + }) assert.NoError(t, err) assert.EqualValues(t, 0, count) } @@ -188,12 +202,12 @@ func TestCountMilestonesByRepoIDs(t *testing.T) { repo1OpenCount, repo1ClosedCount := milestonesCount(1) repo2OpenCount, repo2ClosedCount := milestonesCount(2) - openCounts, err := CountMilestonesByRepoCond(builder.In("repo_id", []int64{1, 2}), false) + openCounts, err := issues_model.CountMilestonesByRepoCond(builder.In("repo_id", []int64{1, 2}), false) assert.NoError(t, err) assert.EqualValues(t, repo1OpenCount, openCounts[1]) assert.EqualValues(t, repo2OpenCount, openCounts[2]) - closedCounts, err := CountMilestonesByRepoCond(builder.In("repo_id", []int64{1, 2}), true) + closedCounts, err := issues_model.CountMilestonesByRepoCond(builder.In("repo_id", []int64{1, 2}), true) assert.NoError(t, err) assert.EqualValues(t, repo1ClosedCount, closedCounts[1]) assert.EqualValues(t, repo2ClosedCount, closedCounts[2]) @@ -203,9 +217,9 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - test := func(sortType string, sortCond func(*Milestone) int) { + test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - openMilestones, err := GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, false, sortType) + openMilestones, err := issues_model.GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, false, sortType) assert.NoError(t, err) assert.Len(t, openMilestones, repo1.NumOpenMilestones+repo2.NumOpenMilestones) values := make([]int, len(openMilestones)) @@ -214,7 +228,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - closedMilestones, err := GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, true, sortType) + closedMilestones, err := issues_model.GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, true, sortType) assert.NoError(t, err) assert.Len(t, closedMilestones, repo1.NumClosedMilestones+repo2.NumClosedMilestones) values = make([]int, len(closedMilestones)) @@ -224,22 +238,22 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { assert.True(t, sort.IntsAreSorted(values)) } } - test("furthestduedate", func(milestone *Milestone) int { + test("furthestduedate", func(milestone *issues_model.Milestone) int { return -int(milestone.DeadlineUnix) }) - test("leastcomplete", func(milestone *Milestone) int { + test("leastcomplete", func(milestone *issues_model.Milestone) int { return milestone.Completeness }) - test("mostcomplete", func(milestone *Milestone) int { + test("mostcomplete", func(milestone *issues_model.Milestone) int { return -milestone.Completeness }) - test("leastissues", func(milestone *Milestone) int { + test("leastissues", func(milestone *issues_model.Milestone) int { return milestone.NumIssues }) - test("mostissues", func(milestone *Milestone) int { + test("mostissues", func(milestone *issues_model.Milestone) int { return -milestone.NumIssues }) - test("soonestduedate", func(milestone *Milestone) int { + test("soonestduedate", func(milestone *issues_model.Milestone) int { return int(milestone.DeadlineUnix) }) } @@ -249,7 +263,7 @@ func TestGetMilestonesStats(t *testing.T) { test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) - stats, err := GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": repoID})) + stats, err := issues_model.GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": repoID})) assert.NoError(t, err) assert.EqualValues(t, repo.NumMilestones-repo.NumClosedMilestones, stats.OpenCount) assert.EqualValues(t, repo.NumClosedMilestones, stats.ClosedCount) @@ -258,7 +272,7 @@ func TestGetMilestonesStats(t *testing.T) { test(2) test(3) - stats, err := GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": unittest.NonexistentID})) + stats, err := issues_model.GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": unittest.NonexistentID})) assert.NoError(t, err) assert.EqualValues(t, 0, stats.OpenCount) assert.EqualValues(t, 0, stats.ClosedCount) @@ -266,8 +280,75 @@ func TestGetMilestonesStats(t *testing.T) { repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - milestoneStats, err := GetMilestonesStatsByRepoCond(builder.In("repo_id", []int64{repo1.ID, repo2.ID})) + milestoneStats, err := issues_model.GetMilestonesStatsByRepoCond(builder.In("repo_id", []int64{repo1.ID, repo2.ID})) assert.NoError(t, err) assert.EqualValues(t, repo1.NumOpenMilestones+repo2.NumOpenMilestones, milestoneStats.OpenCount) assert.EqualValues(t, repo1.NumClosedMilestones+repo2.NumClosedMilestones, milestoneStats.ClosedCount) } + +func TestNewMilestone(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + milestone := &issues_model.Milestone{ + RepoID: 1, + Name: "milestoneName", + Content: "milestoneContent", + } + + assert.NoError(t, issues_model.NewMilestone(milestone)) + unittest.AssertExistsAndLoadBean(t, milestone) + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) +} + +func TestChangeMilestoneStatus(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + + assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, true)) + unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1") + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) + + assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, false)) + unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=0") + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{}) +} + +func TestDeleteMilestoneByRepoID(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + assert.NoError(t, issues_model.DeleteMilestoneByRepoID(1, 1)) + unittest.AssertNotExistsBean(t, &issues_model.Milestone{ID: 1}) + unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}) + + assert.NoError(t, issues_model.DeleteMilestoneByRepoID(unittest.NonexistentID, unittest.NonexistentID)) +} + +func TestUpdateMilestone(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + milestone.Name = " newMilestoneName " + milestone.Content = "newMilestoneContent" + assert.NoError(t, issues_model.UpdateMilestone(milestone, milestone.IsClosed)) + milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) + assert.EqualValues(t, "newMilestoneName", milestone.Name) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) +} + +func TestUpdateMilestoneCounters(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{MilestoneID: 1}, + "is_closed=0").(*issues_model.Issue) + + issue.IsClosed = true + issue.ClosedUnix = timeutil.TimeStampNow() + _, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) + assert.NoError(t, err) + assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) + + issue.IsClosed = false + issue.ClosedUnix = 0 + _, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue) + assert.NoError(t, err) + assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID)) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) +} diff --git a/models/pull.go b/models/issues/pull.go similarity index 80% rename from models/pull.go rename to models/issues/pull.go index 238eb16636..f2ca19b03e 100644 --- a/models/pull.go +++ b/models/issues/pull.go @@ -3,7 +3,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -25,6 +25,83 @@ import ( "xorm.io/builder" ) +// ErrPullRequestNotExist represents a "PullRequestNotExist" kind of error. +type ErrPullRequestNotExist struct { + ID int64 + IssueID int64 + HeadRepoID int64 + BaseRepoID int64 + HeadBranch string + BaseBranch string +} + +// IsErrPullRequestNotExist checks if an error is a ErrPullRequestNotExist. +func IsErrPullRequestNotExist(err error) bool { + _, ok := err.(ErrPullRequestNotExist) + return ok +} + +func (err ErrPullRequestNotExist) Error() string { + return fmt.Sprintf("pull request does not exist [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", + err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) +} + +// ErrPullRequestAlreadyExists represents a "PullRequestAlreadyExists"-error +type ErrPullRequestAlreadyExists struct { + ID int64 + IssueID int64 + HeadRepoID int64 + BaseRepoID int64 + HeadBranch string + BaseBranch string +} + +// IsErrPullRequestAlreadyExists checks if an error is a ErrPullRequestAlreadyExists. +func IsErrPullRequestAlreadyExists(err error) bool { + _, ok := err.(ErrPullRequestAlreadyExists) + return ok +} + +// Error does pretty-printing :D +func (err ErrPullRequestAlreadyExists) Error() string { + return fmt.Sprintf("pull request already exists for these targets [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", + err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) +} + +// ErrPullRequestHeadRepoMissing represents a "ErrPullRequestHeadRepoMissing" error +type ErrPullRequestHeadRepoMissing struct { + ID int64 + HeadRepoID int64 +} + +// IsErrErrPullRequestHeadRepoMissing checks if an error is a ErrPullRequestHeadRepoMissing. +func IsErrErrPullRequestHeadRepoMissing(err error) bool { + _, ok := err.(ErrPullRequestHeadRepoMissing) + return ok +} + +// Error does pretty-printing :D +func (err ErrPullRequestHeadRepoMissing) Error() string { + return fmt.Sprintf("pull request head repo missing [id: %d, head_repo_id: %d]", + err.ID, err.HeadRepoID) +} + +// ErrPullWasClosed is used close a closed pull request +type ErrPullWasClosed struct { + ID int64 + Index int64 +} + +// IsErrPullWasClosed checks if an error is a ErrErrPullWasClosed. +func IsErrPullWasClosed(err error) bool { + _, ok := err.(ErrPullWasClosed) + return ok +} + +func (err ErrPullWasClosed) Error() string { + return fmt.Sprintf("Pull request [%d] %d was already closed", err.ID, err.Index) +} + // PullRequestType defines pull request type type PullRequestType int @@ -98,7 +175,8 @@ func init() { db.RegisterModel(new(PullRequest)) } -func deletePullsByBaseRepoID(ctx context.Context, repoID int64) error { +// DeletePullsByBaseRepoID deletes all pull requests by the base repository ID +func DeletePullsByBaseRepoID(ctx context.Context, repoID int64) error { deleteCond := builder.Select("id").From("pull_request").Where(builder.Eq{"pull_request.base_repo_id": repoID}) // Delete scheduled auto merges @@ -219,7 +297,7 @@ func (pr *PullRequest) LoadIssueCtx(ctx context.Context) (err error) { return nil } - pr.Issue, err = getIssueByID(ctx, pr.IssueID) + pr.Issue, err = GetIssueByID(ctx, pr.IssueID) if err == nil { pr.Issue.PullRequest = pr } @@ -420,14 +498,14 @@ func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue defer committer.Close() ctx.WithContext(outerCtx) - if err = newIssue(ctx, issue.Poster, NewIssueOptions{ + if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{ Repo: repo, Issue: issue, LabelIDs: labelIDs, Attachments: uuids, IsPull: true, }); err != nil { - if IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) { return err } return fmt.Errorf("newIssue: %v", err) @@ -691,3 +769,70 @@ func (pr *PullRequest) Mergeable() bool { return pr.Status != PullRequestStatusChecking && pr.Status != PullRequestStatusConflict && pr.Status != PullRequestStatusError && !pr.IsWorkInProgress() } + +// HasEnoughApprovals returns true if pr has enough granted approvals. +func HasEnoughApprovals(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { + if protectBranch.RequiredApprovals == 0 { + return true + } + return GetGrantedApprovalsCount(ctx, protectBranch, pr) >= protectBranch.RequiredApprovals +} + +// GetGrantedApprovalsCount returns the number of granted approvals for pr. A granted approval must be authored by a user in an approval whitelist. +func GetGrantedApprovalsCount(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) int64 { + sess := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). + And("type = ?", ReviewTypeApprove). + And("official = ?", true). + And("dismissed = ?", false) + if protectBranch.DismissStaleApprovals { + sess = sess.And("stale = ?", false) + } + approvals, err := sess.Count(new(Review)) + if err != nil { + log.Error("GetGrantedApprovalsCount: %v", err) + return 0 + } + + return approvals +} + +// MergeBlockedByRejectedReview returns true if merge is blocked by rejected reviews +func MergeBlockedByRejectedReview(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { + if !protectBranch.BlockOnRejectedReviews { + return false + } + rejectExist, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). + And("type = ?", ReviewTypeReject). + And("official = ?", true). + And("dismissed = ?", false). + Exist(new(Review)) + if err != nil { + log.Error("MergeBlockedByRejectedReview: %v", err) + return true + } + + return rejectExist +} + +// MergeBlockedByOfficialReviewRequests block merge because of some review request to official reviewer +// of from official review +func MergeBlockedByOfficialReviewRequests(ctx context.Context, protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { + if !protectBranch.BlockOnOfficialReviewRequests { + return false + } + has, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID). + And("type = ?", ReviewTypeRequest). + And("official = ?", true). + Exist(new(Review)) + if err != nil { + log.Error("MergeBlockedByOfficialReviewRequests: %v", err) + return true + } + + return has +} + +// MergeBlockedByOutdatedBranch returns true if merge is blocked by an outdated head branch +func MergeBlockedByOutdatedBranch(protectBranch *git_model.ProtectedBranch, pr *PullRequest) bool { + return protectBranch.BlockOnOutdatedBranch && pr.CommitsBehind > 0 +} diff --git a/models/pull_list.go b/models/issues/pull_list.go similarity index 99% rename from models/pull_list.go rename to models/issues/pull_list.go index fb14d3beac..9ca536909e 100644 --- a/models/pull_list.go +++ b/models/issues/pull_list.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" diff --git a/models/pull_test.go b/models/issues/pull_test.go similarity index 58% rename from models/pull_test.go rename to models/issues/pull_test.go index 00bbfc798a..0d1991383d 100644 --- a/models/pull_test.go +++ b/models/issues/pull_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -15,7 +16,7 @@ import ( func TestPullRequest_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadAttributes()) assert.NotNil(t, pr.Merger) assert.Equal(t, pr.MergerID, pr.Merger.ID) @@ -23,7 +24,7 @@ func TestPullRequest_LoadAttributes(t *testing.T) { func TestPullRequest_LoadIssue(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadIssue()) assert.NotNil(t, pr.Issue) assert.Equal(t, int64(2), pr.Issue.ID) @@ -34,7 +35,7 @@ func TestPullRequest_LoadIssue(t *testing.T) { func TestPullRequest_LoadBaseRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadBaseRepo()) assert.NotNil(t, pr.BaseRepo) assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID) @@ -45,7 +46,7 @@ func TestPullRequest_LoadBaseRepo(t *testing.T) { func TestPullRequest_LoadHeadRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadHeadRepo()) assert.NotNil(t, pr.HeadRepo) assert.Equal(t, pr.HeadRepoID, pr.HeadRepo.ID) @@ -57,7 +58,7 @@ func TestPullRequest_LoadHeadRepo(t *testing.T) { func TestPullRequestsNewest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, count, err := PullRequests(1, &PullRequestsOptions{ + prs, count, err := issues_model.PullRequests(1, &issues_model.PullRequestsOptions{ ListOptions: db.ListOptions{ Page: 1, }, @@ -76,7 +77,7 @@ func TestPullRequestsNewest(t *testing.T) { func TestPullRequestsOldest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, count, err := PullRequests(1, &PullRequestsOptions{ + prs, count, err := issues_model.PullRequests(1, &issues_model.PullRequestsOptions{ ListOptions: db.ListOptions{ Page: 1, }, @@ -95,30 +96,30 @@ func TestPullRequestsOldest(t *testing.T) { func TestGetUnmergedPullRequest(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := GetUnmergedPullRequest(1, 1, "branch2", "master", PullRequestFlowGithub) + pr, err := issues_model.GetUnmergedPullRequest(1, 1, "branch2", "master", issues_model.PullRequestFlowGithub) assert.NoError(t, err) assert.Equal(t, int64(2), pr.ID) - _, err = GetUnmergedPullRequest(1, 9223372036854775807, "branch1", "master", PullRequestFlowGithub) + _, err = issues_model.GetUnmergedPullRequest(1, 9223372036854775807, "branch1", "master", issues_model.PullRequestFlowGithub) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - exist, err := HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2") + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2") assert.NoError(t, err) assert.Equal(t, true, exist) - exist, err = HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "not_exist_branch") + exist, err = issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "not_exist_branch") assert.NoError(t, err) assert.Equal(t, false, exist) } func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, err := GetUnmergedPullRequestsByHeadInfo(1, "branch2") + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(1, "branch2") assert.NoError(t, err) assert.Len(t, prs, 1) for _, pr := range prs { @@ -129,7 +130,7 @@ func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) { func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs, err := GetUnmergedPullRequestsByBaseInfo(1, "master") + prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(1, "master") assert.NoError(t, err) assert.Len(t, prs, 1) pr := prs[0] @@ -140,51 +141,51 @@ func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) { func TestGetPullRequestByIndex(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := GetPullRequestByIndex(db.DefaultContext, 1, 2) + pr, err := issues_model.GetPullRequestByIndex(db.DefaultContext, 1, 2) assert.NoError(t, err) assert.Equal(t, int64(1), pr.BaseRepoID) assert.Equal(t, int64(2), pr.Index) - _, err = GetPullRequestByIndex(db.DefaultContext, 9223372036854775807, 9223372036854775807) + _, err = issues_model.GetPullRequestByIndex(db.DefaultContext, 9223372036854775807, 9223372036854775807) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) - _, err = GetPullRequestByIndex(db.DefaultContext, 1, 0) + _, err = issues_model.GetPullRequestByIndex(db.DefaultContext, 1, 0) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestGetPullRequestByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := GetPullRequestByID(db.DefaultContext, 1) + pr, err := issues_model.GetPullRequestByID(db.DefaultContext, 1) assert.NoError(t, err) assert.Equal(t, int64(1), pr.ID) assert.Equal(t, int64(2), pr.IssueID) - _, err = GetPullRequestByID(db.DefaultContext, 9223372036854775807) + _, err = issues_model.GetPullRequestByID(db.DefaultContext, 9223372036854775807) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestGetPullRequestByIssueID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr, err := GetPullRequestByIssueID(db.DefaultContext, 2) + pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, 2) assert.NoError(t, err) assert.Equal(t, int64(2), pr.IssueID) - _, err = GetPullRequestByIssueID(db.DefaultContext, 9223372036854775807) + _, err = issues_model.GetPullRequestByIssueID(db.DefaultContext, 9223372036854775807) assert.Error(t, err) - assert.True(t, IsErrPullRequestNotExist(err)) + assert.True(t, issues_model.IsErrPullRequestNotExist(err)) } func TestPullRequest_Update(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) pr.BaseBranch = "baseBranch" pr.HeadBranch = "headBranch" pr.Update() - pr = unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: pr.ID}).(*PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}).(*issues_model.PullRequest) assert.Equal(t, "baseBranch", pr.BaseBranch) assert.Equal(t, "headBranch", pr.HeadBranch) unittest.CheckConsistencyFor(t, pr) @@ -192,14 +193,14 @@ func TestPullRequest_Update(t *testing.T) { func TestPullRequest_UpdateCols(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := &PullRequest{ + pr := &issues_model.PullRequest{ ID: 1, BaseBranch: "baseBranch", HeadBranch: "headBranch", } assert.NoError(t, pr.UpdateCols("head_branch")) - pr = unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.Equal(t, "master", pr.BaseBranch) assert.Equal(t, "headBranch", pr.HeadBranch) unittest.CheckConsistencyFor(t, pr) @@ -208,17 +209,17 @@ func TestPullRequest_UpdateCols(t *testing.T) { func TestPullRequestList_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - prs := []*PullRequest{ - unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest), - unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest), + prs := []*issues_model.PullRequest{ + unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest), + unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest), } - assert.NoError(t, PullRequestList(prs).LoadAttributes()) + assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes()) for _, pr := range prs { assert.NotNil(t, pr.Issue) assert.Equal(t, pr.IssueID, pr.Issue.ID) } - assert.NoError(t, PullRequestList([]*PullRequest{}).LoadAttributes()) + assert.NoError(t, issues_model.PullRequestList([]*issues_model.PullRequest{}).LoadAttributes()) } // TODO TestAddTestPullRequestTask @@ -226,7 +227,7 @@ func TestPullRequestList_LoadAttributes(t *testing.T) { func TestPullRequest_IsWorkInProgress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) pr.LoadIssue() assert.False(t, pr.IsWorkInProgress()) @@ -241,7 +242,7 @@ func TestPullRequest_IsWorkInProgress(t *testing.T) { func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &PullRequest{ID: 2}).(*PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) pr.LoadIssue() assert.Empty(t, pr.GetWorkInProgressPrefix()) @@ -253,3 +254,24 @@ func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) { pr.Issue.Title = "[wip] " + original assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix()) } + +func TestDeleteOrphanedObjects(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + countBefore, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) + assert.NoError(t, err) + + _, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003}) + assert.NoError(t, err) + + orphaned, err := db.CountOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id") + assert.NoError(t, err) + assert.EqualValues(t, 3, orphaned) + + err = db.DeleteOrphanedObjects("pull_request", "issue", "pull_request.issue_id=issue.id") + assert.NoError(t, err) + + countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) + assert.NoError(t, err) + assert.EqualValues(t, countBefore, countAfter) +} diff --git a/models/issues/reaction_test.go b/models/issues/reaction_test.go index b1216a3a69..ee1b6687a2 100644 --- a/models/issues/reaction_test.go +++ b/models/issues/reaction_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package issues +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -17,12 +18,12 @@ import ( ) func addReaction(t *testing.T, doerID, issueID, commentID int64, content string) { - var reaction *Reaction + var reaction *issues_model.Reaction var err error if commentID == 0 { - reaction, err = CreateIssueReaction(doerID, issueID, content) + reaction, err = issues_model.CreateIssueReaction(doerID, issueID, content) } else { - reaction, err = CreateCommentReaction(doerID, issueID, commentID, content) + reaction, err = issues_model.CreateCommentReaction(doerID, issueID, commentID, content) } assert.NoError(t, err) assert.NotNil(t, reaction) @@ -37,7 +38,7 @@ func TestIssueAddReaction(t *testing.T) { addReaction(t, user1.ID, issue1ID, 0, "heart") - unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) } func TestIssueAddDuplicateReaction(t *testing.T) { @@ -49,15 +50,15 @@ func TestIssueAddDuplicateReaction(t *testing.T) { addReaction(t, user1.ID, issue1ID, 0, "heart") - reaction, err := CreateReaction(&ReactionOptions{ + reaction, err := issues_model.CreateReaction(&issues_model.ReactionOptions{ DoerID: user1.ID, IssueID: issue1ID, Type: "heart", }) assert.Error(t, err) - assert.Equal(t, ErrReactionAlreadyExist{Reaction: "heart"}, err) + assert.Equal(t, issues_model.ErrReactionAlreadyExist{Reaction: "heart"}, err) - existingR := unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}).(*Reaction) + existingR := unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}).(*issues_model.Reaction) assert.Equal(t, existingR.ID, reaction.ID) } @@ -70,10 +71,10 @@ func TestIssueDeleteReaction(t *testing.T) { addReaction(t, user1.ID, issue1ID, 0, "heart") - err := DeleteIssueReaction(user1.ID, issue1ID, "heart") + err := issues_model.DeleteIssueReaction(user1.ID, issue1ID, "heart") assert.NoError(t, err) - unittest.AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) + unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) } func TestIssueReactionCount(t *testing.T) { @@ -98,7 +99,7 @@ func TestIssueReactionCount(t *testing.T) { addReaction(t, user4.ID, issueID, 0, "heart") addReaction(t, ghost.ID, issueID, 0, "-1") - reactionsList, _, err := FindReactions(db.DefaultContext, FindReactionsOptions{ + reactionsList, _, err := issues_model.FindReactions(db.DefaultContext, issues_model.FindReactionsOptions{ IssueID: issueID, }) assert.NoError(t, err) @@ -128,7 +129,7 @@ func TestIssueCommentAddReaction(t *testing.T) { addReaction(t, user1.ID, issue1ID, comment1ID, "heart") - unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) } func TestIssueCommentDeleteReaction(t *testing.T) { @@ -147,7 +148,7 @@ func TestIssueCommentDeleteReaction(t *testing.T) { addReaction(t, user3.ID, issue1ID, comment1ID, "heart") addReaction(t, user4.ID, issue1ID, comment1ID, "+1") - reactionsList, _, err := FindReactions(db.DefaultContext, FindReactionsOptions{ + reactionsList, _, err := issues_model.FindReactions(db.DefaultContext, issues_model.FindReactionsOptions{ IssueID: issue1ID, CommentID: comment1ID, }) @@ -168,7 +169,7 @@ func TestIssueCommentReactionCount(t *testing.T) { var comment1ID int64 = 1 addReaction(t, user1.ID, issue1ID, comment1ID, "heart") - assert.NoError(t, DeleteCommentReaction(user1.ID, issue1ID, comment1ID, "heart")) + assert.NoError(t, issues_model.DeleteCommentReaction(user1.ID, issue1ID, comment1ID, "heart")) - unittest.AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) + unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) } diff --git a/models/review.go b/models/issues/review.go similarity index 94% rename from models/review.go rename to models/issues/review.go index e92caba938..ee65bec3f8 100644 --- a/models/review.go +++ b/models/issues/review.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -17,11 +17,47 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "xorm.io/builder" ) +// ErrReviewNotExist represents a "ReviewNotExist" kind of error. +type ErrReviewNotExist struct { + ID int64 +} + +// IsErrReviewNotExist checks if an error is a ErrReviewNotExist. +func IsErrReviewNotExist(err error) bool { + _, ok := err.(ErrReviewNotExist) + return ok +} + +func (err ErrReviewNotExist) Error() string { + return fmt.Sprintf("review does not exist [id: %d]", err.ID) +} + +// ErrNotValidReviewRequest an not allowed review request modify +type ErrNotValidReviewRequest struct { + Reason string + UserID int64 + RepoID int64 +} + +// IsErrNotValidReviewRequest checks if an error is a ErrNotValidReviewRequest. +func IsErrNotValidReviewRequest(err error) bool { + _, ok := err.(ErrNotValidReviewRequest) + return ok +} + +func (err ErrNotValidReviewRequest) Error() string { + return fmt.Sprintf("%s [user_id: %d, repo_id: %d]", + err.Reason, + err.UserID, + err.RepoID) +} + // ReviewType defines the sort of feedback a review gives type ReviewType int @@ -105,7 +141,7 @@ func (r *Review) loadIssue(ctx context.Context) (err error) { if r.Issue != nil { return } - r.Issue, err = getIssueByID(ctx, r.IssueID) + r.Issue, err = GetIssueByID(ctx, r.IssueID) return } @@ -967,3 +1003,16 @@ func (r *Review) GetExternalName() string { return r.OriginalAuthor } // GetExternalID ExternalUserRemappable interface func (r *Review) GetExternalID() int64 { return r.OriginalAuthorID } + +// UpdateReviewsMigrationsByType updates reviews' migrations information via given git service type and original id and poster id +func UpdateReviewsMigrationsByType(tp structs.GitServiceType, originalAuthorID string, posterID int64) error { + _, err := db.GetEngine(db.DefaultContext).Table("review"). + Where("original_author_id = ?", originalAuthorID). + And(migratedIssueCond(tp)). + Update(map[string]interface{}{ + "reviewer_id": posterID, + "original_author": "", + "original_author_id": 0, + }) + return err +} diff --git a/models/review_test.go b/models/issues/review_test.go similarity index 50% rename from models/review_test.go rename to models/issues/review_test.go index 93291f9f57..3506604b46 100644 --- a/models/review_test.go +++ b/models/issues/review_test.go @@ -2,12 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -16,34 +17,34 @@ import ( func TestGetReviewByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review, err := GetReviewByID(db.DefaultContext, 1) + review, err := issues_model.GetReviewByID(db.DefaultContext, 1) assert.NoError(t, err) assert.Equal(t, "Demo Review", review.Content) - assert.Equal(t, ReviewTypeApprove, review.Type) + assert.Equal(t, issues_model.ReviewTypeApprove, review.Type) - _, err = GetReviewByID(db.DefaultContext, 23892) + _, err = issues_model.GetReviewByID(db.DefaultContext, 23892) assert.Error(t, err) - assert.True(t, IsErrReviewNotExist(err), "IsErrReviewNotExist") + assert.True(t, issues_model.IsErrReviewNotExist(err), "IsErrReviewNotExist") } func TestReview_LoadAttributes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review := unittest.AssertExistsAndLoadBean(t, &Review{ID: 1}).(*Review) + review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 1}).(*issues_model.Review) assert.NoError(t, review.LoadAttributes(db.DefaultContext)) assert.NotNil(t, review.Issue) assert.NotNil(t, review.Reviewer) - invalidReview1 := unittest.AssertExistsAndLoadBean(t, &Review{ID: 2}).(*Review) + invalidReview1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 2}).(*issues_model.Review) assert.Error(t, invalidReview1.LoadAttributes(db.DefaultContext)) - invalidReview2 := unittest.AssertExistsAndLoadBean(t, &Review{ID: 3}).(*Review) + invalidReview2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 3}).(*issues_model.Review) assert.Error(t, invalidReview2.LoadAttributes(db.DefaultContext)) } func TestReview_LoadCodeComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - review := unittest.AssertExistsAndLoadBean(t, &Review{ID: 4}).(*Review) + review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 4}).(*issues_model.Review) assert.NoError(t, review.LoadAttributes(db.DefaultContext)) assert.NoError(t, review.LoadCodeComments(db.DefaultContext)) assert.Len(t, review.CodeComments, 1) @@ -51,18 +52,18 @@ func TestReview_LoadCodeComments(t *testing.T) { } func TestReviewType_Icon(t *testing.T) { - assert.Equal(t, "check", ReviewTypeApprove.Icon()) - assert.Equal(t, "diff", ReviewTypeReject.Icon()) - assert.Equal(t, "comment", ReviewTypeComment.Icon()) - assert.Equal(t, "comment", ReviewTypeUnknown.Icon()) - assert.Equal(t, "dot-fill", ReviewTypeRequest.Icon()) - assert.Equal(t, "comment", ReviewType(6).Icon()) + assert.Equal(t, "check", issues_model.ReviewTypeApprove.Icon()) + assert.Equal(t, "diff", issues_model.ReviewTypeReject.Icon()) + assert.Equal(t, "comment", issues_model.ReviewTypeComment.Icon()) + assert.Equal(t, "comment", issues_model.ReviewTypeUnknown.Icon()) + assert.Equal(t, "dot-fill", issues_model.ReviewTypeRequest.Icon()) + assert.Equal(t, "comment", issues_model.ReviewType(6).Icon()) } func TestFindReviews(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - reviews, err := FindReviews(db.DefaultContext, FindReviewOptions{ - Type: ReviewTypeApprove, + reviews, err := issues_model.FindReviews(db.DefaultContext, issues_model.FindReviewOptions{ + Type: issues_model.ReviewTypeApprove, IssueID: 2, ReviewerID: 1, }) @@ -73,66 +74,66 @@ func TestFindReviews(t *testing.T) { func TestGetCurrentReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - review, err := GetCurrentReview(db.DefaultContext, user, issue) + review, err := issues_model.GetCurrentReview(db.DefaultContext, user, issue) assert.NoError(t, err) assert.NotNil(t, review) - assert.Equal(t, ReviewTypePending, review.Type) + assert.Equal(t, issues_model.ReviewTypePending, review.Type) assert.Equal(t, "Pending Review", review.Content) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 7}).(*user_model.User) - review2, err := GetCurrentReview(db.DefaultContext, user2, issue) + review2, err := issues_model.GetCurrentReview(db.DefaultContext, user2, issue) assert.Error(t, err) - assert.True(t, IsErrReviewNotExist(err)) + assert.True(t, issues_model.IsErrReviewNotExist(err)) assert.Nil(t, review2) } func TestCreateReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) - review, err := CreateReview(db.DefaultContext, CreateReviewOptions{ + review, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ Content: "New Review", - Type: ReviewTypePending, + Type: issues_model.ReviewTypePending, Issue: issue, Reviewer: user, }) assert.NoError(t, err) assert.Equal(t, "New Review", review.Content) - unittest.AssertExistsAndLoadBean(t, &Review{Content: "New Review"}) + unittest.AssertExistsAndLoadBean(t, &issues_model.Review{Content: "New Review"}) } func TestGetReviewersByIssueID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 3}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) - expectedReviews := []*Review{} + expectedReviews := []*issues_model.Review{} expectedReviews = append(expectedReviews, - &Review{ + &issues_model.Review{ Reviewer: user3, - Type: ReviewTypeReject, + Type: issues_model.ReviewTypeReject, UpdatedUnix: 946684812, }, - &Review{ + &issues_model.Review{ Reviewer: user4, - Type: ReviewTypeApprove, + Type: issues_model.ReviewTypeApprove, UpdatedUnix: 946684813, }, - &Review{ + &issues_model.Review{ Reviewer: user2, - Type: ReviewTypeReject, + Type: issues_model.ReviewTypeReject, UpdatedUnix: 946684814, }) - allReviews, err := GetReviewersByIssueID(issue.ID) + allReviews, err := issues_model.GetReviewersByIssueID(issue.ID) for _, reviewer := range allReviews { assert.NoError(t, reviewer.LoadReviewer()) } @@ -149,53 +150,53 @@ func TestGetReviewersByIssueID(t *testing.T) { func TestDismissReview(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample := unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) - approveReviewExample := unittest.AssertExistsAndLoadBean(t, &Review{ID: 8}).(*Review) + rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) + approveReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 8}).(*issues_model.Review) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(rejectReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(rejectReviewExample, true)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) - assert.NoError(t, DismissReview(requestReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(requestReviewExample, true)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(requestReviewExample, true)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(requestReviewExample, true)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(requestReviewExample, false)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(requestReviewExample, false)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(requestReviewExample, false)) - rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 9}).(*Review) - requestReviewExample = unittest.AssertExistsAndLoadBean(t, &Review{ID: 11}).(*Review) + assert.NoError(t, issues_model.DismissReview(requestReviewExample, false)) + rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review) + requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review) assert.True(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(rejectReviewExample, false)) + assert.NoError(t, issues_model.DismissReview(rejectReviewExample, false)) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.False(t, approveReviewExample.Dismissed) - assert.NoError(t, DismissReview(approveReviewExample, true)) + assert.NoError(t, issues_model.DismissReview(approveReviewExample, true)) assert.False(t, rejectReviewExample.Dismissed) assert.False(t, requestReviewExample.Dismissed) assert.True(t, approveReviewExample.Dismissed) diff --git a/models/issue_stopwatch.go b/models/issues/stopwatch.go similarity index 99% rename from models/issue_stopwatch.go rename to models/issues/stopwatch.go index 2cb4a62bd3..e7ac1314e9 100644 --- a/models/issue_stopwatch.go +++ b/models/issues/stopwatch.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -215,7 +215,7 @@ func CreateIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss return err } if exists { - issue, err := getIssueByID(ctx, sw.IssueID) + issue, err := GetIssueByID(ctx, sw.IssueID) if err != nil { return err } diff --git a/models/issues/stopwatch_test.go b/models/issues/stopwatch_test.go new file mode 100644 index 0000000000..c0573964d5 --- /dev/null +++ b/models/issues/stopwatch_test.go @@ -0,0 +1,79 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package issues_test + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/timeutil" + + "github.com/stretchr/testify/assert" +) + +func TestCancelStopwatch(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + user1, err := user_model.GetUserByID(1) + assert.NoError(t, err) + + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + assert.NoError(t, err) + issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) + assert.NoError(t, err) + + err = issues_model.CancelStopwatch(user1, issue1) + assert.NoError(t, err) + unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: user1.ID, IssueID: issue1.ID}) + + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeCancelTracking, PosterID: user1.ID, IssueID: issue1.ID}) + + assert.Nil(t, issues_model.CancelStopwatch(user1, issue2)) +} + +func TestStopwatchExists(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + assert.True(t, issues_model.StopwatchExists(1, 1)) + assert.False(t, issues_model.StopwatchExists(1, 2)) +} + +func TestHasUserStopwatch(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + exists, sw, err := issues_model.HasUserStopwatch(db.DefaultContext, 1) + assert.NoError(t, err) + assert.True(t, exists) + assert.Equal(t, int64(1), sw.ID) + + exists, _, err = issues_model.HasUserStopwatch(db.DefaultContext, 3) + assert.NoError(t, err) + assert.False(t, exists) +} + +func TestCreateOrStopIssueStopwatch(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + user2, err := user_model.GetUserByID(2) + assert.NoError(t, err) + user3, err := user_model.GetUserByID(3) + assert.NoError(t, err) + + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + assert.NoError(t, err) + issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) + assert.NoError(t, err) + + assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(user3, issue1)) + sw := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: 3, IssueID: 1}).(*issues_model.Stopwatch) + assert.LessOrEqual(t, sw.CreatedUnix, timeutil.TimeStampNow()) + + assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(user2, issue2)) + unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: 2, IssueID: 2}) + unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 2, IssueID: 2}) +} diff --git a/models/issue_tracked_time.go b/models/issues/tracked_time.go similarity index 99% rename from models/issue_tracked_time.go rename to models/issues/tracked_time.go index 30b3905bbc..54179bd3ab 100644 --- a/models/issue_tracked_time.go +++ b/models/issues/tracked_time.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues import ( "context" @@ -48,7 +48,7 @@ func (t *TrackedTime) LoadAttributes() (err error) { func (t *TrackedTime) loadAttributes(ctx context.Context) (err error) { if t.Issue == nil { - t.Issue, err = getIssueByID(ctx, t.IssueID) + t.Issue, err = GetIssueByID(ctx, t.IssueID) if err != nil { return } diff --git a/models/issue_tracked_time_test.go b/models/issues/tracked_time_test.go similarity index 56% rename from models/issue_tracked_time_test.go rename to models/issues/tracked_time_test.go index a628329712..787ba9b701 100644 --- a/models/issue_tracked_time_test.go +++ b/models/issues/tracked_time_test.go @@ -2,13 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package models +package issues_test import ( "testing" "time" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -21,20 +22,20 @@ func TestAddTime(t *testing.T) { user3, err := user_model.GetUserByID(3) assert.NoError(t, err) - issue1, err := GetIssueByID(1) + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) assert.NoError(t, err) // 3661 = 1h 1min 1s - trackedTime, err := AddTime(user3, issue1, 3661, time.Now()) + trackedTime, err := issues_model.AddTime(user3, issue1, 3661, time.Now()) assert.NoError(t, err) assert.Equal(t, int64(3), trackedTime.UserID) assert.Equal(t, int64(1), trackedTime.IssueID) assert.Equal(t, int64(3661), trackedTime.Time) - tt := unittest.AssertExistsAndLoadBean(t, &TrackedTime{UserID: 3, IssueID: 1}).(*TrackedTime) + tt := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 3, IssueID: 1}).(*issues_model.TrackedTime) assert.Equal(t, int64(3661), tt.Time) - comment := unittest.AssertExistsAndLoadBean(t, &Comment{Type: CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}).(*Comment) + comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}).(*issues_model.Comment) assert.Equal(t, comment.Content, "1 hour 1 minute") } @@ -42,39 +43,39 @@ func TestGetTrackedTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // by Issue - times, err := GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{IssueID: 1}) + times, err := issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 1}) assert.NoError(t, err) assert.Len(t, times, 1) assert.Equal(t, int64(400), times[0].Time) - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{IssueID: -1}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: -1}) assert.NoError(t, err) assert.Len(t, times, 0) // by User - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{UserID: 1}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 1}) assert.NoError(t, err) assert.Len(t, times, 3) assert.Equal(t, int64(400), times[0].Time) - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{UserID: 3}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 3}) assert.NoError(t, err) assert.Len(t, times, 0) // by Repo - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{RepositoryID: 2}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 2}) assert.NoError(t, err) assert.Len(t, times, 3) assert.Equal(t, int64(1), times[0].Time) - issue, err := GetIssueByID(times[0].IssueID) + issue, err := issues_model.GetIssueByID(db.DefaultContext, times[0].IssueID) assert.NoError(t, err) assert.Equal(t, issue.RepoID, int64(2)) - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{RepositoryID: 1}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 1}) assert.NoError(t, err) assert.Len(t, times, 5) - times, err = GetTrackedTimes(db.DefaultContext, &FindTrackedTimesOptions{RepositoryID: 10}) + times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 10}) assert.NoError(t, err) assert.Len(t, times, 0) } @@ -82,7 +83,7 @@ func TestGetTrackedTimes(t *testing.T) { func TestTotalTimes(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - total, err := TotalTimes(&FindTrackedTimesOptions{IssueID: 1}) + total, err := issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 1}) assert.NoError(t, err) assert.Len(t, total, 1) for user, time := range total { @@ -90,7 +91,7 @@ func TestTotalTimes(t *testing.T) { assert.Equal(t, "6 minutes 40 seconds", time) } - total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 2}) + total, err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 2}) assert.NoError(t, err) assert.Len(t, total, 2) for user, time := range total { @@ -103,7 +104,7 @@ func TestTotalTimes(t *testing.T) { } } - total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 5}) + total, err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 5}) assert.NoError(t, err) assert.Len(t, total, 1) for user, time := range total { @@ -111,7 +112,7 @@ func TestTotalTimes(t *testing.T) { assert.Equal(t, "1 second", time) } - total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 4}) + total, err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: 4}) assert.NoError(t, err) assert.Len(t, total, 2) } diff --git a/models/main_test.go b/models/main_test.go index 96231e4704..bb2fedc15a 100644 --- a/models/main_test.go +++ b/models/main_test.go @@ -7,7 +7,6 @@ package models import ( "testing" - issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -28,10 +27,6 @@ func TestFixturesAreConsistent(t *testing.T) { unittest.CheckConsistencyFor(t, &user_model.User{}, &repo_model.Repository{}, - &Issue{}, - &PullRequest{}, - &issues_model.Milestone{}, - &Label{}, &organization.Team{}, &Action{}) } diff --git a/models/migrate.go b/models/migrate.go index 7b12bc9c93..0af3891cb8 100644 --- a/models/migrate.go +++ b/models/migrate.go @@ -10,8 +10,6 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/structs" - - "xorm.io/builder" ) // InsertMilestones creates milestones of repository. @@ -41,7 +39,7 @@ func InsertMilestones(ms ...*issues_model.Milestone) (err error) { } // InsertIssues insert issues to database -func InsertIssues(issues ...*Issue) error { +func InsertIssues(issues ...*issues_model.Issue) error { ctx, committer, err := db.TxContext() if err != nil { return err @@ -56,14 +54,14 @@ func InsertIssues(issues ...*Issue) error { return committer.Commit() } -func insertIssue(ctx context.Context, issue *Issue) error { +func insertIssue(ctx context.Context, issue *issues_model.Issue) error { sess := db.GetEngine(ctx) if _, err := sess.NoAutoTime().Insert(issue); err != nil { return err } - issueLabels := make([]IssueLabel, 0, len(issue.Labels)) + issueLabels := make([]issues_model.IssueLabel, 0, len(issue.Labels)) for _, label := range issue.Labels { - issueLabels = append(issueLabels, IssueLabel{ + issueLabels = append(issueLabels, issues_model.IssueLabel{ IssueID: issue.ID, LabelID: label.ID, }) @@ -95,7 +93,7 @@ func insertIssue(ctx context.Context, issue *Issue) error { } // InsertIssueComments inserts many comments of issues. -func InsertIssueComments(comments []*Comment) error { +func InsertIssueComments(comments []*issues_model.Comment) error { if len(comments) == 0 { return nil } @@ -127,7 +125,8 @@ func InsertIssueComments(comments []*Comment) error { } for issueID := range issueIDs { - if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?", issueID, CommentTypeComment, issueID); err != nil { + if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?", + issueID, issues_model.CommentTypeComment, issueID); err != nil { return err } } @@ -135,7 +134,7 @@ func InsertIssueComments(comments []*Comment) error { } // InsertPullRequests inserted pull requests -func InsertPullRequests(prs ...*PullRequest) error { +func InsertPullRequests(prs ...*issues_model.PullRequest) error { ctx, committer, err := db.TxContext() if err != nil { return err @@ -182,37 +181,13 @@ func InsertReleases(rels ...*Release) error { return committer.Commit() } -func migratedIssueCond(tp structs.GitServiceType) builder.Cond { - return builder.In("issue_id", - builder.Select("issue.id"). - From("issue"). - InnerJoin("repository", "issue.repo_id = repository.id"). - Where(builder.Eq{ - "repository.original_service_type": tp, - }), - ) -} - -// UpdateReviewsMigrationsByType updates reviews' migrations information via given git service type and original id and poster id -func UpdateReviewsMigrationsByType(tp structs.GitServiceType, originalAuthorID string, posterID int64) error { - _, err := db.GetEngine(db.DefaultContext).Table("review"). - Where("original_author_id = ?", originalAuthorID). - And(migratedIssueCond(tp)). - Update(map[string]interface{}{ - "reviewer_id": posterID, - "original_author": "", - "original_author_id": 0, - }) - return err -} - // UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, userID int64) error { - if err := UpdateIssuesMigrationsByType(tp, externalUserID, userID); err != nil { + if err := issues_model.UpdateIssuesMigrationsByType(tp, externalUserID, userID); err != nil { return err } - if err := UpdateCommentsMigrationsByType(tp, externalUserID, userID); err != nil { + if err := issues_model.UpdateCommentsMigrationsByType(tp, externalUserID, userID); err != nil { return err } @@ -220,8 +195,8 @@ func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, us return err } - if err := UpdateReactionsMigrationsByType(tp, externalUserID, userID); err != nil { + if err := issues_model.UpdateReactionsMigrationsByType(tp, externalUserID, userID); err != nil { return err } - return UpdateReviewsMigrationsByType(tp, externalUserID, userID) + return issues_model.UpdateReviewsMigrationsByType(tp, externalUserID, userID) } diff --git a/models/migrate_test.go b/models/migrate_test.go index ce28b3ca7c..b6525278ec 100644 --- a/models/migrate_test.go +++ b/models/migrate_test.go @@ -41,7 +41,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { reponame := "repo1" repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone) assert.EqualValues(t, milestone.ID, 1) reaction := &issues_model.Reaction{ @@ -51,7 +51,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { foreignIndex := int64(12345) title := "issuetitle1" - is := &Issue{ + is := &issues_model.Issue{ RepoID: repo.ID, MilestoneID: milestone.ID, Repo: repo, @@ -61,7 +61,7 @@ func assertCreateIssues(t *testing.T, isPull bool) { PosterID: owner.ID, Poster: owner, IsClosed: true, - Labels: []*Label{label}, + Labels: []*issues_model.Label{label}, Reactions: []*issues_model.Reaction{reaction}, ForeignReference: &foreignreference.ForeignReference{ ForeignIndex: strconv.FormatInt(foreignIndex, 10), @@ -72,9 +72,9 @@ func assertCreateIssues(t *testing.T, isPull bool) { err := InsertIssues(is) assert.NoError(t, err) - i := unittest.AssertExistsAndLoadBean(t, &Issue{Title: title}).(*Issue) + i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title}).(*issues_model.Issue) assert.Nil(t, i.ForeignReference) - err = i.LoadAttributes() + err = i.LoadAttributes(db.DefaultContext) assert.NoError(t, err) assert.EqualValues(t, strconv.FormatInt(foreignIndex, 10), i.ForeignReference.ForeignIndex) unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: owner.ID, IssueID: i.ID}) @@ -90,7 +90,7 @@ func TestMigrate_CreateIssuesIsPullTrue(t *testing.T) { func TestMigrate_InsertIssueComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) _ = issue.LoadRepo(db.DefaultContext) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) reaction := &issues_model.Reaction{ @@ -98,7 +98,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) { UserID: owner.ID, } - comment := &Comment{ + comment := &issues_model.Comment{ PosterID: owner.ID, Poster: owner, IssueID: issue.ID, @@ -106,13 +106,13 @@ func TestMigrate_InsertIssueComments(t *testing.T) { Reactions: []*issues_model.Reaction{reaction}, } - err := InsertIssueComments([]*Comment{comment}) + err := InsertIssueComments([]*issues_model.Comment{comment}) assert.NoError(t, err) - issueModified := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) + issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) assert.EqualValues(t, issue.NumComments+1, issueModified.NumComments) - unittest.CheckConsistencyFor(t, &Issue{}) + unittest.CheckConsistencyFor(t, &issues_model.Issue{}) } func TestMigrate_InsertPullRequests(t *testing.T) { @@ -121,7 +121,7 @@ func TestMigrate_InsertPullRequests(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) - i := &Issue{ + i := &issues_model.Issue{ RepoID: repo.ID, Repo: repo, Title: "title1", @@ -131,16 +131,16 @@ func TestMigrate_InsertPullRequests(t *testing.T) { Poster: owner, } - p := &PullRequest{ + p := &issues_model.PullRequest{ Issue: i, } err := InsertPullRequests(p) assert.NoError(t, err) - _ = unittest.AssertExistsAndLoadBean(t, &PullRequest{IssueID: i.ID}).(*PullRequest) + _ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID}).(*issues_model.PullRequest) - unittest.CheckConsistencyFor(t, &Issue{}, &PullRequest{}) + unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.PullRequest{}) } func TestMigrate_InsertReleases(t *testing.T) { diff --git a/models/migrations/v111.go b/models/migrations/v111.go index 02624da66a..65fe7c5332 100644 --- a/models/migrations/v111.go +++ b/models/migrations/v111.go @@ -131,7 +131,7 @@ func addBranchProtectionCanPushAndEnableWhitelist(x *xorm.Engine) error { Authorize int } - // getUserRepoPermission static function based on models.IsOfficialReviewer at 5d78792385 + // getUserRepoPermission static function based on issues_model.IsOfficialReviewer at 5d78792385 getUserRepoPermission := func(sess *xorm.Session, repo *Repository, user *User) (Permission, error) { var perm Permission diff --git a/models/notification.go b/models/notification.go index ac5abc6f92..3f0e374b83 100644 --- a/models/notification.go +++ b/models/notification.go @@ -11,6 +11,7 @@ import ( "strconv" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -66,9 +67,9 @@ type Notification struct { UpdatedBy int64 `xorm:"INDEX NOT NULL"` - Issue *Issue `xorm:"-"` + Issue *issues_model.Issue `xorm:"-"` Repository *repo_model.Repository `xorm:"-"` - Comment *Comment `xorm:"-"` + Comment *issues_model.Comment `xorm:"-"` User *user_model.User `xorm:"-"` CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"` @@ -204,7 +205,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n return err } - issue, err := getIssueByID(ctx, issueID) + issue, err := issues_model.GetIssueByID(ctx, issueID) if err != nil { return err } @@ -214,14 +215,14 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n toNotify[receiverID] = struct{}{} } else { toNotify = make(map[int64]struct{}, 32) - issueWatches, err := GetIssueWatchersIDs(ctx, issueID, true) + issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true) if err != nil { return err } for _, id := range issueWatches { toNotify[id] = struct{}{} } - if !(issue.IsPull && HasWorkInProgressPrefix(issue.Title)) { + if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) { repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID) if err != nil { return err @@ -230,7 +231,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n toNotify[id] = struct{}{} } } - issueParticipants, err := issue.getParticipantIDsByIssue(ctx) + issueParticipants, err := issue.GetParticipantIDsByIssue(ctx) if err != nil { return err } @@ -241,7 +242,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n // dont notify user who cause notification delete(toNotify, notificationAuthorID) // explicit unwatch on issue - issueUnWatches, err := GetIssueWatchersIDs(ctx, issueID, false) + issueUnWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, false) if err != nil { return err } @@ -303,7 +304,7 @@ func notificationExists(notifications []*Notification, issueID, userID int64) bo return false } -func createIssueNotification(ctx context.Context, userID int64, issue *Issue, commentID, updatedByID int64) error { +func createIssueNotification(ctx context.Context, userID int64, issue *issues_model.Issue, commentID, updatedByID int64) error { notification := &Notification{ UserID: userID, RepoID: issue.RepoID, @@ -415,21 +416,21 @@ func (n *Notification) loadRepo(ctx context.Context) (err error) { func (n *Notification) loadIssue(ctx context.Context) (err error) { if n.Issue == nil && n.IssueID != 0 { - n.Issue, err = getIssueByID(ctx, n.IssueID) + n.Issue, err = issues_model.GetIssueByID(ctx, n.IssueID) if err != nil { return fmt.Errorf("getIssueByID [%d]: %v", n.IssueID, err) } - return n.Issue.loadAttributes(ctx) + return n.Issue.LoadAttributes(ctx) } return nil } func (n *Notification) loadComment(ctx context.Context) (err error) { if n.Comment == nil && n.CommentID != 0 { - n.Comment, err = GetCommentByID(ctx, n.CommentID) + n.Comment, err = issues_model.GetCommentByID(ctx, n.CommentID) if err != nil { - if IsErrCommentNotExist(err) { - return ErrCommentNotExist{ + if issues_model.IsErrCommentNotExist(err) { + return issues_model.ErrCommentNotExist{ ID: n.CommentID, IssueID: n.IssueID, } @@ -456,7 +457,7 @@ func (n *Notification) GetRepo() (*repo_model.Repository, error) { } // GetIssue returns the issue of the notification -func (n *Notification) GetIssue() (*Issue, error) { +func (n *Notification) GetIssue() (*issues_model.Issue, error) { return n.Issue, n.loadIssue(db.DefaultContext) } @@ -489,7 +490,7 @@ func (nl NotificationList) LoadAttributes() error { var err error for i := 0; i < len(nl); i++ { err = nl[i].LoadAttributes() - if err != nil && !IsErrCommentNotExist(err) { + if err != nil && !issues_model.IsErrCommentNotExist(err) { return err } } @@ -519,7 +520,7 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error) repos := make(map[int64]*repo_model.Repository, len(repoIDs)) left := len(repoIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } @@ -592,22 +593,22 @@ func (nl NotificationList) LoadIssues() ([]int, error) { } issueIDs := nl.getPendingIssueIDs() - issues := make(map[int64]*Issue, len(issueIDs)) + issues := make(map[int64]*issues_model.Issue, len(issueIDs)) left := len(issueIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } rows, err := db.GetEngine(db.DefaultContext). In("id", issueIDs[:limit]). - Rows(new(Issue)) + Rows(new(issues_model.Issue)) if err != nil { return nil, err } for rows.Next() { - var issue Issue + var issue issues_model.Issue err = rows.Scan(&issue) if err != nil { rows.Close() @@ -678,22 +679,22 @@ func (nl NotificationList) LoadComments() ([]int, error) { } commentIDs := nl.getPendingCommentIDs() - comments := make(map[int64]*Comment, len(commentIDs)) + comments := make(map[int64]*issues_model.Comment, len(commentIDs)) left := len(commentIDs) for left > 0 { - limit := defaultMaxInSize + limit := db.DefaultMaxInSize if left < limit { limit = left } rows, err := db.GetEngine(db.DefaultContext). In("id", commentIDs[:limit]). - Rows(new(Comment)) + Rows(new(issues_model.Comment)) if err != nil { return nil, err } for rows.Next() { - var comment Comment + var comment issues_model.Comment err = rows.Scan(&comment) if err != nil { rows.Close() @@ -747,6 +748,15 @@ func GetUIDsAndNotificationCounts(since, until timeutil.TimeStamp) ([]UserIDCoun return res, db.GetEngine(db.DefaultContext).SQL(sql, since, until, NotificationStatusUnread).Find(&res) } +// SetIssueReadBy sets issue to be read by given user. +func SetIssueReadBy(ctx context.Context, issueID, userID int64) error { + if err := issues_model.UpdateIssueUserByRead(userID, issueID); err != nil { + return err + } + + return setIssueNotificationStatusReadIfUnread(ctx, userID, issueID) +} + func setIssueNotificationStatusReadIfUnread(ctx context.Context, userID, issueID int64) error { notification, err := getIssueNotification(ctx, userID, issueID) // ignore if not exists diff --git a/models/notification_test.go b/models/notification_test.go index 15c29389c8..16ff02d6c0 100644 --- a/models/notification_test.go +++ b/models/notification_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -16,14 +17,14 @@ import ( func TestCreateOrUpdateIssueNotifications(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue) assert.NoError(t, CreateOrUpdateIssueNotifications(issue.ID, 0, 2, 0)) // User 9 is inactive, thus notifications for user 1 and 4 are created notf := unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID}).(*Notification) assert.Equal(t, NotificationStatusUnread, notf.Status) - unittest.CheckConsistencyFor(t, &Issue{ID: issue.ID}) + unittest.CheckConsistencyFor(t, &issues_model.Issue{ID: issue.ID}) notf = unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID}).(*Notification) assert.Equal(t, NotificationStatusUnread, notf.Status) diff --git a/models/org_team.go b/models/org_team.go index 7ff3095273..5d29e33337 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -13,6 +13,7 @@ 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/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -153,7 +154,7 @@ func removeAllRepositories(ctx context.Context, t *organization.Team) (err error } // Remove all IssueWatches a user has subscribed to in the repositories - if err = removeIssueWatchersByRepoID(ctx, user.ID, repo.ID); err != nil { + if err = issues_model.RemoveIssueWatchersByRepoID(ctx, user.ID, repo.ID); err != nil { return err } } @@ -216,7 +217,7 @@ func removeRepository(ctx context.Context, t *organization.Team, repo *repo_mode } // Remove all IssueWatches a user has subscribed to in the repositories - if err := removeIssueWatchersByRepoID(ctx, teamUser.UID, repo.ID); err != nil { + if err := issues_model.RemoveIssueWatchersByRepoID(ctx, teamUser.UID, repo.ID); err != nil { return err } } diff --git a/models/repo.go b/models/repo.go index a8aa18381d..e9d83f5f32 100644 --- a/models/repo.go +++ b/models/repo.go @@ -281,7 +281,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { &access_model.Access{RepoID: repo.ID}, &Action{RepoID: repo.ID}, &repo_model.Collaboration{RepoID: repoID}, - &Comment{RefRepoID: repoID}, + &issues_model.Comment{RefRepoID: repoID}, &git_model.CommitStatus{RepoID: repoID}, &git_model.DeletedBranch{RepoID: repoID}, &webhook.HookTask{RepoID: repoID}, @@ -306,18 +306,18 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { } // Delete Labels and related objects - if err := deleteLabelsByRepoID(ctx, repoID); err != nil { + if err := issues_model.DeleteLabelsByRepoID(ctx, repoID); err != nil { return err } // Delete Pulls and related objects - if err := deletePullsByBaseRepoID(ctx, repoID); err != nil { + if err := issues_model.DeletePullsByBaseRepoID(ctx, repoID); err != nil { return err } // Delete Issues and related objects var attachmentPaths []string - if attachmentPaths, err = deleteIssuesByRepoID(ctx, repoID); err != nil { + if attachmentPaths, err = issues_model.DeleteIssuesByRepoID(ctx, repoID); err != nil { return err } @@ -576,16 +576,11 @@ func repoStatsCorrectNum(ctx context.Context, id int64, isPull bool, field strin } func repoStatsCorrectNumClosedIssues(ctx context.Context, id int64) error { - return repoStatsCorrectNumClosed(ctx, id, false, "num_closed_issues") + return repo_model.StatsCorrectNumClosed(ctx, id, false, "num_closed_issues") } func repoStatsCorrectNumClosedPulls(ctx context.Context, id int64) error { - return repoStatsCorrectNumClosed(ctx, id, true, "num_closed_pulls") -} - -func repoStatsCorrectNumClosed(ctx context.Context, id int64, isPull bool, field string) error { - _, err := db.GetEngine(ctx).Exec("UPDATE `repository` SET "+field+"=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_closed=? AND is_pull=?) WHERE id=?", id, true, isPull, id) - return err + return repo_model.StatsCorrectNumClosed(ctx, id, true, "num_closed_pulls") } func statsQuery(args ...interface{}) func(context.Context) ([]map[string][]byte, error) { @@ -687,12 +682,11 @@ func CheckRepoStats(ctx context.Context) error { continue } - rawResult, err := e.Query("SELECT COUNT(*) FROM `repository` WHERE fork_id=?", repo.ID) + _, err = e.SQL("SELECT COUNT(*) FROM `repository` WHERE fork_id=?", repo.ID).Get(&repo.NumForks) if err != nil { log.Error("Select count of forks[%d]: %v", repo.ID, err) continue } - repo.NumForks = int(parseCountResult(rawResult)) if _, err = e.ID(repo.ID).Cols("num_forks").Update(repo); err != nil { log.Error("UpdateRepository[%d]: %v", id, err) diff --git a/models/repo/repo.go b/models/repo/repo.go index 57d85435eb..f6097d2d6a 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -25,6 +25,22 @@ import ( "code.gitea.io/gitea/modules/util" ) +// ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo. +type ErrUserDoesNotHaveAccessToRepo struct { + UserID int64 + RepoName string +} + +// IsErrUserDoesNotHaveAccessToRepo checks if an error is a ErrRepoFileAlreadyExists. +func IsErrUserDoesNotHaveAccessToRepo(err error) bool { + _, ok := err.(ErrUserDoesNotHaveAccessToRepo) + return ok +} + +func (err ErrUserDoesNotHaveAccessToRepo) Error() string { + return fmt.Sprintf("user doesn't have access to repo [user_id: %d, repo_name: %s]", err.UserID, err.RepoName) +} + var ( reservedRepoNames = []string{".", "..", "-"} reservedRepoPatterns = []string{"*.git", "*.wiki", "*.rss", "*.atom"} @@ -743,3 +759,34 @@ func CountRepositories(ctx context.Context, opts CountRepositoryOptions) (int64, } return count, nil } + +// StatsCorrectNumClosed update repository's issue related numbers +func StatsCorrectNumClosed(ctx context.Context, id int64, isPull bool, field string) error { + _, err := db.Exec(ctx, "UPDATE `repository` SET "+field+"=(SELECT COUNT(*) FROM `issue` WHERE repo_id=? AND is_closed=? AND is_pull=?) WHERE id=?", id, true, isPull, id) + return err +} + +// UpdateRepoIssueNumbers update repository issue numbers +func UpdateRepoIssueNumbers(ctx context.Context, repoID int64, isPull, isClosed bool) error { + e := db.GetEngine(ctx) + if isPull { + if _, err := e.ID(repoID).Decr("num_pulls").Update(new(Repository)); err != nil { + return err + } + if isClosed { + if _, err := e.ID(repoID).Decr("num_closed_pulls").Update(new(Repository)); err != nil { + return err + } + } + } else { + if _, err := e.ID(repoID).Decr("num_issues").Update(new(Repository)); err != nil { + return err + } + if isClosed { + if _, err := e.ID(repoID).Decr("num_closed_issues").Update(new(Repository)); err != nil { + return err + } + } + } + return nil +} diff --git a/models/repo_activity.go b/models/repo_activity.go index 06710ff1ac..6a3636ab07 100644 --- a/models/repo_activity.go +++ b/models/repo_activity.go @@ -11,6 +11,7 @@ import ( "time" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -29,15 +30,15 @@ type ActivityAuthorData struct { // ActivityStats represets issue and pull request information. type ActivityStats struct { - OpenedPRs PullRequestList + OpenedPRs issues_model.PullRequestList OpenedPRAuthorCount int64 - MergedPRs PullRequestList + MergedPRs issues_model.PullRequestList MergedPRAuthorCount int64 - OpenedIssues IssueList + OpenedIssues issues_model.IssueList OpenedIssueAuthorCount int64 - ClosedIssues IssueList + ClosedIssues issues_model.IssueList ClosedIssueAuthorCount int64 - UnresolvedIssues IssueList + UnresolvedIssues issues_model.IssueList PublishedReleases []*Release PublishedReleaseAuthorCount int64 Code *git.CodeActivityStats @@ -212,7 +213,7 @@ func (stats *ActivityStats) FillPullRequests(repoID int64, fromTime time.Time) e // Merged pull requests sess := pullRequestsForActivityStatement(repoID, fromTime, true) sess.OrderBy("pull_request.merged_unix DESC") - stats.MergedPRs = make(PullRequestList, 0) + stats.MergedPRs = make(issues_model.PullRequestList, 0) if err = sess.Find(&stats.MergedPRs); err != nil { return err } @@ -230,7 +231,7 @@ func (stats *ActivityStats) FillPullRequests(repoID int64, fromTime time.Time) e // Opened pull requests sess = pullRequestsForActivityStatement(repoID, fromTime, false) sess.OrderBy("issue.created_unix ASC") - stats.OpenedPRs = make(PullRequestList, 0) + stats.OpenedPRs = make(issues_model.PullRequestList, 0) if err = sess.Find(&stats.OpenedPRs); err != nil { return err } @@ -271,7 +272,7 @@ func (stats *ActivityStats) FillIssues(repoID int64, fromTime time.Time) error { // Closed issues sess := issuesForActivityStatement(repoID, fromTime, true, false) sess.OrderBy("issue.closed_unix DESC") - stats.ClosedIssues = make(IssueList, 0) + stats.ClosedIssues = make(issues_model.IssueList, 0) if err = sess.Find(&stats.ClosedIssues); err != nil { return err } @@ -286,7 +287,7 @@ func (stats *ActivityStats) FillIssues(repoID int64, fromTime time.Time) error { // New issues sess = issuesForActivityStatement(repoID, fromTime, false, false) sess.OrderBy("issue.created_unix ASC") - stats.OpenedIssues = make(IssueList, 0) + stats.OpenedIssues = make(issues_model.IssueList, 0) if err = sess.Find(&stats.OpenedIssues); err != nil { return err } @@ -312,7 +313,7 @@ func (stats *ActivityStats) FillUnresolvedIssues(repoID int64, fromTime time.Tim sess.And("issue.is_pull = ?", prs) } sess.OrderBy("issue.updated_unix DESC") - stats.UnresolvedIssues = make(IssueList, 0) + stats.UnresolvedIssues = make(issues_model.IssueList, 0) return sess.Find(&stats.UnresolvedIssues) } diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go index 7d43115b23..c8866421bd 100644 --- a/models/repo_collaboration.go +++ b/models/repo_collaboration.go @@ -10,6 +10,7 @@ import ( "fmt" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -101,7 +102,7 @@ func reconsiderRepoIssuesAssignee(ctx context.Context, repo *repo_model.Reposito if _, err := db.GetEngine(ctx).Where(builder.Eq{"assignee_id": uid}). In("issue_id", builder.Select("id").From("issue").Where(builder.Eq{"repo_id": repo.ID})). - Delete(&IssueAssignees{}); err != nil { + Delete(&issues_model.IssueAssignees{}); err != nil { return fmt.Errorf("Could not delete assignee[%d] %v", uid, err) } return nil @@ -116,5 +117,5 @@ func reconsiderWatches(ctx context.Context, repo *repo_model.Repository, uid int } // Remove all IssueWatches a user has subscribed to in the repository - return removeIssueWatchersByRepoID(ctx, uid, repo.ID) + return issues_model.RemoveIssueWatchersByRepoID(ctx, uid, repo.ID) } diff --git a/models/repo_transfer.go b/models/repo_transfer.go index 79cfc699c8..7d07fb252c 100644 --- a/models/repo_transfer.go +++ b/models/repo_transfer.go @@ -10,6 +10,7 @@ import ( "os" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" @@ -376,7 +377,7 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_mo INNER JOIN issue ON issue.id = com.issue_id WHERE com.type = ? AND issue.repo_id = ? AND ((label.org_id = 0 AND issue.repo_id != label.repo_id) OR (label.repo_id = 0 AND label.org_id != ?)) - ) AS il_too)`, CommentTypeLabel, repo.ID, newOwner.ID); err != nil { + ) AS il_too)`, issues_model.CommentTypeLabel, repo.ID, newOwner.ID); err != nil { return fmt.Errorf("Unable to remove old org label comments: %v", err) } } diff --git a/models/statistic.go b/models/statistic.go index dfc236ec58..55ace626c8 100644 --- a/models/statistic.go +++ b/models/statistic.go @@ -97,7 +97,7 @@ func GetStatistic() (stats Statistic) { stats.Counter.Issue = stats.Counter.IssueClosed + stats.Counter.IssueOpen - stats.Counter.Comment, _ = e.Count(new(Comment)) + stats.Counter.Comment, _ = e.Count(new(issues_model.Comment)) stats.Counter.Oauth = 0 stats.Counter.Follow, _ = e.Count(new(user_model.Follow)) stats.Counter.Mirror, _ = e.Count(new(repo_model.Mirror)) @@ -105,7 +105,7 @@ func GetStatistic() (stats Statistic) { stats.Counter.AuthSource = auth.CountSources() stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook)) stats.Counter.Milestone, _ = e.Count(new(issues_model.Milestone)) - stats.Counter.Label, _ = e.Count(new(Label)) + stats.Counter.Label, _ = e.Count(new(issues_model.Label)) stats.Counter.HookTask, _ = e.Count(new(webhook.HookTask)) stats.Counter.Team, _ = e.Count(new(organization.Team)) stats.Counter.Attachment, _ = e.Count(new(repo_model.Attachment)) diff --git a/models/user.go b/models/user.go index 59ec643d55..49374014aa 100644 --- a/models/user.go +++ b/models/user.go @@ -16,7 +16,7 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" - "code.gitea.io/gitea/models/issues" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" @@ -78,12 +78,12 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { &user_model.Follow{UserID: u.ID}, &user_model.Follow{FollowID: u.ID}, &Action{UserID: u.ID}, - &IssueUser{UID: u.ID}, + &issues_model.IssueUser{UID: u.ID}, &user_model.EmailAddress{UID: u.ID}, &user_model.UserOpenID{UID: u.ID}, - &issues.Reaction{UserID: u.ID}, + &issues_model.Reaction{UserID: u.ID}, &organization.TeamUser{UID: u.ID}, - &Stopwatch{UserID: u.ID}, + &issues_model.Stopwatch{UserID: u.ID}, &user_model.Setting{UserID: u.ID}, &pull_model.AutoMerge{DoerID: u.ID}, &pull_model.ReviewState{UserID: u.ID}, @@ -101,8 +101,8 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { // Delete Comments const batchSize = 50 for start := 0; ; start += batchSize { - comments := make([]*Comment, 0, batchSize) - if err = e.Where("type=? AND poster_id=?", CommentTypeComment, u.ID).Limit(batchSize, start).Find(&comments); err != nil { + comments := make([]*issues_model.Comment, 0, batchSize) + if err = e.Where("type=? AND poster_id=?", issues_model.CommentTypeComment, u.ID).Limit(batchSize, start).Find(&comments); err != nil { return err } if len(comments) == 0 { @@ -110,14 +110,14 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { } for _, comment := range comments { - if err = deleteComment(ctx, comment); err != nil { + if err = issues_model.DeleteComment(ctx, comment); err != nil { return err } } } // Delete Reactions - if err = issues.DeleteReaction(ctx, &issues.ReactionOptions{DoerID: u.ID}); err != nil { + if err = issues_model.DeleteReaction(ctx, &issues_model.ReactionOptions{DoerID: u.ID}); err != nil { return err } } @@ -189,7 +189,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { // ***** END: GPGPublicKey ***** // Clear assignee. - if _, err = db.DeleteByBean(ctx, &IssueAssignees{AssigneeID: u.ID}); err != nil { + if _, err = db.DeleteByBean(ctx, &issues_model.IssueAssignees{AssigneeID: u.ID}); err != nil { return fmt.Errorf("clear assignee: %v", err) } diff --git a/modules/context/repo.go b/modules/context/repo.go index 05ced909a8..c2b8306b9d 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" 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" @@ -83,7 +84,7 @@ type Repository struct { // CanWriteToBranch checks if the branch is writable by the user func (r *Repository) CanWriteToBranch(user *user_model.User, branch string) bool { - return models.CanMaintainerWriteToBranch(r.Permission, branch, user) + return issues_model.CanMaintainerWriteToBranch(r.Permission, branch, user) } // CanEnableEditor returns true if repository is editable and user has proper access level. @@ -158,11 +159,11 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use } // CanUseTimetracker returns whether or not a user can use the timetracker. -func (r *Repository) CanUseTimetracker(issue *models.Issue, user *user_model.User) bool { +func (r *Repository) CanUseTimetracker(issue *issues_model.Issue, user *user_model.User) bool { // Checking for following: // 1. Is timetracker enabled // 2. Is the user a contributor, admin, poster or assignee and do the repository policies require this? - isAssigned, _ := models.IsUserAssignedToIssue(db.DefaultContext, issue, user) + isAssigned, _ := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user) return r.Repository.IsTimetrackerEnabled() && (!r.Repository.AllowOnlyContributorsToTrackTime() || r.Permission.CanWriteIssuesOrPulls(issue.IsPull) || issue.IsPoster(user.ID) || isAssigned) } diff --git a/modules/convert/convert.go b/modules/convert/convert.go index 4e8aa59067..c8cb23261e 100644 --- a/modules/convert/convert.go +++ b/modules/convert/convert.go @@ -11,11 +11,11 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/auth" "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/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -55,7 +55,7 @@ func ToBranch(repo *repo_model.Repository, b *git.Branch, c *git.Commit, bp *git if err != nil { return nil, err } - canPush = models.CanMaintainerWriteToBranch(perms, b.Name, user) + canPush = issues_model.CanMaintainerWriteToBranch(perms, b.Name, user) } return &api.Branch{ diff --git a/modules/convert/issue.go b/modules/convert/issue.go index a4512e424f..35eff05229 100644 --- a/modules/convert/issue.go +++ b/modules/convert/issue.go @@ -9,7 +9,6 @@ import ( "net/url" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" @@ -23,7 +22,7 @@ import ( // it assumes some fields assigned with values: // Required - Poster, Labels, // Optional - Milestone, Assignee, PullRequest -func ToAPIIssue(issue *models.Issue) *api.Issue { +func ToAPIIssue(issue *issues_model.Issue) *api.Issue { if err := issue.LoadLabels(db.DefaultContext); err != nil { return &api.Issue{} } @@ -100,7 +99,7 @@ func ToAPIIssue(issue *models.Issue) *api.Issue { } // ToAPIIssueList converts an IssueList to API format -func ToAPIIssueList(il models.IssueList) []*api.Issue { +func ToAPIIssueList(il issues_model.IssueList) []*api.Issue { result := make([]*api.Issue, len(il)) for i := range il { result[i] = ToAPIIssue(il[i]) @@ -109,7 +108,7 @@ func ToAPIIssueList(il models.IssueList) []*api.Issue { } // ToTrackedTime converts TrackedTime to API format -func ToTrackedTime(t *models.TrackedTime) (apiT *api.TrackedTime) { +func ToTrackedTime(t *issues_model.TrackedTime) (apiT *api.TrackedTime) { apiT = &api.TrackedTime{ ID: t.ID, IssueID: t.IssueID, @@ -128,13 +127,13 @@ func ToTrackedTime(t *models.TrackedTime) (apiT *api.TrackedTime) { } // ToStopWatches convert Stopwatch list to api.StopWatches -func ToStopWatches(sws []*models.Stopwatch) (api.StopWatches, error) { +func ToStopWatches(sws []*issues_model.Stopwatch) (api.StopWatches, error) { result := api.StopWatches(make([]api.StopWatch, 0, len(sws))) - issueCache := make(map[int64]*models.Issue) + issueCache := make(map[int64]*issues_model.Issue) repoCache := make(map[int64]*repo_model.Repository) var ( - issue *models.Issue + issue *issues_model.Issue repo *repo_model.Repository ok bool err error @@ -143,7 +142,7 @@ func ToStopWatches(sws []*models.Stopwatch) (api.StopWatches, error) { for _, sw := range sws { issue, ok = issueCache[sw.IssueID] if !ok { - issue, err = models.GetIssueByID(sw.IssueID) + issue, err = issues_model.GetIssueByID(db.DefaultContext, sw.IssueID) if err != nil { return nil, err } @@ -170,7 +169,7 @@ func ToStopWatches(sws []*models.Stopwatch) (api.StopWatches, error) { } // ToTrackedTimeList converts TrackedTimeList to API format -func ToTrackedTimeList(tl models.TrackedTimeList) api.TrackedTimeList { +func ToTrackedTimeList(tl issues_model.TrackedTimeList) api.TrackedTimeList { result := make([]*api.TrackedTime, 0, len(tl)) for _, t := range tl { result = append(result, ToTrackedTime(t)) @@ -179,7 +178,7 @@ func ToTrackedTimeList(tl models.TrackedTimeList) api.TrackedTimeList { } // ToLabel converts Label to API format -func ToLabel(label *models.Label, repo *repo_model.Repository, org *user_model.User) *api.Label { +func ToLabel(label *issues_model.Label, repo *repo_model.Repository, org *user_model.User) *api.Label { result := &api.Label{ ID: label.ID, Name: label.Name, @@ -206,7 +205,7 @@ func ToLabel(label *models.Label, repo *repo_model.Repository, org *user_model.U } // ToLabelList converts list of Label to API format -func ToLabelList(labels []*models.Label, repo *repo_model.Repository, org *user_model.User) []*api.Label { +func ToLabelList(labels []*issues_model.Label, repo *repo_model.Repository, org *user_model.User) []*api.Label { result := make([]*api.Label, len(labels)) for i := range labels { result[i] = ToLabel(labels[i], repo, org) diff --git a/modules/convert/issue_comment.go b/modules/convert/issue_comment.go index eaa7f64ea3..ccc94b2496 100644 --- a/modules/convert/issue_comment.go +++ b/modules/convert/issue_comment.go @@ -5,16 +5,16 @@ package convert import ( - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" ) -// ToComment converts a models.Comment to the api.Comment format -func ToComment(c *models.Comment) *api.Comment { +// ToComment converts a issues_model.Comment to the api.Comment format +func ToComment(c *issues_model.Comment) *api.Comment { return &api.Comment{ ID: c.ID, Poster: ToUser(c.Poster, nil), @@ -27,8 +27,8 @@ func ToComment(c *models.Comment) *api.Comment { } } -// ToTimelineComment converts a models.Comment to the api.TimelineComment format -func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineComment { +// ToTimelineComment converts a issues_model.Comment to the api.TimelineComment format +func ToTimelineComment(c *issues_model.Comment, doer *user_model.User) *api.TimelineComment { err := c.LoadMilestone() if err != nil { log.Error("LoadMilestone: %v", err) @@ -105,7 +105,7 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo } if c.RefIssueID != 0 { - issue, err := models.GetIssueByID(c.RefIssueID) + issue, err := issues_model.GetIssueByID(db.DefaultContext, c.RefIssueID) if err != nil { log.Error("GetIssueByID(%d): %v", c.RefIssueID, err) return nil @@ -114,7 +114,7 @@ func ToTimelineComment(c *models.Comment, doer *user_model.User) *api.TimelineCo } if c.RefCommentID != 0 { - com, err := models.GetCommentByID(db.DefaultContext, c.RefCommentID) + com, err := issues_model.GetCommentByID(db.DefaultContext, c.RefCommentID) if err != nil { log.Error("GetCommentByID(%d): %v", c.RefCommentID, err) return nil diff --git a/modules/convert/issue_test.go b/modules/convert/issue_test.go index b237c18f69..5bf04bcb52 100644 --- a/modules/convert/issue_test.go +++ b/modules/convert/issue_test.go @@ -9,7 +9,6 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -22,7 +21,7 @@ import ( func TestLabel_ToLabel(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - label := unittest.AssertExistsAndLoadBean(t, &models.Label{ID: 1}).(*models.Label) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID}).(*repo_model.Repository) assert.Equal(t, &api.Label{ ID: label.ID, diff --git a/modules/convert/pull.go b/modules/convert/pull.go index 310a7626c9..9c31f9bd2c 100644 --- a/modules/convert/pull.go +++ b/modules/convert/pull.go @@ -8,7 +8,7 @@ import ( "context" "fmt" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" user_model "code.gitea.io/gitea/models/user" @@ -20,7 +20,7 @@ import ( // ToAPIPullRequest assumes following fields have been assigned with valid values: // Required - Issue // Optional - Merger -func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_model.User) *api.PullRequest { +func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User) *api.PullRequest { var ( baseBranch *git.Branch headBranch *git.Branch @@ -114,7 +114,7 @@ func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_mo } } - if pr.Flow == models.PullRequestFlowAGit { + if pr.Flow == issues_model.PullRequestFlowAGit { gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) if err != nil { log.Error("OpenRepository[%s]: %v", pr.GetGitRefName(), err) @@ -132,7 +132,7 @@ func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_mo apiPullRequest.Head.Name = "" } - if pr.HeadRepo != nil && pr.Flow == models.PullRequestFlowGithub { + if pr.HeadRepo != nil && pr.Flow == issues_model.PullRequestFlowGithub { p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) if err != nil { log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) diff --git a/modules/convert/pull_review.go b/modules/convert/pull_review.go index 907ccafb66..93ce208224 100644 --- a/modules/convert/pull_review.go +++ b/modules/convert/pull_review.go @@ -8,13 +8,13 @@ import ( "context" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" ) // ToPullReview convert a review to api format -func ToPullReview(ctx context.Context, r *models.Review, doer *user_model.User) (*api.PullReview, error) { +func ToPullReview(ctx context.Context, r *issues_model.Review, doer *user_model.User) (*api.PullReview, error) { if err := r.LoadAttributes(ctx); err != nil { if !user_model.IsErrUserNotExist(err) { return nil, err @@ -44,15 +44,15 @@ func ToPullReview(ctx context.Context, r *models.Review, doer *user_model.User) } switch r.Type { - case models.ReviewTypeApprove: + case issues_model.ReviewTypeApprove: result.State = api.ReviewStateApproved - case models.ReviewTypeReject: + case issues_model.ReviewTypeReject: result.State = api.ReviewStateRequestChanges - case models.ReviewTypeComment: + case issues_model.ReviewTypeComment: result.State = api.ReviewStateComment - case models.ReviewTypePending: + case issues_model.ReviewTypePending: result.State = api.ReviewStatePending - case models.ReviewTypeRequest: + case issues_model.ReviewTypeRequest: result.State = api.ReviewStateRequestReview } @@ -60,11 +60,11 @@ func ToPullReview(ctx context.Context, r *models.Review, doer *user_model.User) } // ToPullReviewList convert a list of review to it's api format -func ToPullReviewList(ctx context.Context, rl []*models.Review, doer *user_model.User) ([]*api.PullReview, error) { +func ToPullReviewList(ctx context.Context, rl []*issues_model.Review, doer *user_model.User) ([]*api.PullReview, error) { result := make([]*api.PullReview, 0, len(rl)) for i := range rl { // show pending reviews only for the user who created them - if rl[i].Type == models.ReviewTypePending && !(doer.IsAdmin || doer.ID == rl[i].ReviewerID) { + if rl[i].Type == issues_model.ReviewTypePending && !(doer.IsAdmin || doer.ID == rl[i].ReviewerID) { continue } r, err := ToPullReview(ctx, rl[i], doer) @@ -77,7 +77,7 @@ func ToPullReviewList(ctx context.Context, rl []*models.Review, doer *user_model } // ToPullReviewCommentList convert the CodeComments of an review to it's api format -func ToPullReviewCommentList(ctx context.Context, review *models.Review, doer *user_model.User) ([]*api.PullReviewComment, error) { +func ToPullReviewCommentList(ctx context.Context, review *issues_model.Review, doer *user_model.User) ([]*api.PullReviewComment, error) { if err := review.LoadAttributes(ctx); err != nil { if !user_model.IsErrUserNotExist(err) { return nil, err diff --git a/modules/convert/pull_test.go b/modules/convert/pull_test.go index 8574ccfd26..10ef311399 100644 --- a/modules/convert/pull_test.go +++ b/modules/convert/pull_test.go @@ -7,7 +7,7 @@ package convert import ( "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" @@ -21,7 +21,7 @@ func TestPullRequest_APIFormat(t *testing.T) { // with HeadRepo assert.NoError(t, unittest.PrepareTestDatabase()) headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 1}).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadAttributes()) assert.NoError(t, pr.LoadIssue()) apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil) @@ -35,7 +35,7 @@ func TestPullRequest_APIFormat(t *testing.T) { }, apiPullRequest.Head) // withOut HeadRepo - pr = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 1}).(*models.PullRequest) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadIssue()) assert.NoError(t, pr.LoadAttributes()) // simulate fork deletion diff --git a/modules/doctor/dbconsistency.go b/modules/doctor/dbconsistency.go index 18cb2cdac6..b23807cca2 100644 --- a/modules/doctor/dbconsistency.go +++ b/modules/doctor/dbconsistency.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/migrations" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/log" @@ -64,10 +65,10 @@ func genericOrphanCheck(name, subject, refobject, joincond string) consistencyCh return consistencyCheck{ Name: name, Counter: func() (int64, error) { - return models.CountOrphanedObjects(subject, refobject, joincond) + return db.CountOrphanedObjects(subject, refobject, joincond) }, Fixer: func() (int64, error) { - err := models.DeleteOrphanedObjects(subject, refobject, joincond) + err := db.DeleteOrphanedObjects(subject, refobject, joincond) return -1, err }, } @@ -84,20 +85,20 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er { // find labels without existing repo or org Name: "Orphaned Labels without existing repository or organisation", - Counter: models.CountOrphanedLabels, - Fixer: asFixer(models.DeleteOrphanedLabels), + Counter: issues_model.CountOrphanedLabels, + Fixer: asFixer(issues_model.DeleteOrphanedLabels), }, { // find IssueLabels without existing label Name: "Orphaned Issue Labels without existing label", - Counter: models.CountOrphanedIssueLabels, - Fixer: asFixer(models.DeleteOrphanedIssueLabels), + Counter: issues_model.CountOrphanedIssueLabels, + Fixer: asFixer(issues_model.DeleteOrphanedIssueLabels), }, { // find issues without existing repository Name: "Orphaned Issues without existing repository", - Counter: models.CountOrphanedIssues, - Fixer: asFixer(models.DeleteOrphanedIssues), + Counter: issues_model.CountOrphanedIssues, + Fixer: asFixer(issues_model.DeleteOrphanedIssues), }, // find releases without existing repository genericOrphanCheck("Orphaned Releases without existing repository", @@ -127,22 +128,22 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er // find label comments with empty labels { Name: "Label comments with empty labels", - Counter: models.CountCommentTypeLabelWithEmptyLabel, - Fixer: models.FixCommentTypeLabelWithEmptyLabel, + Counter: issues_model.CountCommentTypeLabelWithEmptyLabel, + Fixer: issues_model.FixCommentTypeLabelWithEmptyLabel, FixedMessage: "Fixed", }, // find label comments with labels from outside the repository { Name: "Label comments with labels from outside the repository", - Counter: models.CountCommentTypeLabelWithOutsideLabels, - Fixer: models.FixCommentTypeLabelWithOutsideLabels, + Counter: issues_model.CountCommentTypeLabelWithOutsideLabels, + Fixer: issues_model.FixCommentTypeLabelWithOutsideLabels, FixedMessage: "Removed", }, // find issue_label with labels from outside the repository { Name: "IssueLabels with Labels from outside the repository", - Counter: models.CountIssueLabelWithOutsideLabels, - Fixer: models.FixIssueLabelWithOutsideLabels, + Counter: issues_model.CountIssueLabelWithOutsideLabels, + Fixer: issues_model.FixIssueLabelWithOutsideLabels, FixedMessage: "Removed", }, { diff --git a/modules/doctor/mergebase.go b/modules/doctor/mergebase.go index 61ee9e212b..46369290a1 100644 --- a/modules/doctor/mergebase.go +++ b/modules/doctor/mergebase.go @@ -9,8 +9,8 @@ import ( "fmt" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + 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/log" @@ -18,13 +18,13 @@ import ( "xorm.io/builder" ) -func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*repo_model.Repository, *models.PullRequest) error) error { +func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*repo_model.Repository, *issues_model.PullRequest) error) error { return db.Iterate( ctx, - new(models.PullRequest), + new(issues_model.PullRequest), builder.Eq{"base_repo_id": repo.ID}, func(idx int, bean interface{}) error { - return each(repo, bean.(*models.PullRequest)) + return each(repo, bean.(*issues_model.PullRequest)) }, ) } @@ -35,7 +35,7 @@ func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) erro numPRsUpdated := 0 err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { numRepos++ - return iteratePRs(ctx, repo, func(repo *repo_model.Repository, pr *models.PullRequest) error { + return iteratePRs(ctx, repo, func(repo *repo_model.Repository, pr *issues_model.PullRequest) error { numPRs++ pr.BaseRepo = repo repoPath := repo.RepoPath() diff --git a/modules/eventsource/manager_run.go b/modules/eventsource/manager_run.go index 127979ad63..6055cf7232 100644 --- a/modules/eventsource/manager_run.go +++ b/modules/eventsource/manager_run.go @@ -9,6 +9,7 @@ import ( "time" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/json" @@ -84,7 +85,7 @@ loop: then = now if setting.Service.EnableTimetracking { - usersStopwatches, err := models.GetUIDsAndStopwatch() + usersStopwatches, err := issues_model.GetUIDsAndStopwatch() if err != nil { log.Error("Unable to get GetUIDsAndStopwatch: %v", err) return diff --git a/modules/indexer/issues/db.go b/modules/indexer/issues/db.go index e2badf64f2..d21c86337e 100644 --- a/modules/indexer/issues/db.go +++ b/modules/indexer/issues/db.go @@ -7,8 +7,8 @@ package issues import ( "context" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" ) // DBIndexer implements Indexer interface to use database's like search @@ -44,7 +44,7 @@ func (i *DBIndexer) Close() { // Search dummy function func (i *DBIndexer) Search(ctx context.Context, kw string, repoIDs []int64, limit, start int) (*SearchResult, error) { - total, ids, err := models.SearchIssueIDsByKeyword(ctx, kw, repoIDs, limit, start) + total, ids, err := issues_model.SearchIssueIDsByKeyword(ctx, kw, repoIDs, limit, start) if err != nil { return nil, err } diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go index 85de4c75b3..da6a200aef 100644 --- a/modules/indexer/issues/indexer.go +++ b/modules/indexer/issues/indexer.go @@ -12,8 +12,8 @@ import ( "sync" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/log" @@ -320,7 +320,7 @@ func populateIssueIndexer(ctx context.Context) { // UpdateRepoIndexer add/update all issues of the repositories func UpdateRepoIndexer(repo *repo_model.Repository) { - is, err := models.Issues(&models.IssuesOptions{ + is, err := issues_model.Issues(&issues_model.IssuesOptions{ RepoID: repo.ID, IsClosed: util.OptionalBoolNone, IsPull: util.OptionalBoolNone, @@ -329,7 +329,7 @@ func UpdateRepoIndexer(repo *repo_model.Repository) { log.Error("Issues: %v", err) return } - if err = models.IssueList(is).LoadDiscussComments(); err != nil { + if err = issues_model.IssueList(is).LoadDiscussComments(); err != nil { log.Error("LoadComments: %v", err) return } @@ -339,10 +339,10 @@ func UpdateRepoIndexer(repo *repo_model.Repository) { } // UpdateIssueIndexer add/update an issue to the issue indexer -func UpdateIssueIndexer(issue *models.Issue) { +func UpdateIssueIndexer(issue *issues_model.Issue) { var comments []string for _, comment := range issue.Comments { - if comment.Type == models.CommentTypeComment { + if comment.Type == issues_model.CommentTypeComment { comments = append(comments, comment.Content) } } @@ -362,7 +362,7 @@ func UpdateIssueIndexer(issue *models.Issue) { // DeleteRepoIssueIndexer deletes repo's all issues indexes func DeleteRepoIssueIndexer(repo *repo_model.Repository) { var ids []int64 - ids, err := models.GetIssueIDsByRepoID(db.DefaultContext, repo.ID) + ids, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, repo.ID) if err != nil { log.Error("getIssueIDsByRepoID failed: %v", err) return diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index 547498a9dc..e438f41485 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/graceful" @@ -33,7 +34,7 @@ func NewNotifier() base.Notifier { return &actionNotifier{} } -func (a *actionNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (a *actionNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { if err := issue.LoadPoster(); err != nil { log.Error("issue.LoadPoster: %v", err) return @@ -58,7 +59,7 @@ func (a *actionNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_mo } // NotifyIssueChangeStatus notifies close or reopen issue to notifiers -func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, closeOrReopen bool) { +func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) { // Compose comment action, could be plain comment, close or reopen issue/pull request. // This object will be used to notify watchers in the end of function. act := &models.Action{ @@ -92,7 +93,7 @@ func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *m // NotifyCreateIssueComment notifies comment on an issue to notifiers func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { act := &models.Action{ ActUserID: doer.ID, @@ -126,7 +127,7 @@ func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *r } } -func (a *actionNotifier) NotifyNewPullRequest(pull *models.PullRequest, mentions []*user_model.User) { +func (a *actionNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, mentions []*user_model.User) { if err := pull.LoadIssue(); err != nil { log.Error("pull.LoadIssue: %v", err) return @@ -207,7 +208,7 @@ func (a *actionNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, re } } -func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment, mentions []*user_model.User) { +func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("actionNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -239,7 +240,7 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review } } - if review.Type != models.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" { + if review.Type != issues_model.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" { action := &models.Action{ ActUserID: review.Reviewer.ID, ActUser: review.Reviewer, @@ -252,9 +253,9 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review } switch review.Type { - case models.ReviewTypeApprove: + case issues_model.ReviewTypeApprove: action.OpType = models.ActionApprovePullRequest - case models.ReviewTypeReject: + case issues_model.ReviewTypeReject: action.OpType = models.ActionRejectPullRequest default: action.OpType = models.ActionCommentPull @@ -268,7 +269,7 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *models.PullRequest, review } } -func (*actionNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (*actionNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { if err := models.NotifyWatchers(&models.Action{ ActUserID: doer.ID, ActUser: doer, @@ -282,7 +283,7 @@ func (*actionNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user } } -func (*actionNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func (*actionNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { reviewerName := review.Reviewer.Name if len(review.OriginalAuthor) > 0 { reviewerName = review.OriginalAuthor diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go index 2b8be18ad3..31fa8f5f18 100644 --- a/modules/notification/base/notifier.go +++ b/modules/notification/base/notifier.go @@ -6,6 +6,7 @@ package base import ( "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -21,30 +22,30 @@ type Notifier interface { NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldRepoName string) NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) - NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) - NotifyIssueChangeStatus(*user_model.User, *models.Issue, *models.Comment, bool) - NotifyDeleteIssue(*user_model.User, *models.Issue) - NotifyIssueChangeMilestone(doer *user_model.User, issue *models.Issue, oldMilestoneID int64) - NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) - NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) - NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) - NotifyIssueClearLabels(doer *user_model.User, issue *models.Issue) - NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) - NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldRef string) - NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label) - NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) - NotifyMergePullRequest(*models.PullRequest, *user_model.User) - NotifyPullRequestSynchronized(doer *user_model.User, pr *models.PullRequest) - NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment, mentions []*user_model.User) - NotifyPullRequestCodeComment(pr *models.PullRequest, comment *models.Comment, mentions []*user_model.User) - NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *models.PullRequest, oldBranch string) - NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) - NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) + NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) + NotifyIssueChangeStatus(*user_model.User, *issues_model.Issue, *issues_model.Comment, bool) + NotifyDeleteIssue(*user_model.User, *issues_model.Issue) + NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) + NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) + NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) + NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) + NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) + NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) + NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string) + NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, + addedLabels, removedLabels []*issues_model.Label) + NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) + NotifyMergePullRequest(*issues_model.PullRequest, *user_model.User) + NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) + NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) + NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) + NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) + NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) + NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) - NotifyUpdateComment(*user_model.User, *models.Comment, string) - NotifyDeleteComment(*user_model.User, *models.Comment) + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User) + NotifyUpdateComment(*user_model.User, *issues_model.Comment, string) + NotifyDeleteComment(*user_model.User, *issues_model.Comment) NotifyNewRelease(rel *models.Release) NotifyUpdateRelease(doer *user_model.User, rel *models.Release) NotifyDeleteRelease(doer *user_model.User, rel *models.Release) diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go index 29b5f0c97e..d336f09301 100644 --- a/modules/notification/base/null.go +++ b/modules/notification/base/null.go @@ -6,6 +6,7 @@ package base import ( "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -23,59 +24,59 @@ func (*NullNotifier) Run() { // NotifyCreateIssueComment places a place holder function func (*NullNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) { + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User) { } // NotifyNewIssue places a place holder function -func (*NullNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (*NullNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { } // NotifyIssueChangeStatus places a place holder function -func (*NullNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, isClosed bool) { +func (*NullNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { } // NotifyDeleteIssue notify when some issue deleted -func (*NullNotifier) NotifyDeleteIssue(doer *user_model.User, issue *models.Issue) { +func (*NullNotifier) NotifyDeleteIssue(doer *user_model.User, issue *issues_model.Issue) { } // NotifyNewPullRequest places a place holder function -func (*NullNotifier) NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func (*NullNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { } // NotifyPullRequestReview places a place holder function -func (*NullNotifier) NotifyPullRequestReview(pr *models.PullRequest, r *models.Review, comment *models.Comment, mentions []*user_model.User) { +func (*NullNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { } // NotifyPullRequestCodeComment places a place holder function -func (*NullNotifier) NotifyPullRequestCodeComment(pr *models.PullRequest, comment *models.Comment, mentions []*user_model.User) { +func (*NullNotifier) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) { } // NotifyMergePullRequest places a place holder function -func (*NullNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (*NullNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { } // NotifyPullRequestSynchronized places a place holder function -func (*NullNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *models.PullRequest) { +func (*NullNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) { } // NotifyPullRequestChangeTargetBranch places a place holder function -func (*NullNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *models.PullRequest, oldBranch string) { +func (*NullNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { } // NotifyPullRequestPushCommits notifies when push commits to pull request's head branch -func (*NullNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) { +func (*NullNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { } // NotifyPullRevieweDismiss notifies when a review was dismissed by repo admin -func (*NullNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func (*NullNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { } // NotifyUpdateComment places a place holder function -func (*NullNotifier) NotifyUpdateComment(doer *user_model.User, c *models.Comment, oldContent string) { +func (*NullNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) { } // NotifyDeleteComment places a place holder function -func (*NullNotifier) NotifyDeleteComment(doer *user_model.User, c *models.Comment) { +func (*NullNotifier) NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) { } // NotifyNewRelease places a place holder function @@ -91,36 +92,36 @@ func (*NullNotifier) NotifyDeleteRelease(doer *user_model.User, rel *models.Rele } // NotifyIssueChangeMilestone places a place holder function -func (*NullNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *models.Issue, oldMilestoneID int64) { +func (*NullNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { } // NotifyIssueChangeContent places a place holder function -func (*NullNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) { +func (*NullNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) { } // NotifyIssueChangeAssignee places a place holder function -func (*NullNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func (*NullNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { } // NotifyPullReviewRequest places a place holder function -func (*NullNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) { +func (*NullNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { } // NotifyIssueClearLabels places a place holder function -func (*NullNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *models.Issue) { +func (*NullNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) { } // NotifyIssueChangeTitle places a place holder function -func (*NullNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (*NullNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { } // NotifyIssueChangeRef places a place holder function -func (*NullNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (*NullNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { } // NotifyIssueChangeLabels places a place holder function -func (*NullNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label) { +func (*NullNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, + addedLabels, removedLabels []*issues_model.Label) { } // NotifyCreateRepository places a place holder function diff --git a/modules/notification/indexer/indexer.go b/modules/notification/indexer/indexer.go index 48a491f3f1..fc9afdd4bc 100644 --- a/modules/notification/indexer/indexer.go +++ b/modules/notification/indexer/indexer.go @@ -5,7 +5,7 @@ package indexer import ( - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -30,9 +30,9 @@ func NewNotifier() base.Notifier { } func (r *indexerNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { - if comment.Type == models.CommentTypeComment { + if comment.Type == issues_model.CommentTypeComment { if issue.Comments == nil { if err := issue.LoadDiscussComments(); err != nil { log.Error("LoadComments failed: %v", err) @@ -46,16 +46,16 @@ func (r *indexerNotifier) NotifyCreateIssueComment(doer *user_model.User, repo * } } -func (r *indexerNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (r *indexerNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { issue_indexer.UpdateIssueIndexer(issue) } -func (r *indexerNotifier) NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func (r *indexerNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { issue_indexer.UpdateIssueIndexer(pr.Issue) } -func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *models.Comment, oldContent string) { - if c.Type == models.CommentTypeComment { +func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) { + if c.Type == issues_model.CommentTypeComment { var found bool if c.Issue.Comments != nil { for i := 0; i < len(c.Issue.Comments); i++ { @@ -78,8 +78,8 @@ func (r *indexerNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C } } -func (r *indexerNotifier) NotifyDeleteComment(doer *user_model.User, comment *models.Comment) { - if comment.Type == models.CommentTypeComment { +func (r *indexerNotifier) NotifyDeleteComment(doer *user_model.User, comment *issues_model.Comment) { + if comment.Type == issues_model.CommentTypeComment { if err := comment.LoadIssue(); err != nil { log.Error("LoadIssue: %v", err) return @@ -142,14 +142,14 @@ func (r *indexerNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *r } } -func (r *indexerNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) { +func (r *indexerNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) { issue_indexer.UpdateIssueIndexer(issue) } -func (r *indexerNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (r *indexerNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { issue_indexer.UpdateIssueIndexer(issue) } -func (r *indexerNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldRef string) { +func (r *indexerNotifier) NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string) { issue_indexer.UpdateIssueIndexer(issue) } diff --git a/modules/notification/mail/mail.go b/modules/notification/mail/mail.go index 138e438751..1f217304b0 100644 --- a/modules/notification/mail/mail.go +++ b/modules/notification/mail/mail.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/graceful" @@ -29,21 +30,21 @@ func NewNotifier() base.Notifier { } func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyCreateIssueComment Issue[%d] #%d in [%d]", issue.ID, issue.Index, issue.RepoID)) defer finished() var act models.ActionType - if comment.Type == models.CommentTypeClose { + if comment.Type == issues_model.CommentTypeClose { act = models.ActionCloseIssue - } else if comment.Type == models.CommentTypeReopen { + } else if comment.Type == issues_model.CommentTypeReopen { act = models.ActionReopenIssue - } else if comment.Type == models.CommentTypeComment { + } else if comment.Type == issues_model.CommentTypeComment { act = models.ActionCommentIssue - } else if comment.Type == models.CommentTypeCode { + } else if comment.Type == issues_model.CommentTypeCode { act = models.ActionCommentIssue - } else if comment.Type == models.CommentTypePullRequestPush { + } else if comment.Type == issues_model.CommentTypePullRequestPush { act = 0 } @@ -52,13 +53,13 @@ func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *rep } } -func (m *mailNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (m *mailNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { if err := mailer.MailParticipants(issue, issue.Poster, models.ActionCreateIssue, mentions); err != nil { log.Error("MailParticipants: %v", err) } } -func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, isClosed bool) { +func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { var actionType models.ActionType if issue.IsPull { if isClosed { @@ -79,34 +80,34 @@ func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *mod } } -func (m *mailNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (m *mailNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { if err := issue.LoadPullRequest(); err != nil { log.Error("issue.LoadPullRequest: %v", err) return } - if issue.IsPull && models.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { + if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { if err := mailer.MailParticipants(issue, doer, models.ActionPullRequestReadyForReview, nil); err != nil { log.Error("MailParticipants: %v", err) } } } -func (m *mailNotifier) NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func (m *mailNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { if err := mailer.MailParticipants(pr.Issue, pr.Issue.Poster, models.ActionCreatePullRequest, mentions); err != nil { log.Error("MailParticipants: %v", err) } } -func (m *mailNotifier) NotifyPullRequestReview(pr *models.PullRequest, r *models.Review, comment *models.Comment, mentions []*user_model.User) { +func (m *mailNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() var act models.ActionType - if comment.Type == models.CommentTypeClose { + if comment.Type == issues_model.CommentTypeClose { act = models.ActionCloseIssue - } else if comment.Type == models.CommentTypeReopen { + } else if comment.Type == issues_model.CommentTypeReopen { act = models.ActionReopenIssue - } else if comment.Type == models.CommentTypeComment { + } else if comment.Type == issues_model.CommentTypeComment { act = models.ActionCommentPull } if err := mailer.MailParticipantsComment(ctx, comment, act, pr.Issue, mentions); err != nil { @@ -114,7 +115,7 @@ func (m *mailNotifier) NotifyPullRequestReview(pr *models.PullRequest, r *models } } -func (m *mailNotifier) NotifyPullRequestCodeComment(pr *models.PullRequest, comment *models.Comment, mentions []*user_model.User) { +func (m *mailNotifier) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestCodeComment Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -123,7 +124,7 @@ func (m *mailNotifier) NotifyPullRequestCodeComment(pr *models.PullRequest, comm } } -func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { // mail only sent to added assignees and not self-assignee if !removed && doer.ID != assignee.ID && (assignee.EmailNotifications() == user_model.EmailNotificationsEnabled || assignee.EmailNotifications() == user_model.EmailNotificationsOnMention) { ct := fmt.Sprintf("Assigned #%d.", issue.Index) @@ -133,7 +134,7 @@ func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *m } } -func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) { +func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { if isRequest && doer.ID != reviewer.ID && (reviewer.EmailNotifications() == user_model.EmailNotificationsEnabled || reviewer.EmailNotifications() == user_model.EmailNotificationsOnMention) { ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL()) if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil { @@ -142,7 +143,7 @@ func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *mod } } -func (m *mailNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (m *mailNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { if err := pr.LoadIssue(); err != nil { log.Error("pr.LoadIssue: %v", err) return @@ -152,7 +153,7 @@ func (m *mailNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user } } -func (m *mailNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) { +func (m *mailNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestPushCommits Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -179,7 +180,7 @@ func (m *mailNotifier) NotifyPullRequestPushCommits(doer *user_model.User, pr *m m.NotifyCreateIssueComment(doer, comment.Issue.Repo, comment.Issue, comment, nil) } -func (m *mailNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func (m *mailNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRevieweDismiss Review[%d] in Issue[%d]", review.ID, review.IssueID)) defer finished() diff --git a/modules/notification/notification.go b/modules/notification/notification.go index 90ff87941f..d60a880bec 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -6,6 +6,7 @@ package notification import ( "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -40,7 +41,7 @@ func NewContext() { // NotifyCreateIssueComment notifies issue comment related message to notifiers func NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { for _, notifier := range notifiers { notifier.NotifyCreateIssueComment(doer, repo, issue, comment, mentions) @@ -48,91 +49,91 @@ func NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository } // NotifyNewIssue notifies new issue to notifiers -func NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { for _, notifier := range notifiers { notifier.NotifyNewIssue(issue, mentions) } } // NotifyIssueChangeStatus notifies close or reopen issue to notifiers -func NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, closeOrReopen bool) { +func NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) { for _, notifier := range notifiers { notifier.NotifyIssueChangeStatus(doer, issue, actionComment, closeOrReopen) } } // NotifyDeleteIssue notify when some issue deleted -func NotifyDeleteIssue(doer *user_model.User, issue *models.Issue) { +func NotifyDeleteIssue(doer *user_model.User, issue *issues_model.Issue) { for _, notifier := range notifiers { notifier.NotifyDeleteIssue(doer, issue) } } // NotifyMergePullRequest notifies merge pull request to notifiers -func NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { for _, notifier := range notifiers { notifier.NotifyMergePullRequest(pr, doer) } } // NotifyNewPullRequest notifies new pull request to notifiers -func NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { for _, notifier := range notifiers { notifier.NotifyNewPullRequest(pr, mentions) } } // NotifyPullRequestSynchronized notifies Synchronized pull request -func NotifyPullRequestSynchronized(doer *user_model.User, pr *models.PullRequest) { +func NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) { for _, notifier := range notifiers { notifier.NotifyPullRequestSynchronized(doer, pr) } } // NotifyPullRequestReview notifies new pull request review -func NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment, mentions []*user_model.User) { +func NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { for _, notifier := range notifiers { notifier.NotifyPullRequestReview(pr, review, comment, mentions) } } // NotifyPullRequestCodeComment notifies new pull request code comment -func NotifyPullRequestCodeComment(pr *models.PullRequest, comment *models.Comment, mentions []*user_model.User) { +func NotifyPullRequestCodeComment(pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) { for _, notifier := range notifiers { notifier.NotifyPullRequestCodeComment(pr, comment, mentions) } } // NotifyPullRequestChangeTargetBranch notifies when a pull request's target branch was changed -func NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *models.PullRequest, oldBranch string) { +func NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { for _, notifier := range notifiers { notifier.NotifyPullRequestChangeTargetBranch(doer, pr, oldBranch) } } // NotifyPullRequestPushCommits notifies when push commits to pull request's head branch -func NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) { +func NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyPullRequestPushCommits(doer, pr, comment) } } // NotifyPullRevieweDismiss notifies when a review was dismissed by repo admin -func NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyPullRevieweDismiss(doer, review, comment) } } // NotifyUpdateComment notifies update comment to notifiers -func NotifyUpdateComment(doer *user_model.User, c *models.Comment, oldContent string) { +func NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) { for _, notifier := range notifiers { notifier.NotifyUpdateComment(doer, c, oldContent) } } // NotifyDeleteComment notifies delete comment to notifiers -func NotifyDeleteComment(doer *user_model.User, c *models.Comment) { +func NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyDeleteComment(doer, c) } @@ -160,57 +161,57 @@ func NotifyDeleteRelease(doer *user_model.User, rel *models.Release) { } // NotifyIssueChangeMilestone notifies change milestone to notifiers -func NotifyIssueChangeMilestone(doer *user_model.User, issue *models.Issue, oldMilestoneID int64) { +func NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { for _, notifier := range notifiers { notifier.NotifyIssueChangeMilestone(doer, issue, oldMilestoneID) } } // NotifyIssueChangeContent notifies change content to notifiers -func NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) { +func NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) { for _, notifier := range notifiers { notifier.NotifyIssueChangeContent(doer, issue, oldContent) } } // NotifyIssueChangeAssignee notifies change content to notifiers -func NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyIssueChangeAssignee(doer, issue, assignee, removed, comment) } } // NotifyPullReviewRequest notifies Request Review change -func NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) { +func NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { for _, notifier := range notifiers { notifier.NotifyPullReviewRequest(doer, issue, reviewer, isRequest, comment) } } // NotifyIssueClearLabels notifies clear labels to notifiers -func NotifyIssueClearLabels(doer *user_model.User, issue *models.Issue) { +func NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) { for _, notifier := range notifiers { notifier.NotifyIssueClearLabels(doer, issue) } } // NotifyIssueChangeTitle notifies change title to notifiers -func NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { for _, notifier := range notifiers { notifier.NotifyIssueChangeTitle(doer, issue, oldTitle) } } // NotifyIssueChangeRef notifies change reference to notifiers -func NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldRef string) { +func NotifyIssueChangeRef(doer *user_model.User, issue *issues_model.Issue, oldRef string) { for _, notifier := range notifiers { notifier.NotifyIssueChangeRef(doer, issue, oldRef) } } // NotifyIssueChangeLabels notifies change labels to notifiers -func NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label, +func NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, + addedLabels, removedLabels []*issues_model.Label, ) { for _, notifier := range notifiers { notifier.NotifyIssueChangeLabels(doer, issue, addedLabels, removedLabels) diff --git a/modules/notification/ui/ui.go b/modules/notification/ui/ui.go index 037167f640..74866a3363 100644 --- a/modules/notification/ui/ui.go +++ b/modules/notification/ui/ui.go @@ -7,6 +7,7 @@ package ui import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/graceful" @@ -53,7 +54,7 @@ func (ns *notificationService) Run() { } func (ns *notificationService) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { opts := issueNotificationOpts{ IssueID: issue.ID, @@ -76,7 +77,7 @@ func (ns *notificationService) NotifyCreateIssueComment(doer *user_model.User, r } } -func (ns *notificationService) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (ns *notificationService) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: issue.ID, NotificationAuthorID: issue.Poster.ID, @@ -90,19 +91,19 @@ func (ns *notificationService) NotifyNewIssue(issue *models.Issue, mentions []*u } } -func (ns *notificationService) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, isClosed bool) { +func (ns *notificationService) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: issue.ID, NotificationAuthorID: doer.ID, }) } -func (ns *notificationService) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (ns *notificationService) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { if err := issue.LoadPullRequest(); err != nil { log.Error("issue.LoadPullRequest: %v", err) return } - if issue.IsPull && models.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { + if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: issue.ID, NotificationAuthorID: doer.ID, @@ -110,14 +111,14 @@ func (ns *notificationService) NotifyIssueChangeTitle(doer *user_model.User, iss } } -func (ns *notificationService) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (ns *notificationService) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: pr.Issue.ID, NotificationAuthorID: doer.ID, }) } -func (ns *notificationService) NotifyNewPullRequest(pr *models.PullRequest, mentions []*user_model.User) { +func (ns *notificationService) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { if err := pr.LoadIssue(); err != nil { log.Error("Unable to load issue: %d for pr: %d: Error: %v", pr.IssueID, pr.ID, err) return @@ -131,7 +132,7 @@ func (ns *notificationService) NotifyNewPullRequest(pr *models.PullRequest, ment for _, id := range repoWatchers { toNotify[id] = struct{}{} } - issueParticipants, err := models.GetParticipantsIDsByIssueID(pr.IssueID) + issueParticipants, err := issues_model.GetParticipantsIDsByIssueID(pr.IssueID) if err != nil { log.Error("GetParticipantsIDsByIssueID: %v", err) return @@ -152,7 +153,7 @@ func (ns *notificationService) NotifyNewPullRequest(pr *models.PullRequest, ment } } -func (ns *notificationService) NotifyPullRequestReview(pr *models.PullRequest, r *models.Review, c *models.Comment, mentions []*user_model.User) { +func (ns *notificationService) NotifyPullRequestReview(pr *issues_model.PullRequest, r *issues_model.Review, c *issues_model.Comment, mentions []*user_model.User) { opts := issueNotificationOpts{ IssueID: pr.Issue.ID, NotificationAuthorID: r.Reviewer.ID, @@ -174,7 +175,7 @@ func (ns *notificationService) NotifyPullRequestReview(pr *models.PullRequest, r } } -func (ns *notificationService) NotifyPullRequestCodeComment(pr *models.PullRequest, c *models.Comment, mentions []*user_model.User) { +func (ns *notificationService) NotifyPullRequestCodeComment(pr *issues_model.PullRequest, c *issues_model.Comment, mentions []*user_model.User) { for _, mention := range mentions { _ = ns.issueQueue.Push(issueNotificationOpts{ IssueID: pr.Issue.ID, @@ -185,7 +186,7 @@ func (ns *notificationService) NotifyPullRequestCodeComment(pr *models.PullReque } } -func (ns *notificationService) NotifyPullRequestPushCommits(doer *user_model.User, pr *models.PullRequest, comment *models.Comment) { +func (ns *notificationService) NotifyPullRequestPushCommits(doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { opts := issueNotificationOpts{ IssueID: pr.IssueID, NotificationAuthorID: doer.ID, @@ -194,7 +195,7 @@ func (ns *notificationService) NotifyPullRequestPushCommits(doer *user_model.Use _ = ns.issueQueue.Push(opts) } -func (ns *notificationService) NotifyPullRevieweDismiss(doer *user_model.User, review *models.Review, comment *models.Comment) { +func (ns *notificationService) NotifyPullRevieweDismiss(doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { opts := issueNotificationOpts{ IssueID: review.IssueID, NotificationAuthorID: doer.ID, @@ -203,7 +204,7 @@ func (ns *notificationService) NotifyPullRevieweDismiss(doer *user_model.User, r _ = ns.issueQueue.Push(opts) } -func (ns *notificationService) NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func (ns *notificationService) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { if !removed && doer.ID != assignee.ID { opts := issueNotificationOpts{ IssueID: issue.ID, @@ -219,7 +220,7 @@ func (ns *notificationService) NotifyIssueChangeAssignee(doer *user_model.User, } } -func (ns *notificationService) NotifyPullReviewRequest(doer *user_model.User, issue *models.Issue, reviewer *user_model.User, isRequest bool, comment *models.Comment) { +func (ns *notificationService) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { if isRequest { opts := issueNotificationOpts{ IssueID: issue.ID, diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go index 38077f2180..be71d18fda 100644 --- a/modules/notification/webhook/webhook.go +++ b/modules/notification/webhook/webhook.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -39,7 +40,7 @@ func NewNotifier() base.Notifier { return &webhookNotifier{} } -func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *models.Issue) { +func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *issues_model.Issue) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueClearLabels User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -147,7 +148,7 @@ func (m *webhookNotifier) NotifyMigrateRepository(doer, u *user_model.User, repo } } -func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *models.Issue, assignee *user_model.User, removed bool, comment *models.Comment) { +func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeAssignee User: %s[%d] Issue[%d] #%d in [%d] Assignee %s[%d] removed: %t", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID, assignee.Name, assignee.ID, removed)) defer finished() @@ -196,7 +197,7 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue } } -func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *models.Issue, oldTitle string) { +func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issues_model.Issue, oldTitle string) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeTitle User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -240,7 +241,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *m } } -func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *models.Issue, actionComment *models.Comment, isClosed bool) { +func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeStatus User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -283,7 +284,7 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue * } } -func (m *webhookNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_model.User) { +func (m *webhookNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { if err := issue.LoadRepo(db.DefaultContext); err != nil { log.Error("issue.LoadRepo: %v", err) return @@ -305,7 +306,7 @@ func (m *webhookNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_m } } -func (m *webhookNotifier) NotifyNewPullRequest(pull *models.PullRequest, mentions []*user_model.User) { +func (m *webhookNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyNewPullRequest Pull[%d] #%d in [%d]", pull.ID, pull.Index, pull.BaseRepoID)) defer finished() @@ -334,7 +335,7 @@ func (m *webhookNotifier) NotifyNewPullRequest(pull *models.PullRequest, mention } } -func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *models.Issue, oldContent string) { +func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue *issues_model.Issue, oldContent string) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeContent User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -373,7 +374,7 @@ func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue } } -func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.Comment, oldContent string) { +func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *issues_model.Comment, oldContent string) { var err error if err = c.LoadPoster(); err != nil { @@ -385,7 +386,7 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C return } - if err = c.Issue.LoadAttributes(); err != nil { + if err = c.Issue.LoadAttributes(db.DefaultContext); err != nil { log.Error("LoadAttributes: %v", err) return } @@ -427,7 +428,7 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C } func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User, + issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { mode, _ := access_model.AccessLevel(doer, repo) @@ -457,7 +458,7 @@ func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo * } } -func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *models.Comment) { +func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *issues_model.Comment) { var err error if err = comment.LoadPoster(); err != nil { @@ -469,7 +470,7 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *mo return } - if err = comment.Issue.LoadAttributes(); err != nil { + if err = comment.Issue.LoadAttributes(db.DefaultContext); err != nil { log.Error("LoadAttributes: %v", err) return } @@ -501,8 +502,8 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *mo } } -func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label, +func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *issues_model.Issue, + addedLabels, removedLabels []*issues_model.Label, ) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeLabels User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -550,7 +551,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue * } } -func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *models.Issue, oldMilestoneID int64) { +func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeMilestone User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() @@ -562,7 +563,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issu hookAction = api.HookIssueDemilestoned } - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(db.DefaultContext); err != nil { log.Error("issue.LoadAttributes failed: %v", err) return } @@ -621,7 +622,7 @@ func (m *webhookNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_ } } -func (*webhookNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *user_model.User) { +func (*webhookNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyMergePullRequest Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -662,7 +663,7 @@ func (*webhookNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *use } } -func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *models.PullRequest, oldBranch string) { +func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestChangeTargetBranch Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -696,18 +697,18 @@ func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.U } } -func (m *webhookNotifier) NotifyPullRequestReview(pr *models.PullRequest, review *models.Review, comment *models.Comment, mentions []*user_model.User) { +func (m *webhookNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() var reviewHookType webhook.HookEventType switch review.Type { - case models.ReviewTypeApprove: + case issues_model.ReviewTypeApprove: reviewHookType = webhook.HookEventPullRequestReviewApproved - case models.ReviewTypeComment: + case issues_model.ReviewTypeComment: reviewHookType = webhook.HookEventPullRequestComment - case models.ReviewTypeReject: + case issues_model.ReviewTypeReject: reviewHookType = webhook.HookEventPullRequestReviewRejected default: // unsupported review webhook type here @@ -756,7 +757,7 @@ func (m *webhookNotifier) NotifyCreateRef(pusher *user_model.User, repo *repo_mo } } -func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *models.PullRequest) { +func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, pr *issues_model.PullRequest) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyPullRequestSynchronized Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) defer finished() @@ -764,7 +765,7 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, p log.Error("pr.LoadIssue: %v", err) return } - if err := pr.Issue.LoadAttributes(); err != nil { + if err := pr.Issue.LoadAttributes(db.DefaultContext); err != nil { log.Error("LoadAttributes: %v", err) return } diff --git a/modules/repository/init.go b/modules/repository/init.go index 285fe81dbe..f5cef3301d 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -16,6 +16,7 @@ import ( "time" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -113,7 +114,7 @@ func GetLabelTemplateFile(name string) ([][3]string, error) { if len(color) == 6 { color = "#" + color } - if !models.LabelColorPattern.MatchString(color) { + if !issues_model.LabelColorPattern.MatchString(color) { return nil, ErrIssueLabelTemplateLoad{name, fmt.Errorf("bad HTML color code in line: %s", line)} } @@ -453,9 +454,9 @@ func InitializeLabels(ctx context.Context, id int64, labelTemplate string, isOrg return err } - labels := make([]*models.Label, len(list)) + labels := make([]*issues_model.Label, len(list)) for i := 0; i < len(list); i++ { - labels[i] = &models.Label{ + labels[i] = &issues_model.Label{ Name: list[i][0], Description: list[i][2], Color: list[i][1], @@ -467,7 +468,7 @@ func InitializeLabels(ctx context.Context, id int64, labelTemplate string, isOrg } } for _, label := range labels { - if err = models.NewLabel(ctx, label); err != nil { + if err = issues_model.NewLabel(ctx, label); err != nil { return err } } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index c0be5c1fa5..b77928fc9c 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -26,6 +26,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/avatars" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -374,7 +375,7 @@ func NewFuncMap() []template.FuncMap { // the table is NOT sorted with this header return "" }, - "RenderLabels": func(labels []*models.Label) template.HTML { + "RenderLabels": func(labels []*issues_model.Label) template.HTML { html := `` for _, label := range labels { // Protect against nil value in labels - shouldn't happen but would cause a panic if so diff --git a/routers/api/v1/misc/nodeinfo.go b/routers/api/v1/misc/nodeinfo.go index c786544e14..bd629b87ca 100644 --- a/routers/api/v1/misc/nodeinfo.go +++ b/routers/api/v1/misc/nodeinfo.go @@ -8,7 +8,7 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" @@ -42,8 +42,8 @@ func NodeInfo(ctx *context.APIContext) { usersActiveMonth := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeOneMonthAgo})) usersActiveHalfyear := int(user_model.CountUsers(&user_model.CountUserFilter{LastLoginSince: &timeHaveYearAgo})) - allIssues, _ := models.CountIssues(&models.IssuesOptions{}) - allComments, _ := models.CountComments(&models.FindCommentsOptions{}) + allIssues, _ := issues_model.CountIssues(&issues_model.IssuesOptions{}) + allComments, _ := issues_model.CountComments(&issues_model.FindCommentsOptions{}) nodeInfoUsage = structs.NodeInfoUsage{ Users: structs.NodeInfoUsageUsers{ diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index 4effd6b3e0..7d8d34504f 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" ) @@ -41,7 +42,7 @@ func GetThread(ctx *context.APIContext) { if n == nil { return } - if err := n.LoadAttributes(); err != nil && !models.IsErrCommentNotExist(err) { + if err := n.LoadAttributes(); err != nil && !issues_model.IsErrCommentNotExist(err) { ctx.InternalServerError(err) return } @@ -93,7 +94,7 @@ func ReadThread(ctx *context.APIContext) { ctx.InternalServerError(err) return } - if err = notif.LoadAttributes(); err != nil && !models.IsErrCommentNotExist(err) { + if err = notif.LoadAttributes(); err != nil && !issues_model.IsErrCommentNotExist(err) { ctx.InternalServerError(err) return } diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index 9844ea21d2..a67bd56dfc 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -43,13 +43,13 @@ func ListLabels(ctx *context.APIContext) { // "200": // "$ref": "#/responses/LabelList" - labels, err := models.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) + labels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByOrgID", err) return } - count, err := models.CountLabelsByOrgID(ctx.Org.Organization.ID) + count, err := issues_model.CountLabelsByOrgID(ctx.Org.Organization.ID) if err != nil { ctx.InternalServerError(err) return @@ -88,18 +88,18 @@ func CreateLabel(ctx *context.APIContext) { if len(form.Color) == 6 { form.Color = "#" + form.Color } - if !models.LabelColorPattern.MatchString(form.Color) { + if !issues_model.LabelColorPattern.MatchString(form.Color) { ctx.Error(http.StatusUnprocessableEntity, "ColorPattern", fmt.Errorf("bad color code: %s", form.Color)) return } - label := &models.Label{ + label := &issues_model.Label{ Name: form.Name, Color: form.Color, OrgID: ctx.Org.Organization.ID, Description: form.Description, } - if err := models.NewLabel(ctx, label); err != nil { + if err := issues_model.NewLabel(ctx, label); err != nil { ctx.Error(http.StatusInternalServerError, "NewLabel", err) return } @@ -131,17 +131,17 @@ func GetLabel(ctx *context.APIContext) { // "$ref": "#/responses/Label" var ( - label *models.Label + label *issues_model.Label err error ) strID := ctx.Params(":id") if intID, err2 := strconv.ParseInt(strID, 10, 64); err2 != nil { - label, err = models.GetLabelInOrgByName(ctx, ctx.Org.Organization.ID, strID) + label, err = issues_model.GetLabelInOrgByName(ctx, ctx.Org.Organization.ID, strID) } else { - label, err = models.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, intID) + label, err = issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, intID) } if err != nil { - if models.IsErrOrgLabelNotExist(err) { + if issues_model.IsErrOrgLabelNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetLabelByOrgID", err) @@ -183,9 +183,9 @@ func EditLabel(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" form := web.GetForm(ctx).(*api.EditLabelOption) - label, err := models.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.ParamsInt64(":id")) + label, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrOrgLabelNotExist(err) { + if issues_model.IsErrOrgLabelNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) @@ -201,7 +201,7 @@ func EditLabel(ctx *context.APIContext) { if len(label.Color) == 6 { label.Color = "#" + label.Color } - if !models.LabelColorPattern.MatchString(label.Color) { + if !issues_model.LabelColorPattern.MatchString(label.Color) { ctx.Error(http.StatusUnprocessableEntity, "ColorPattern", fmt.Errorf("bad color code: %s", label.Color)) return } @@ -209,7 +209,7 @@ func EditLabel(ctx *context.APIContext) { if form.Description != nil { label.Description = *form.Description } - if err := models.UpdateLabel(label); err != nil { + if err := issues_model.UpdateLabel(label); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateLabel", err) return } @@ -238,7 +238,7 @@ func DeleteLabel(ctx *context.APIContext) { // "204": // "$ref": "#/responses/empty" - if err := models.DeleteLabel(ctx.Org.Organization.ID, ctx.ParamsInt64(":id")); err != nil { + if err := issues_model.DeleteLabel(ctx.Org.Organization.ID, ctx.ParamsInt64(":id")); err != nil { ctx.Error(http.StatusInternalServerError, "DeleteLabel", err) return } diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index ffa3ddc784..2190094bac 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -557,7 +557,7 @@ func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) { // Called from both CreateFile or UpdateFile to handle both func createOrUpdateFile(ctx *context.APIContext, opts *files_service.UpdateRepoFileOptions) (*api.FileResponse, error) { if !canWriteFiles(ctx, opts.OldBranch) { - return nil, models.ErrUserDoesNotHaveAccessToRepo{ + return nil, repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, } @@ -614,7 +614,7 @@ func DeleteFile(ctx *context.APIContext) { apiOpts := web.GetForm(ctx).(*api.DeleteFileOptions) if !canWriteFiles(ctx, apiOpts.BranchName) { - ctx.Error(http.StatusForbidden, "DeleteFile", models.ErrUserDoesNotHaveAccessToRepo{ + ctx.Error(http.StatusForbidden, "DeleteFile", repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) @@ -712,7 +712,7 @@ func GetContents(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !canReadFiles(ctx.Repo) { - ctx.Error(http.StatusInternalServerError, "GetContentsOrList", models.ErrUserDoesNotHaveAccessToRepo{ + ctx.Error(http.StatusInternalServerError, "GetContentsOrList", repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index c394ad1756..ddad18ef62 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -12,7 +12,6 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" @@ -184,7 +183,7 @@ func SearchIssues(ctx *context.APIContext) { return } - var issues []*models.Issue + var issues []*issues_model.Issue var filteredCount int64 keyword := ctx.FormTrim("q") @@ -233,7 +232,7 @@ func SearchIssues(ctx *context.APIContext) { // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(includedLabelNames) > 0 || len(includedMilestones) > 0 { - issuesOpt := &models.IssuesOptions{ + issuesOpt := &issues_model.IssuesOptions{ ListOptions: db.ListOptions{ Page: ctx.FormInt("page"), PageSize: limit, @@ -269,7 +268,7 @@ func SearchIssues(ctx *context.APIContext) { issuesOpt.ReviewRequestedID = ctxUserID } - if issues, err = models.Issues(issuesOpt); err != nil { + if issues, err = issues_model.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err) return } @@ -277,7 +276,7 @@ func SearchIssues(ctx *context.APIContext) { issuesOpt.ListOptions = db.ListOptions{ Page: -1, } - if filteredCount, err = models.CountIssues(issuesOpt); err != nil { + if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "CountIssues", err) return } @@ -379,7 +378,7 @@ func ListIssues(ctx *context.APIContext) { isClosed = util.OptionalBoolFalse } - var issues []*models.Issue + var issues []*issues_model.Issue var filteredCount int64 keyword := ctx.FormTrim("q") @@ -397,7 +396,7 @@ func ListIssues(ctx *context.APIContext) { } if splitted := strings.Split(ctx.FormString("labels"), ","); len(splitted) > 0 { - labelIDs, err = models.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) + labelIDs, err = issues_model.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err) return @@ -463,7 +462,7 @@ func ListIssues(ctx *context.APIContext) { // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { - issuesOpt := &models.IssuesOptions{ + issuesOpt := &issues_model.IssuesOptions{ ListOptions: listOptions, RepoID: ctx.Repo.Repository.ID, IsClosed: isClosed, @@ -478,7 +477,7 @@ func ListIssues(ctx *context.APIContext) { MentionedID: mentionedByID, } - if issues, err = models.Issues(issuesOpt); err != nil { + if issues, err = issues_model.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err) return } @@ -486,7 +485,7 @@ func ListIssues(ctx *context.APIContext) { issuesOpt.ListOptions = db.ListOptions{ Page: -1, } - if filteredCount, err = models.CountIssues(issuesOpt); err != nil { + if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "CountIssues", err) return } @@ -547,9 +546,9 @@ func GetIssue(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -598,7 +597,7 @@ func CreateIssue(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) } - issue := &models.Issue{ + issue := &issues_model.Issue{ RepoID: ctx.Repo.Repository.ID, Repo: ctx.Repo.Repository, Title: form.Title, @@ -613,7 +612,7 @@ func CreateIssue(ctx *context.APIContext) { var err error if ctx.Repo.CanWrite(unit.TypeIssues) { issue.MilestoneID = form.Milestone - assigneeIDs, err = models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) + assigneeIDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) if err != nil { if user_model.IsErrUserNotExist(err) { ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) @@ -637,7 +636,7 @@ func CreateIssue(ctx *context.APIContext) { return } if !valid { - ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) + ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) return } } @@ -647,7 +646,7 @@ func CreateIssue(ctx *context.APIContext) { } if err := issue_service.NewIssue(ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) return } @@ -657,7 +656,7 @@ func CreateIssue(ctx *context.APIContext) { if form.Closed { if err := issue_service.ChangeStatus(issue, ctx.Doer, true); err != nil { - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies") return } @@ -667,7 +666,7 @@ func CreateIssue(ctx *context.APIContext) { } // Refetch from database to assign some automatic values - issue, err = models.GetIssueByID(issue.ID) + issue, err = issues_model.GetIssueByID(ctx, issue.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetIssueByID", err) return @@ -716,9 +715,9 @@ func EditIssue(ctx *context.APIContext) { // "$ref": "#/responses/error" form := web.GetForm(ctx).(*api.EditIssueOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -728,7 +727,7 @@ func EditIssue(ctx *context.APIContext) { issue.Repo = ctx.Repo.Repository canWrite := ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) - err = issue.LoadAttributes() + err = issue.LoadAttributes(ctx) if err != nil { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return @@ -764,7 +763,7 @@ func EditIssue(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(deadline.Unix()) } - if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { + if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } @@ -813,9 +812,9 @@ func EditIssue(ctx *context.APIContext) { } issue.IsClosed = api.StateClosed == api.StateType(*form.State) } - statusChangeComment, titleChanged, err := models.UpdateIssueByAPI(issue, ctx.Doer) + statusChangeComment, titleChanged, err := issues_model.UpdateIssueByAPI(issue, ctx.Doer) if err != nil { - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies") return } @@ -832,7 +831,7 @@ func EditIssue(ctx *context.APIContext) { } // Refetch from database to assign some automatic values - issue, err = models.GetIssueByID(issue.ID) + issue, err = issues_model.GetIssueByID(ctx, issue.ID) if err != nil { ctx.InternalServerError(err) return @@ -872,9 +871,9 @@ func DeleteIssue(ctx *context.APIContext) { // "$ref": "#/responses/forbidden" // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByID", err) @@ -928,9 +927,9 @@ func UpdateIssueDeadline(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" form := web.GetForm(ctx).(*api.EditDeadlineOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -951,7 +950,7 @@ func UpdateIssueDeadline(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(deadline.Unix()) } - if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { + if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 22533c3810..89038e4f16 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -10,7 +10,7 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -65,33 +65,33 @@ func ListIssueComments(ctx *context.APIContext) { ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) return } - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) return } issue.Repo = ctx.Repo.Repository - opts := &models.FindCommentsOptions{ + opts := &issues_model.FindCommentsOptions{ IssueID: issue.ID, Since: since, Before: before, - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, } - comments, err := models.FindComments(ctx, opts) + comments, err := issues_model.FindComments(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "FindComments", err) return } - totalCount, err := models.CountComments(opts) + totalCount, err := issues_model.CountComments(opts) if err != nil { ctx.InternalServerError(err) return } - if err := models.CommentList(comments).LoadPosters(); err != nil { + if err := issues_model.CommentList(comments).LoadPosters(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } @@ -157,35 +157,35 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) return } - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) return } issue.Repo = ctx.Repo.Repository - opts := &models.FindCommentsOptions{ + opts := &issues_model.FindCommentsOptions{ ListOptions: utils.GetListOptions(ctx), IssueID: issue.ID, Since: since, Before: before, - Type: models.CommentTypeUnknown, + Type: issues_model.CommentTypeUnknown, } - comments, err := models.FindComments(ctx, opts) + comments, err := issues_model.FindComments(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "FindComments", err) return } - if err := models.CommentList(comments).LoadPosters(); err != nil { + if err := issues_model.CommentList(comments).LoadPosters(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } var apiComments []*api.TimelineComment for _, comment := range comments { - if comment.Type != models.CommentTypeCode && isXRefCommentAccessible(ctx, ctx.Doer, comment, issue.RepoID) { + if comment.Type != issues_model.CommentTypeCode && isXRefCommentAccessible(ctx, ctx.Doer, comment, issue.RepoID) { comment.Issue = issue apiComments = append(apiComments, convert.ToTimelineComment(comment, ctx.Doer)) } @@ -195,9 +195,9 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { ctx.JSON(http.StatusOK, &apiComments) } -func isXRefCommentAccessible(ctx stdCtx.Context, user *user_model.User, c *models.Comment, issueRepoID int64) bool { +func isXRefCommentAccessible(ctx stdCtx.Context, user *user_model.User, c *issues_model.Comment, issueRepoID int64) bool { // Remove comments that the user has no permissions to see - if models.CommentTypeIsRef(c.Type) && c.RefRepoID != issueRepoID && c.RefRepoID != 0 { + if issues_model.CommentTypeIsRef(c.Type) && c.RefRepoID != issueRepoID && c.RefRepoID != 0 { var err error // Set RefRepo for description in template c.RefRepo, err = repo_model.GetRepositoryByIDCtx(ctx, c.RefRepoID) @@ -261,41 +261,41 @@ func ListRepoIssueComments(ctx *context.APIContext) { return } - opts := &models.FindCommentsOptions{ + opts := &issues_model.FindCommentsOptions{ ListOptions: utils.GetListOptions(ctx), RepoID: ctx.Repo.Repository.ID, - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, Since: since, Before: before, } - comments, err := models.FindComments(ctx, opts) + comments, err := issues_model.FindComments(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "FindComments", err) return } - totalCount, err := models.CountComments(opts) + totalCount, err := issues_model.CountComments(opts) if err != nil { ctx.InternalServerError(err) return } - if err = models.CommentList(comments).LoadPosters(); err != nil { + if err = issues_model.CommentList(comments).LoadPosters(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } apiComments := make([]*api.Comment, len(comments)) - if err := models.CommentList(comments).LoadIssues(); err != nil { + if err := issues_model.CommentList(comments).LoadIssues(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadIssues", err) return } - if err := models.CommentList(comments).LoadPosters(); err != nil { + if err := issues_model.CommentList(comments).LoadPosters(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } - if _, err := models.CommentList(comments).Issues().LoadRepositories(); err != nil { + if _, err := issues_model.CommentList(comments).Issues().LoadRepositories(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadRepositories", err) return } @@ -343,7 +343,7 @@ func CreateIssueComment(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" form := web.GetForm(ctx).(*api.CreateIssueCommentOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) return @@ -399,9 +399,9 @@ func GetIssueComment(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -418,7 +418,7 @@ func GetIssueComment(ctx *context.APIContext) { return } - if comment.Type != models.CommentTypeComment { + if comment.Type != issues_model.CommentTypeComment { ctx.Status(http.StatusNoContent) return } @@ -526,9 +526,9 @@ func EditIssueCommentDeprecated(ctx *context.APIContext) { } func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -541,7 +541,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) return } - if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeReview && comment.Type != models.CommentTypeCode { + if comment.Type != issues_model.CommentTypeComment && comment.Type != issues_model.CommentTypeReview && comment.Type != issues_model.CommentTypeCode { ctx.Status(http.StatusNoContent) return } @@ -629,9 +629,9 @@ func DeleteIssueCommentDeprecated(ctx *context.APIContext) { } func deleteIssueComment(ctx *context.APIContext) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -642,7 +642,7 @@ func deleteIssueComment(ctx *context.APIContext) { if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.IsAdmin()) { ctx.Status(http.StatusForbidden) return - } else if comment.Type != models.CommentTypeComment { + } else if comment.Type != issues_model.CommentTypeComment { ctx.Status(http.StatusNoContent) return } diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index 0193eb4230..50c09e02fa 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -8,7 +8,7 @@ package repo import ( "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -46,9 +46,9 @@ func ListIssueLabels(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -56,7 +56,7 @@ func ListIssueLabels(ctx *context.APIContext) { return } - if err := issue.LoadAttributes(); err != nil { + if err := issue.LoadAttributes(ctx); err != nil { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } @@ -111,7 +111,7 @@ func AddIssueLabels(ctx *context.APIContext) { return } - labels, err = models.GetLabelsByIssueID(ctx, issue.ID) + labels, err = issues_model.GetLabelsByIssueID(ctx, issue.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByIssueID", err) return @@ -158,9 +158,9 @@ func DeleteIssueLabel(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -173,9 +173,9 @@ func DeleteIssueLabel(ctx *context.APIContext) { return } - label, err := models.GetLabelByID(ctx, ctx.ParamsInt64(":id")) + label, err := issues_model.GetLabelByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrLabelNotExist(err) { + if issues_model.IsErrLabelNotExist(err) { ctx.Error(http.StatusUnprocessableEntity, "", err) } else { ctx.Error(http.StatusInternalServerError, "GetLabelByID", err) @@ -237,7 +237,7 @@ func ReplaceIssueLabels(ctx *context.APIContext) { return } - labels, err = models.GetLabelsByIssueID(ctx, issue.ID) + labels, err = issues_model.GetLabelsByIssueID(ctx, issue.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByIssueID", err) return @@ -276,9 +276,9 @@ func ClearIssueLabels(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -299,10 +299,10 @@ func ClearIssueLabels(ctx *context.APIContext) { ctx.Status(http.StatusNoContent) } -func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) (issue *models.Issue, labels []*models.Label, err error) { - issue, err = models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) (issue *issues_model.Issue, labels []*issues_model.Label, err error) { + issue, err = issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -310,7 +310,7 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) return } - labels, err = models.GetLabelsByIDs(form.Labels) + labels, err = issues_model.GetLabelsByIDs(form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByIDs", err) return diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index 45be7a92dd..f4c40d2bcd 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -8,7 +8,6 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -49,9 +48,9 @@ func GetIssueCommentReactions(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -176,9 +175,9 @@ func DeleteIssueCommentReaction(ctx *context.APIContext) { } func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrCommentNotExist(err) { + if issues_model.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) @@ -271,9 +270,9 @@ func GetIssueReactions(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -391,9 +390,9 @@ func DeleteIssueReaction(ctx *context.APIContext) { } func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) { - issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index 382f294346..941b22e454 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -8,7 +8,7 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/routers/api/v1/utils" @@ -55,7 +55,7 @@ func StartIssueStopwatch(ctx *context.APIContext) { return } - if err := models.CreateIssueStopwatch(ctx, ctx.Doer, issue); err != nil { + if err := issues_model.CreateIssueStopwatch(ctx, ctx.Doer, issue); err != nil { ctx.Error(http.StatusInternalServerError, "CreateOrStopIssueStopwatch", err) return } @@ -104,7 +104,7 @@ func StopIssueStopwatch(ctx *context.APIContext) { return } - if err := models.FinishIssueStopwatch(ctx, ctx.Doer, issue); err != nil { + if err := issues_model.FinishIssueStopwatch(ctx, ctx.Doer, issue); err != nil { ctx.Error(http.StatusInternalServerError, "CreateOrStopIssueStopwatch", err) return } @@ -153,7 +153,7 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { return } - if err := models.CancelStopwatch(ctx.Doer, issue); err != nil { + if err := issues_model.CancelStopwatch(ctx.Doer, issue); err != nil { ctx.Error(http.StatusInternalServerError, "CancelStopwatch", err) return } @@ -161,10 +161,10 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { ctx.Status(http.StatusNoContent) } -func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.Issue, error) { - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*issues_model.Issue, error) { + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -183,7 +183,7 @@ func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.I return nil, errors.New("Cannot use time tracker") } - if models.StopwatchExists(ctx.Doer.ID, issue.ID) != shouldExist { + if issues_model.StopwatchExists(ctx.Doer.ID, issue.ID) != shouldExist { if shouldExist { ctx.Error(http.StatusConflict, "StopwatchExists", "cannot stop/cancel a non existent stopwatch") err = errors.New("cannot stop/cancel a non existent stopwatch") @@ -219,13 +219,13 @@ func GetStopwatches(ctx *context.APIContext) { // "200": // "$ref": "#/responses/StopWatchList" - sws, err := models.GetUserStopwatches(ctx.Doer.ID, utils.GetListOptions(ctx)) + sws, err := issues_model.GetUserStopwatches(ctx.Doer.ID, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetUserStopwatches", err) return } - count, err := models.CountUserStopwatches(ctx.Doer.ID) + count, err := issues_model.CountUserStopwatches(ctx.Doer.ID) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index a608ba2278..5e03e42b4c 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -8,7 +8,7 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -105,9 +105,9 @@ func DelIssueSubscription(ctx *context.APIContext) { } func setIssueSubscription(ctx *context.APIContext, watch bool) { - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -133,7 +133,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { return } - current, err := models.CheckIssueWatch(user, issue) + current, err := issues_model.CheckIssueWatch(user, issue) if err != nil { ctx.Error(http.StatusInternalServerError, "CheckIssueWatch", err) return @@ -146,7 +146,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { } // Update watch state - if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, watch); err != nil { + if err := issues_model.CreateOrUpdateIssueWatch(user.ID, issue.ID, watch); err != nil { ctx.Error(http.StatusInternalServerError, "CreateOrUpdateIssueWatch", err) return } @@ -186,9 +186,9 @@ func CheckIssueSubscription(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -197,7 +197,7 @@ func CheckIssueSubscription(ctx *context.APIContext) { return } - watching, err := models.CheckIssueWatch(ctx.Doer, issue) + watching, err := issues_model.CheckIssueWatch(ctx.Doer, issue) if err != nil { ctx.InternalServerError(err) return @@ -252,9 +252,9 @@ func GetIssueSubscribers(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -263,7 +263,7 @@ func GetIssueSubscribers(ctx *context.APIContext) { return } - iwl, err := models.GetIssueWatchers(ctx, issue.ID, utils.GetListOptions(ctx)) + iwl, err := issues_model.GetIssueWatchers(ctx, issue.ID, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetIssueWatchers", err) return @@ -284,7 +284,7 @@ func GetIssueSubscribers(ctx *context.APIContext) { apiUsers = append(apiUsers, convert.ToUser(v, ctx.Doer)) } - count, err := models.CountIssueWatchers(ctx, issue.ID) + count, err := issues_model.CountIssueWatchers(ctx, issue.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "CountIssueWatchers", err) return diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index 19e1a82590..b9a6c5af64 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -9,8 +9,8 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" @@ -76,9 +76,9 @@ func ListTrackedTimes(ctx *context.APIContext) { ctx.NotFound("Timetracker is disabled") return } - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -86,7 +86,7 @@ func ListTrackedTimes(ctx *context.APIContext) { return } - opts := &models.FindTrackedTimesOptions{ + opts := &issues_model.FindTrackedTimesOptions{ ListOptions: utils.GetListOptions(ctx), RepositoryID: ctx.Repo.Repository.ID, IssueID: issue.ID, @@ -122,13 +122,13 @@ func ListTrackedTimes(ctx *context.APIContext) { } } - count, err := models.CountTrackedTimes(opts) + count, err := issues_model.CountTrackedTimes(opts) if err != nil { ctx.InternalServerError(err) return } - trackedTimes, err := models.GetTrackedTimes(ctx, opts) + trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) return @@ -180,9 +180,9 @@ func AddTime(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" form := web.GetForm(ctx).(*api.AddTimeOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -215,7 +215,7 @@ func AddTime(ctx *context.APIContext) { created = form.Created } - trackedTime, err := models.AddTime(user, issue, form.Time, created) + trackedTime, err := issues_model.AddTime(user, issue, form.Time, created) if err != nil { ctx.Error(http.StatusInternalServerError, "AddTime", err) return @@ -261,9 +261,9 @@ func ResetIssueTime(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -280,7 +280,7 @@ func ResetIssueTime(ctx *context.APIContext) { return } - err = models.DeleteIssueUserTimes(issue, ctx.Doer) + err = issues_model.DeleteIssueUserTimes(issue, ctx.Doer) if err != nil { if db.IsErrNotExist(err) { ctx.Error(http.StatusNotFound, "DeleteIssueUserTimes", err) @@ -332,9 +332,9 @@ func DeleteTime(ctx *context.APIContext) { // "403": // "$ref": "#/responses/forbidden" - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) @@ -351,7 +351,7 @@ func DeleteTime(ctx *context.APIContext) { return } - time, err := models.GetTrackedTimeByID(ctx.ParamsInt64(":id")) + time, err := issues_model.GetTrackedTimeByID(ctx.ParamsInt64(":id")) if err != nil { if db.IsErrNotExist(err) { ctx.NotFound(err) @@ -371,7 +371,7 @@ func DeleteTime(ctx *context.APIContext) { return } - err = models.DeleteTime(time) + err = issues_model.DeleteTime(time) if err != nil { ctx.Error(http.StatusInternalServerError, "DeleteTime", err) return @@ -434,12 +434,12 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { return } - opts := &models.FindTrackedTimesOptions{ + opts := &issues_model.FindTrackedTimesOptions{ UserID: user.ID, RepositoryID: ctx.Repo.Repository.ID, } - trackedTimes, err := models.GetTrackedTimes(ctx, opts) + trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) return @@ -504,7 +504,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { return } - opts := &models.FindTrackedTimesOptions{ + opts := &issues_model.FindTrackedTimesOptions{ ListOptions: utils.GetListOptions(ctx), RepositoryID: ctx.Repo.Repository.ID, } @@ -541,13 +541,13 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { } } - count, err := models.CountTrackedTimes(opts) + count, err := issues_model.CountTrackedTimes(opts) if err != nil { ctx.InternalServerError(err) return } - trackedTimes, err := models.GetTrackedTimes(ctx, opts) + trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) return @@ -592,7 +592,7 @@ func ListMyTrackedTimes(ctx *context.APIContext) { // "200": // "$ref": "#/responses/TrackedTimeList" - opts := &models.FindTrackedTimesOptions{ + opts := &issues_model.FindTrackedTimesOptions{ ListOptions: utils.GetListOptions(ctx), UserID: ctx.Doer.ID, } @@ -603,13 +603,13 @@ func ListMyTrackedTimes(ctx *context.APIContext) { return } - count, err := models.CountTrackedTimes(opts) + count, err := issues_model.CountTrackedTimes(opts) if err != nil { ctx.InternalServerError(err) return } - trackedTimes, err := models.GetTrackedTimes(ctx, opts) + trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) return diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index 4332b8e627..8b1e298668 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -11,7 +11,7 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -49,13 +49,13 @@ func ListLabels(ctx *context.APIContext) { // "200": // "$ref": "#/responses/LabelList" - labels, err := models.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) + labels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsByRepoID", err) return } - count, err := models.CountLabelsByRepoID(ctx.Repo.Repository.ID) + count, err := issues_model.CountLabelsByRepoID(ctx.Repo.Repository.ID) if err != nil { ctx.InternalServerError(err) return @@ -94,17 +94,17 @@ func GetLabel(ctx *context.APIContext) { // "$ref": "#/responses/Label" var ( - label *models.Label + label *issues_model.Label err error ) strID := ctx.Params(":id") if intID, err2 := strconv.ParseInt(strID, 10, 64); err2 != nil { - label, err = models.GetLabelInRepoByName(ctx, ctx.Repo.Repository.ID, strID) + label, err = issues_model.GetLabelInRepoByName(ctx, ctx.Repo.Repository.ID, strID) } else { - label, err = models.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, intID) + label, err = issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, intID) } if err != nil { - if models.IsErrRepoLabelNotExist(err) { + if issues_model.IsErrRepoLabelNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) @@ -150,18 +150,18 @@ func CreateLabel(ctx *context.APIContext) { if len(form.Color) == 6 { form.Color = "#" + form.Color } - if !models.LabelColorPattern.MatchString(form.Color) { + if !issues_model.LabelColorPattern.MatchString(form.Color) { ctx.Error(http.StatusUnprocessableEntity, "ColorPattern", fmt.Errorf("bad color code: %s", form.Color)) return } - label := &models.Label{ + label := &issues_model.Label{ Name: form.Name, Color: form.Color, RepoID: ctx.Repo.Repository.ID, Description: form.Description, } - if err := models.NewLabel(ctx, label); err != nil { + if err := issues_model.NewLabel(ctx, label); err != nil { ctx.Error(http.StatusInternalServerError, "NewLabel", err) return } @@ -206,9 +206,9 @@ func EditLabel(ctx *context.APIContext) { // "$ref": "#/responses/validationError" form := web.GetForm(ctx).(*api.EditLabelOption) - label, err := models.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) + label, err := issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrRepoLabelNotExist(err) { + if issues_model.IsErrRepoLabelNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) @@ -224,7 +224,7 @@ func EditLabel(ctx *context.APIContext) { if len(label.Color) == 6 { label.Color = "#" + label.Color } - if !models.LabelColorPattern.MatchString(label.Color) { + if !issues_model.LabelColorPattern.MatchString(label.Color) { ctx.Error(http.StatusUnprocessableEntity, "ColorPattern", fmt.Errorf("bad color code: %s", label.Color)) return } @@ -232,7 +232,7 @@ func EditLabel(ctx *context.APIContext) { if form.Description != nil { label.Description = *form.Description } - if err := models.UpdateLabel(label); err != nil { + if err := issues_model.UpdateLabel(label); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateLabel", err) return } @@ -266,7 +266,7 @@ func DeleteLabel(ctx *context.APIContext) { // "204": // "$ref": "#/responses/empty" - if err := models.DeleteLabel(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil { + if err := issues_model.DeleteLabel(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil { ctx.Error(http.StatusInternalServerError, "DeleteLabel", err) return } diff --git a/routers/api/v1/repo/patch.go b/routers/api/v1/repo/patch.go index 6dbf979701..40afe2d92b 100644 --- a/routers/api/v1/repo/patch.go +++ b/routers/api/v1/repo/patch.go @@ -9,6 +9,7 @@ import ( "time" "code.gitea.io/gitea/models" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" @@ -78,7 +79,7 @@ func ApplyDiffPatch(ctx *context.APIContext) { } if !canWriteFiles(ctx, apiOpts.BranchName) { - ctx.Error(http.StatusInternalServerError, "ApplyPatch", models.ErrUserDoesNotHaveAccessToRepo{ + ctx.Error(http.StatusInternalServerError, "ApplyPatch", repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 393f2d1576..50d2c9484f 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -92,7 +92,7 @@ func ListPullRequests(ctx *context.APIContext) { listOptions := utils.GetListOptions(ctx) - prs, maxResults, err := models.PullRequests(ctx.Repo.Repository.ID, &models.PullRequestsOptions{ + prs, maxResults, err := issues_model.PullRequests(ctx.Repo.Repository.ID, &issues_model.PullRequestsOptions{ ListOptions: listOptions, State: ctx.FormTrim("state"), SortType: ctx.FormTrim("sort"), @@ -160,9 +160,9 @@ func GetPullRequest(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -220,9 +220,9 @@ func DownloadPullDiffOrPatch(ctx *context.APIContext) { // "$ref": "#/responses/string" // "404": // "$ref": "#/responses/notFound" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.InternalServerError(err) @@ -297,14 +297,14 @@ func CreatePullRequest(ctx *context.APIContext) { defer headGitRepo.Close() // Check if another PR exists with the same targets - existingPr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch, models.PullRequestFlowGithub) + existingPr, err := issues_model.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch, issues_model.PullRequestFlowGithub) if err != nil { - if !models.IsErrPullRequestNotExist(err) { + if !issues_model.IsErrPullRequestNotExist(err) { ctx.Error(http.StatusInternalServerError, "GetUnmergedPullRequest", err) return } } else { - err = models.ErrPullRequestAlreadyExists{ + err = issues_model.ErrPullRequestAlreadyExists{ ID: existingPr.ID, IssueID: existingPr.Index, HeadRepoID: existingPr.HeadRepoID, @@ -317,7 +317,7 @@ func CreatePullRequest(ctx *context.APIContext) { } if len(form.Labels) > 0 { - labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) + labels, err := issues_model.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDs", err) return @@ -331,7 +331,7 @@ func CreatePullRequest(ctx *context.APIContext) { } if ctx.Repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels) + orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err) return @@ -364,7 +364,7 @@ func CreatePullRequest(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) } - prIssue := &models.Issue{ + prIssue := &issues_model.Issue{ RepoID: repo.ID, Title: form.Title, PosterID: ctx.Doer.ID, @@ -374,7 +374,7 @@ func CreatePullRequest(ctx *context.APIContext) { Content: form.Body, DeadlineUnix: deadlineUnix, } - pr := &models.PullRequest{ + pr := &issues_model.PullRequest{ HeadRepoID: headRepo.ID, BaseRepoID: repo.ID, HeadBranch: headBranch, @@ -382,11 +382,11 @@ func CreatePullRequest(ctx *context.APIContext) { HeadRepo: headRepo, BaseRepo: repo, MergeBase: compareInfo.MergeBase, - Type: models.PullRequestGitea, + Type: issues_model.PullRequestGitea, } // Get all assignee IDs - assigneeIDs, err := models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) + assigneeIDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) if err != nil { if user_model.IsErrUserNotExist(err) { ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) @@ -409,13 +409,13 @@ func CreatePullRequest(ctx *context.APIContext) { return } if !valid { - ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) + ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) return } } if err := pull_service.NewPullRequest(ctx, repo, prIssue, labelIDs, []string{}, pr, assigneeIDs); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) return } @@ -470,9 +470,9 @@ func EditPullRequest(ctx *context.APIContext) { // "$ref": "#/responses/validationError" form := web.GetForm(ctx).(*api.EditPullRequestOption) - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -510,7 +510,7 @@ func EditPullRequest(ctx *context.APIContext) { deadlineUnix = timeutil.TimeStamp(deadline.Unix()) } - if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { + if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } @@ -548,14 +548,14 @@ func EditPullRequest(ctx *context.APIContext) { } if ctx.Repo.CanWrite(unit.TypePullRequests) && form.Labels != nil { - labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) + labels, err := issues_model.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDsError", err) return } if ctx.Repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels) + orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx.Repo.Owner.ID, form.Labels) if err != nil { ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err) return @@ -564,7 +564,7 @@ func EditPullRequest(ctx *context.APIContext) { labels = append(labels, orgLabels...) } - if err = models.ReplaceIssueLabels(issue, labels, ctx.Doer); err != nil { + if err = issues_model.ReplaceIssueLabels(issue, labels, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "ReplaceLabelsError", err) return } @@ -577,9 +577,9 @@ func EditPullRequest(ctx *context.APIContext) { } issue.IsClosed = api.StateClosed == api.StateType(*form.State) } - statusChangeComment, titleChanged, err := models.UpdateIssueByAPI(issue, ctx.Doer) + statusChangeComment, titleChanged, err := issues_model.UpdateIssueByAPI(issue, ctx.Doer) if err != nil { - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies") return } @@ -602,10 +602,10 @@ func EditPullRequest(ctx *context.APIContext) { return } if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.Doer, form.Base); err != nil { - if models.IsErrPullRequestAlreadyExists(err) { + if issues_model.IsErrPullRequestAlreadyExists(err) { ctx.Error(http.StatusConflict, "IsErrPullRequestAlreadyExists", err) return - } else if models.IsErrIssueIsClosed(err) { + } else if issues_model.IsErrIssueIsClosed(err) { ctx.Error(http.StatusUnprocessableEntity, "IsErrIssueIsClosed", err) return } else if models.IsErrPullRequestHasMerged(err) { @@ -632,9 +632,9 @@ func EditPullRequest(ctx *context.APIContext) { } // Refetch from database - pr, err = models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pr.Index) + pr, err = issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pr.Index) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -676,9 +676,9 @@ func IsPullRequestMerged(ctx *context.APIContext) { // "404": // description: pull request has not been merged - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -730,9 +730,9 @@ func MergePullRequest(ctx *context.APIContext) { form := web.GetForm(ctx).(*forms.MergePullRequestForm) - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -753,7 +753,7 @@ func MergePullRequest(ctx *context.APIContext) { if ctx.IsSigned { // Update issue-user. - if err = pr.Issue.ReadBy(ctx, ctx.Doer.ID); err != nil { + if err = models.SetIssueReadBy(ctx, pr.Issue.ID, ctx.Doer.ID); err != nil { ctx.Error(http.StatusInternalServerError, "ReadBy", err) return } @@ -868,7 +868,7 @@ func MergePullRequest(ctx *context.APIContext) { if form.DeleteBranchAfterMerge { // Don't cleanup when there are other PR's that use this branch as head branch. - exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) if err != nil { ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return @@ -902,7 +902,7 @@ func MergePullRequest(ctx *context.APIContext) { } return } - if err := models.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil { + if err := issues_model.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil { // Do not fail here as branch has already been deleted log.Error("DeleteBranch: %v", err) } @@ -1079,9 +1079,9 @@ func UpdatePullRequest(ctx *context.APIContext) { // "422": // "$ref": "#/responses/validationError" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -1177,9 +1177,9 @@ func CancelScheduledAutoMerge(ctx *context.APIContext) { // "$ref": "#/responses/notFound" pullIndex := ctx.ParamsInt64(":index") - pull, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pullIndex) + pull, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pullIndex) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() return } @@ -1254,9 +1254,9 @@ func GetPullRequestCommits(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 5175fa921f..57548f2102 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -9,7 +9,7 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" access_model "code.gitea.io/gitea/models/perm/access" user_model "code.gitea.io/gitea/models/user" @@ -61,9 +61,9 @@ func ListPullReviews(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -81,19 +81,19 @@ func ListPullReviews(ctx *context.APIContext) { return } - opts := models.FindReviewOptions{ + opts := issues_model.FindReviewOptions{ ListOptions: utils.GetListOptions(ctx), - Type: models.ReviewTypeUnknown, + Type: issues_model.ReviewTypeUnknown, IssueID: pr.IssueID, } - allReviews, err := models.FindReviews(ctx, opts) + allReviews, err := issues_model.FindReviews(ctx, opts) if err != nil { ctx.InternalServerError(err) return } - count, err := models.CountReviews(opts) + count, err := issues_model.CountReviews(opts) if err != nil { ctx.InternalServerError(err) return @@ -261,7 +261,7 @@ func DeletePullReview(ctx *context.APIContext) { return } - if err := models.DeleteReview(review); err != nil { + if err := issues_model.DeleteReview(review); err != nil { ctx.Error(http.StatusInternalServerError, "DeleteReview", fmt.Errorf("can not delete ReviewID: %d", review.ID)) return } @@ -307,9 +307,9 @@ func CreatePullReview(ctx *context.APIContext) { // "$ref": "#/responses/validationError" opts := web.GetForm(ctx).(*api.CreatePullReviewOptions) - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -435,7 +435,7 @@ func SubmitPullReview(ctx *context.APIContext) { return } - if review.Type != models.ReviewTypePending { + if review.Type != issues_model.ReviewTypePending { ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("only a pending review can be submitted")) return } @@ -447,7 +447,7 @@ func SubmitPullReview(ctx *context.APIContext) { } // if review stay pending return - if reviewType == models.ReviewTypePending { + if reviewType == issues_model.ReviewTypePending { ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("review stay pending")) return } @@ -475,7 +475,7 @@ func SubmitPullReview(ctx *context.APIContext) { } // preparePullReviewType return ReviewType and false or nil and true if an error happen -func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, event api.ReviewStateType, body string, hasComments bool) (models.ReviewType, bool) { +func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest, event api.ReviewStateType, body string, hasComments bool) (issues_model.ReviewType, bool) { if err := pr.LoadIssue(); err != nil { ctx.Error(http.StatusInternalServerError, "LoadIssue", err) return -1, true @@ -484,7 +484,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even needsBody := true hasBody := len(strings.TrimSpace(body)) > 0 - var reviewType models.ReviewType + var reviewType issues_model.ReviewType switch event { case api.ReviewStateApproved: // can not approve your own PR @@ -492,7 +492,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("approve your own pull is not allowed")) return -1, true } - reviewType = models.ReviewTypeApprove + reviewType = issues_model.ReviewTypeApprove needsBody = false case api.ReviewStateRequestChanges: @@ -501,10 +501,10 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("reject your own pull is not allowed")) return -1, true } - reviewType = models.ReviewTypeReject + reviewType = issues_model.ReviewTypeReject case api.ReviewStateComment: - reviewType = models.ReviewTypeComment + reviewType = issues_model.ReviewTypeComment needsBody = false // if there is no body we need to ensure that there are comments if !hasBody && !hasComments { @@ -512,7 +512,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even return -1, true } default: - reviewType = models.ReviewTypePending + reviewType = issues_model.ReviewTypePending } // reject reviews with empty body if a body is required for this call @@ -525,10 +525,10 @@ func preparePullReviewType(ctx *context.APIContext, pr *models.PullRequest, even } // prepareSingleReview return review, related pull and false or nil, nil and true if an error happen -func prepareSingleReview(ctx *context.APIContext) (*models.Review, *models.PullRequest, bool) { - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func prepareSingleReview(ctx *context.APIContext) (*issues_model.Review, *issues_model.PullRequest, bool) { + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -536,9 +536,9 @@ func prepareSingleReview(ctx *context.APIContext) (*models.Review, *models.PullR return nil, nil, true } - review, err := models.GetReviewByID(ctx, ctx.ParamsInt64(":id")) + review, err := issues_model.GetReviewByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - if models.IsErrReviewNotExist(err) { + if issues_model.IsErrReviewNotExist(err) { ctx.NotFound("GetReviewByID", err) } else { ctx.Error(http.StatusInternalServerError, "GetReviewByID", err) @@ -553,7 +553,7 @@ func prepareSingleReview(ctx *context.APIContext) (*models.Review, *models.PullR } // make sure that the user has access to this review if it is pending - if review.Type == models.ReviewTypePending && review.ReviewerID != ctx.Doer.ID && !ctx.Doer.IsAdmin { + if review.Type == issues_model.ReviewTypePending && review.ReviewerID != ctx.Doer.ID && !ctx.Doer.IsAdmin { ctx.NotFound("GetReviewByID") return nil, nil, true } @@ -648,9 +648,9 @@ func DeleteReviewRequests(ctx *context.APIContext) { } func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions, isAdd bool) { - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) @@ -690,7 +690,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions err = issue_service.IsValidReviewRequest(ctx, reviewer, ctx.Doer, isAdd, pr.Issue, &permDoer) if err != nil { - if models.IsErrNotValidReviewRequest(err) { + if issues_model.IsErrNotValidReviewRequest(err) { ctx.Error(http.StatusUnprocessableEntity, "NotValidReviewRequest", err) return } @@ -701,9 +701,9 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions reviewers = append(reviewers, reviewer) } - var reviews []*models.Review + var reviews []*issues_model.Review if isAdd { - reviews = make([]*models.Review, 0, len(reviewers)) + reviews = make([]*issues_model.Review, 0, len(reviewers)) } for _, reviewer := range reviewers { @@ -739,7 +739,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions err = issue_service.IsValidTeamReviewRequest(ctx, teamReviewer, ctx.Doer, isAdd, pr.Issue) if err != nil { - if models.IsErrNotValidReviewRequest(err) { + if issues_model.IsErrNotValidReviewRequest(err) { ctx.Error(http.StatusUnprocessableEntity, "NotValidReviewRequest", err) return } @@ -876,7 +876,7 @@ func dismissReview(ctx *context.APIContext, msg string, isDismiss bool) { return } - if review.Type != models.ReviewTypeApprove && review.Type != models.ReviewTypeReject { + if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject { ctx.Error(http.StatusForbidden, "", "not need to dismiss this review because it's type is not Approve or change request") return } @@ -892,7 +892,7 @@ func dismissReview(ctx *context.APIContext, msg string, isDismiss bool) { return } - if review, err = models.GetReviewByID(ctx, review.ID); err != nil { + if review, err = issues_model.GetReviewByID(ctx, review.ID); err != nil { ctx.Error(http.StatusInternalServerError, "GetReviewByID", err) return } diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index eb2bbc1e5f..93aa450f9c 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -11,7 +11,7 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" gitea_context "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -141,8 +141,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { continue } - pr, err := models.GetPullRequestByIndex(ctx, repo.ID, pullIndex) - if err != nil && !models.IsErrPullRequestNotExist(err) { + pr, err := issues_model.GetPullRequestByIndex(ctx, repo.ID, pullIndex) + if err != nil && !issues_model.IsErrPullRequestNotExist(err) { log.Error("Failed to get PR by index %v Error: %v", pullIndex, err) ctx.JSON(http.StatusInternalServerError, private.Response{ Err: fmt.Sprintf("Failed to get PR by index %v Error: %v", pullIndex, err), @@ -202,8 +202,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { continue } - pr, err := models.GetUnmergedPullRequest(repo.ID, baseRepo.ID, branch, baseRepo.DefaultBranch, models.PullRequestFlowGithub) - if err != nil && !models.IsErrPullRequestNotExist(err) { + pr, err := issues_model.GetUnmergedPullRequest(repo.ID, baseRepo.ID, branch, baseRepo.DefaultBranch, issues_model.PullRequestFlowGithub) + if err != nil && !issues_model.IsErrPullRequestNotExist(err) { log.Error("Failed to get active PR in: %-v Branch: %s to: %-v Branch: %s Error: %v", repo, branch, baseRepo, baseRepo.DefaultBranch, err) ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{ Err: fmt.Sprintf( diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 411319f2e6..cadfea782c 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" perm_model "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" "code.gitea.io/gitea/models/unit" @@ -57,7 +58,7 @@ func (ctx *preReceiveContext) CanWriteCode() bool { if !ctx.loadPusherAndPermission() { return false } - ctx.canWriteCode = models.CanMaintainerWriteToBranch(ctx.userPerm, ctx.branchName, ctx.user) || ctx.deployKeyAccessMode >= perm_model.AccessModeWrite + ctx.canWriteCode = issues_model.CanMaintainerWriteToBranch(ctx.userPerm, ctx.branchName, ctx.user) || ctx.deployKeyAccessMode >= perm_model.AccessModeWrite ctx.checkedCanWriteCode = true } return ctx.canWriteCode @@ -296,7 +297,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullN // 6b. Merge (from UI or API) // Get the PR, user and permissions for the user in the repository - pr, err := models.GetPullRequestByID(ctx, ctx.opts.PullRequestID) + pr, err := issues_model.GetPullRequestByID(ctx, ctx.opts.PullRequestID) if err != nil { log.Error("Unable to get PullRequest %d Error: %v", ctx.opts.PullRequestID, err) ctx.JSON(http.StatusInternalServerError, private.Response{ diff --git a/routers/web/org/org_labels.go b/routers/web/org/org_labels.go index bfa9f162c3..185e1eee31 100644 --- a/routers/web/org/org_labels.go +++ b/routers/web/org/org_labels.go @@ -7,8 +7,8 @@ package org import ( "net/http" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/web" @@ -17,7 +17,7 @@ import ( // RetrieveLabels find all the labels of an organization func RetrieveLabels(ctx *context.Context) { - labels, err := models.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), db.ListOptions{}) + labels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("RetrieveLabels.GetLabels", err) return @@ -43,13 +43,13 @@ func NewLabel(ctx *context.Context) { return } - l := &models.Label{ + l := &issues_model.Label{ OrgID: ctx.Org.Organization.ID, Name: form.Title, Description: form.Description, Color: form.Color, } - if err := models.NewLabel(ctx, l); err != nil { + if err := issues_model.NewLabel(ctx, l); err != nil { ctx.ServerError("NewLabel", err) return } @@ -59,10 +59,10 @@ func NewLabel(ctx *context.Context) { // UpdateLabel update a label's name and color func UpdateLabel(ctx *context.Context) { form := web.GetForm(ctx).(*forms.CreateLabelForm) - l, err := models.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, form.ID) + l, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, form.ID) if err != nil { switch { - case models.IsErrOrgLabelNotExist(err): + case issues_model.IsErrOrgLabelNotExist(err): ctx.Error(http.StatusNotFound) default: ctx.ServerError("UpdateLabel", err) @@ -73,7 +73,7 @@ func UpdateLabel(ctx *context.Context) { l.Name = form.Title l.Description = form.Description l.Color = form.Color - if err := models.UpdateLabel(l); err != nil { + if err := issues_model.UpdateLabel(l); err != nil { ctx.ServerError("UpdateLabel", err) return } @@ -82,7 +82,7 @@ func UpdateLabel(ctx *context.Context) { // DeleteLabel delete a label func DeleteLabel(ctx *context.Context) { - if err := models.DeleteLabel(ctx.Org.Organization.ID, ctx.FormInt64("id")); err != nil { + if err := issues_model.DeleteLabel(ctx.Org.Organization.ID, ctx.FormInt64("id")); err != nil { ctx.Flash.Error("DeleteLabel: " + err.Error()) } else { ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success")) diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 84ad803ee5..4bd2af4e8e 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" @@ -44,7 +45,7 @@ type Branch struct { DeletedBranch *git_model.DeletedBranch CommitsAhead int CommitsBehind int - LatestPullRequest *models.PullRequest + LatestPullRequest *issues_model.PullRequest MergeMovedOn bool } @@ -264,7 +265,7 @@ func loadOneBranch(ctx *context.Context, rawBranch, defaultBranch *git.Branch, p } } - pr, err := models.GetLatestPullRequestByHeadInfo(ctx.Repo.Repository.ID, branchName) + pr, err := issues_model.GetLatestPullRequestByHeadInfo(ctx.Repo.Repository.ID, branchName) if err != nil { ctx.ServerError("GetLatestPullRequestByHeadInfo", err) return nil diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 44e89062e8..605594d5a9 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -747,9 +748,9 @@ func CompareDiff(ctx *context.Context) { ctx.Data["HeadTags"] = headTags if ctx.Data["PageIsComparePull"] == true { - pr, err := models.GetUnmergedPullRequest(ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadBranch, ci.BaseBranch, models.PullRequestFlowGithub) + pr, err := issues_model.GetUnmergedPullRequest(ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadBranch, ci.BaseBranch, issues_model.PullRequestFlowGithub) if err != nil { - if !models.IsErrPullRequestNotExist(err) { + if !issues_model.IsErrPullRequestNotExist(err) { ctx.ServerError("GetUnmergedPullRequest", err) return } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 38ee933044..11d2daeeff 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -183,11 +183,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti } } - var issueStats *models.IssueStats + var issueStats *issues_model.IssueStats if forceEmpty { - issueStats = &models.IssueStats{} + issueStats = &issues_model.IssueStats{} } else { - issueStats, err = models.GetIssueStats(&models.IssueStatsOptions{ + issueStats, err = issues_model.GetIssueStats(&issues_model.IssueStatsOptions{ RepoID: repo.ID, Labels: selectLabels, MilestoneID: milestoneID, @@ -228,11 +228,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti mileIDs = []int64{milestoneID} } - var issues []*models.Issue + var issues []*issues_model.Issue if forceEmpty { - issues = []*models.Issue{} + issues = []*issues_model.Issue{} } else { - issues, err = models.Issues(&models.IssuesOptions{ + issues, err = issues_model.Issues(&issues_model.IssuesOptions{ ListOptions: db.ListOptions{ Page: pager.Paginater.Current(), PageSize: setting.UI.IssuePagingNum, @@ -256,7 +256,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti } } - issueList := models.IssueList(issues) + issueList := issues_model.IssueList(issues) approvalCounts, err := issueList.GetApprovalCounts(ctx) if err != nil { ctx.ServerError("ApprovalCounts", err) @@ -296,14 +296,14 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti return } - labels, err := models.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByRepoID", err) return } if repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) + orgLabels, err := issues_model.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByOrgID", err) return @@ -330,11 +330,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti if !ok || len(counts) == 0 { return 0 } - reviewTyp := models.ReviewTypeApprove + reviewTyp := issues_model.ReviewTypeApprove if typ == "reject" { - reviewTyp = models.ReviewTypeReject + reviewTyp = issues_model.ReviewTypeReject } else if typ == "waiting" { - reviewTyp = models.ReviewTypeRequest + reviewTyp = issues_model.ReviewTypeRequest } for _, count := range counts { if count.Type == reviewTyp { @@ -483,24 +483,24 @@ type repoReviewerSelection struct { IsTeam bool Team *organization.Team User *user_model.User - Review *models.Review + Review *issues_model.Review CanChange bool Checked bool ItemID int64 } // RetrieveRepoReviewers find all reviewers of a repository -func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, issue *models.Issue, canChooseReviewer bool) { +func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, issue *issues_model.Issue, canChooseReviewer bool) { ctx.Data["CanChooseReviewer"] = canChooseReviewer - originalAuthorReviews, err := models.GetReviewersFromOriginalAuthorsByIssueID(issue.ID) + originalAuthorReviews, err := issues_model.GetReviewersFromOriginalAuthorsByIssueID(issue.ID) if err != nil { ctx.ServerError("GetReviewersFromOriginalAuthorsByIssueID", err) return } ctx.Data["OriginalReviews"] = originalAuthorReviews - reviews, err := models.GetReviewersByIssueID(issue.ID) + reviews, err := issues_model.GetReviewersByIssueID(issue.ID) if err != nil { ctx.ServerError("GetReviewersByIssueID", err) return @@ -549,7 +549,7 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is for _, review := range reviews { tmp := &repoReviewerSelection{ - Checked: review.Type == models.ReviewTypeRequest, + Checked: review.Type == issues_model.ReviewTypeRequest, Review: review, ItemID: review.ReviewerID, } @@ -561,10 +561,10 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is if ctx.Repo.IsAdmin() { // Admin can dismiss or re-request any review requests tmp.CanChange = true - } else if ctx.Doer != nil && ctx.Doer.ID == review.ReviewerID && review.Type == models.ReviewTypeRequest { + } else if ctx.Doer != nil && ctx.Doer.ID == review.ReviewerID && review.Type == issues_model.ReviewTypeRequest { // A user can refuse review requests tmp.CanChange = true - } else if (canChooseReviewer || (ctx.Doer != nil && ctx.Doer.ID == issue.PosterID)) && review.Type != models.ReviewTypeRequest && + } else if (canChooseReviewer || (ctx.Doer != nil && ctx.Doer.ID == issue.PosterID)) && review.Type != issues_model.ReviewTypeRequest && ctx.Doer.ID != review.ReviewerID { // The poster of the PR, a manager, or official reviewers can re-request review from other reviewers tmp.CanChange = true @@ -670,19 +670,19 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is } // RetrieveRepoMetas find all the meta information of a repository -func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull bool) []*models.Label { +func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull bool) []*issues_model.Label { if !ctx.Repo.CanWriteIssuesOrPulls(isPull) { return nil } - labels, err := models.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByRepoID", err) return nil } ctx.Data["Labels"] = labels if repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) + orgLabels, err := issues_model.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { return nil } @@ -763,10 +763,10 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleDirs, ctx.Data[issueTemplateTitleKey] = meta.Title ctx.Data[ctxDataKey] = templateBody labelIDs := make([]string, 0, len(meta.Labels)) - if repoLabels, err := models.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, "", db.ListOptions{}); err == nil { + if repoLabels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, "", db.ListOptions{}); err == nil { ctx.Data["Labels"] = repoLabels if ctx.Repo.Owner.IsOrganization() { - if orgLabels, err := models.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}); err == nil { + if orgLabels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}); err == nil { ctx.Data["OrgLabels"] = orgLabels repoLabels = append(repoLabels, orgLabels...) } @@ -969,7 +969,7 @@ func ValidateRepoMetas(ctx *context.Context, form forms.CreateIssueForm, isPull } if !valid { - ctx.ServerError("canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) + ctx.ServerError("canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) return nil, nil, 0, 0 } } @@ -1017,7 +1017,7 @@ func NewIssuePost(ctx *context.Context) { return } - issue := &models.Issue{ + issue := &issues_model.Issue{ RepoID: repo.ID, Repo: repo, Title: form.Title, @@ -1029,7 +1029,7 @@ func NewIssuePost(ctx *context.Context) { } if err := issue_service.NewIssue(repo, issue, labelIDs, attachments, assigneeIDs); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) return } @@ -1038,7 +1038,7 @@ func NewIssuePost(ctx *context.Context) { } if projectID > 0 { - if err := models.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { + if err := issues_model.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { ctx.ServerError("ChangeProjectAssign", err) return } @@ -1053,29 +1053,29 @@ func NewIssuePost(ctx *context.Context) { } // 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, issue *models.Issue) (models.RoleDescriptor, error) { +func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue) (issues_model.RoleDescriptor, error) { perm, err := access_model.GetUserRepoPermission(ctx, repo, poster) if err != nil { - return models.RoleDescriptorNone, err + return issues_model.RoleDescriptorNone, err } // By default the poster has no roles on the comment. - roleDescriptor := models.RoleDescriptorNone + roleDescriptor := issues_model.RoleDescriptorNone // Check if the poster is owner of the repo. if perm.IsOwner() { // If the poster isn't a admin, enable the owner role. if !poster.IsAdmin { - roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorOwner) + roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner) } else { // Otherwise check if poster is the real repo admin. ok, err := access_model.IsUserRealRepoAdmin(repo, poster) if err != nil { - return models.RoleDescriptorNone, err + return issues_model.RoleDescriptorNone, err } if ok { - roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorOwner) + roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorOwner) } } } @@ -1083,18 +1083,18 @@ func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *use // Is the poster can write issues or pulls to the repo, enable the Writer role. // Only enable this if the poster doesn't have the owner role already. if !roleDescriptor.HasRole("Owner") && perm.CanWriteIssuesOrPulls(issue.IsPull) { - roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorWriter) + roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorWriter) } // If the poster is the actual poster of the issue, enable Poster role. if issue.IsPoster(poster.ID) { - roleDescriptor = roleDescriptor.WithRole(models.RoleDescriptorPoster) + roleDescriptor = roleDescriptor.WithRole(issues_model.RoleDescriptorPoster) } return roleDescriptor, nil } -func getBranchData(ctx *context.Context, issue *models.Issue) { +func getBranchData(ctx *context.Context, issue *issues_model.Issue) { ctx.Data["BaseBranch"] = nil ctx.Data["HeadBranch"] = nil ctx.Data["HeadUserName"] = nil @@ -1131,9 +1131,9 @@ func ViewIssue(ctx *context.Context) { } } - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound("GetIssueByIndex", err) } else { ctx.ServerError("GetIssueByIndex", err) @@ -1182,7 +1182,7 @@ func ViewIssue(ctx *context.Context) { ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled upload.AddUploadContext(ctx, "comment") - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(ctx); err != nil { ctx.ServerError("LoadAttributes", err) return } @@ -1194,11 +1194,11 @@ func ViewIssue(ctx *context.Context) { ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, issue.Title) - iw := new(models.IssueWatch) + iw := new(issues_model.IssueWatch) if ctx.Doer != nil { iw.UserID = ctx.Doer.ID iw.IssueID = issue.ID - iw.IsWatching, err = models.CheckIssueWatch(ctx.Doer, issue) + iw.IsWatching, err = issues_model.CheckIssueWatch(ctx.Doer, issue) if err != nil { ctx.ServerError("CheckIssueWatch", err) return @@ -1239,7 +1239,7 @@ func ViewIssue(ctx *context.Context) { for i := range issue.Labels { labelIDMark[issue.Labels[i].ID] = true } - labels, err := models.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByRepoID", err) return @@ -1247,7 +1247,7 @@ func ViewIssue(ctx *context.Context) { ctx.Data["Labels"] = labels if repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) + orgLabels, err := issues_model.GetLabelsByOrgID(ctx, repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByOrgID", err) return @@ -1279,7 +1279,7 @@ func ViewIssue(ctx *context.Context) { if issue.IsPull { canChooseReviewer := ctx.Repo.CanWrite(unit.TypePullRequests) if !canChooseReviewer && ctx.Doer != nil && ctx.IsSigned { - canChooseReviewer, err = models.IsOfficialReviewer(ctx, issue, ctx.Doer) + canChooseReviewer, err = issues_model.IsOfficialReviewer(ctx, issue, ctx.Doer) if err != nil { ctx.ServerError("IsOfficialReviewer", err) return @@ -1294,35 +1294,35 @@ func ViewIssue(ctx *context.Context) { if ctx.IsSigned { // Update issue-user. - if err = issue.ReadBy(ctx, ctx.Doer.ID); err != nil { + if err = models.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) return } } var ( - role models.RoleDescriptor + role issues_model.RoleDescriptor ok bool - marked = make(map[int64]models.RoleDescriptor) - comment *models.Comment + marked = make(map[int64]issues_model.RoleDescriptor) + comment *issues_model.Comment participants = make([]*user_model.User, 1, 10) ) if ctx.Repo.Repository.IsTimetrackerEnabled() { if ctx.IsSigned { // Deal with the stopwatch - ctx.Data["IsStopwatchRunning"] = models.StopwatchExists(ctx.Doer.ID, issue.ID) + ctx.Data["IsStopwatchRunning"] = issues_model.StopwatchExists(ctx.Doer.ID, issue.ID) if !ctx.Data["IsStopwatchRunning"].(bool) { var exists bool - var sw *models.Stopwatch - if exists, sw, err = models.HasUserStopwatch(ctx, ctx.Doer.ID); err != nil { + var sw *issues_model.Stopwatch + if exists, sw, err = issues_model.HasUserStopwatch(ctx, ctx.Doer.ID); err != nil { ctx.ServerError("HasUserStopwatch", err) return } ctx.Data["HasUserStopwatch"] = exists if exists { // Add warning if the user has already a stopwatch - var otherIssue *models.Issue - if otherIssue, err = models.GetIssueByID(sw.IssueID); err != nil { + var otherIssue *issues_model.Issue + if otherIssue, err = issues_model.GetIssueByID(ctx, sw.IssueID); err != nil { ctx.ServerError("GetIssueByID", err) return } @@ -1338,7 +1338,7 @@ func ViewIssue(ctx *context.Context) { } else { ctx.Data["CanUseTimetracker"] = false } - if ctx.Data["WorkingUsers"], err = models.TotalTimes(&models.FindTrackedTimesOptions{IssueID: issue.ID}); err != nil { + if ctx.Data["WorkingUsers"], err = issues_model.TotalTimes(&issues_model.FindTrackedTimesOptions{IssueID: issue.ID}); err != nil { ctx.ServerError("TotalTimes", err) return } @@ -1366,7 +1366,7 @@ func ViewIssue(ctx *context.Context) { return } - if comment.Type == models.CommentTypeComment || comment.Type == models.CommentTypeReview { + if comment.Type == issues_model.CommentTypeComment || comment.Type == issues_model.CommentTypeReview { if err := comment.LoadAttachments(); err != nil { ctx.ServerError("LoadAttachments", err) return @@ -1396,12 +1396,12 @@ func ViewIssue(ctx *context.Context) { } marked[comment.PosterID] = comment.ShowRole participants = addParticipant(comment.Poster, participants) - } else if comment.Type == models.CommentTypeLabel { + } else if comment.Type == issues_model.CommentTypeLabel { if err = comment.LoadLabel(); err != nil { ctx.ServerError("LoadLabel", err) return } - } else if comment.Type == models.CommentTypeMilestone { + } else if comment.Type == issues_model.CommentTypeMilestone { if err = comment.LoadMilestone(); err != nil { ctx.ServerError("LoadMilestone", err) return @@ -1416,7 +1416,7 @@ func ViewIssue(ctx *context.Context) { if comment.MilestoneID > 0 && comment.Milestone == nil { comment.Milestone = ghostMilestone } - } else if comment.Type == models.CommentTypeProject { + } else if comment.Type == issues_model.CommentTypeProject { if err = comment.LoadProject(); err != nil { ctx.ServerError("LoadProject", err) @@ -1436,19 +1436,19 @@ func ViewIssue(ctx *context.Context) { comment.Project = ghostProject } - } else if comment.Type == models.CommentTypeAssignees || comment.Type == models.CommentTypeReviewRequest { + } else if comment.Type == issues_model.CommentTypeAssignees || comment.Type == issues_model.CommentTypeReviewRequest { if err = comment.LoadAssigneeUserAndTeam(); err != nil { ctx.ServerError("LoadAssigneeUserAndTeam", err) return } - } else if comment.Type == models.CommentTypeRemoveDependency || comment.Type == models.CommentTypeAddDependency { + } else if comment.Type == issues_model.CommentTypeRemoveDependency || comment.Type == issues_model.CommentTypeAddDependency { if err = comment.LoadDepIssueDetails(); err != nil { - if !models.IsErrIssueNotExist(err) { + if !issues_model.IsErrIssueNotExist(err) { ctx.ServerError("LoadDepIssueDetails", err) return } } - } else if comment.Type == models.CommentTypeCode || comment.Type == models.CommentTypeReview || comment.Type == models.CommentTypeDismissReview { + } else if comment.Type == issues_model.CommentTypeCode || comment.Type == issues_model.CommentTypeReview || comment.Type == issues_model.CommentTypeDismissReview { comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{ URLPrefix: ctx.Repo.RepoLink, Metas: ctx.Repo.Repository.ComposeMetas(), @@ -1459,7 +1459,7 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("RenderString", err) return } - if err = comment.LoadReview(); err != nil && !models.IsErrReviewNotExist(err) { + if err = comment.LoadReview(); err != nil && !issues_model.IsErrReviewNotExist(err) { ctx.ServerError("LoadReview", err) return } @@ -1502,14 +1502,14 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("LoadResolveDoer", err) return } - } else if comment.Type == models.CommentTypePullRequestPush { + } else if comment.Type == issues_model.CommentTypePullRequestPush { participants = addParticipant(comment.Poster, participants) if err = comment.LoadPushCommits(ctx); err != nil { ctx.ServerError("LoadPushCommits", err) return } - } else if comment.Type == models.CommentTypeAddTimeManual || - comment.Type == models.CommentTypeStopTracking { + } else if comment.Type == issues_model.CommentTypeAddTimeManual || + comment.Type == issues_model.CommentTypeStopTracking { // drop error since times could be pruned from DB.. _ = comment.LoadTime() } @@ -1562,7 +1562,7 @@ func ViewIssue(ctx *context.Context) { return } - if ctx.Data["CanMarkConversation"], err = models.CanMarkConversation(issue, ctx.Doer); err != nil { + if ctx.Data["CanMarkConversation"], err = issues_model.CanMarkConversation(issue, ctx.Doer); err != nil { ctx.ServerError("CanMarkConversation", err) return } @@ -1621,11 +1621,11 @@ func ViewIssue(ctx *context.Context) { if ctx.Doer != nil { showMergeInstructions = pull.ProtectedBranch.CanUserPush(ctx.Doer.ID) } - ctx.Data["IsBlockedByApprovals"] = !models.HasEnoughApprovals(ctx, pull.ProtectedBranch, pull) - ctx.Data["IsBlockedByRejection"] = models.MergeBlockedByRejectedReview(ctx, pull.ProtectedBranch, pull) - ctx.Data["IsBlockedByOfficialReviewRequests"] = models.MergeBlockedByOfficialReviewRequests(ctx, pull.ProtectedBranch, pull) - ctx.Data["IsBlockedByOutdatedBranch"] = models.MergeBlockedByOutdatedBranch(pull.ProtectedBranch, pull) - ctx.Data["GrantedApprovals"] = models.GetGrantedApprovalsCount(ctx, pull.ProtectedBranch, pull) + ctx.Data["IsBlockedByApprovals"] = !issues_model.HasEnoughApprovals(ctx, pull.ProtectedBranch, pull) + ctx.Data["IsBlockedByRejection"] = issues_model.MergeBlockedByRejectedReview(ctx, pull.ProtectedBranch, pull) + ctx.Data["IsBlockedByOfficialReviewRequests"] = issues_model.MergeBlockedByOfficialReviewRequests(ctx, pull.ProtectedBranch, pull) + ctx.Data["IsBlockedByOutdatedBranch"] = issues_model.MergeBlockedByOutdatedBranch(pull.ProtectedBranch, pull) + ctx.Data["GrantedApprovals"] = issues_model.GetGrantedApprovalsCount(ctx, pull.ProtectedBranch, pull) ctx.Data["RequireSigned"] = pull.ProtectedBranch.RequireSignedCommits ctx.Data["ChangedProtectedFiles"] = pull.ChangedProtectedFiles ctx.Data["IsBlockedByChangedProtectedFiles"] = len(pull.ChangedProtectedFiles) != 0 @@ -1655,7 +1655,7 @@ func ViewIssue(ctx *context.Context) { (!pull.HasMerged || ctx.Data["HeadBranchCommitID"] == ctx.Data["PullHeadCommitID"]) if isPullBranchDeletable && pull.HasMerged { - exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pull.HeadRepoID, pull.HeadBranch) + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pull.HeadRepoID, pull.HeadBranch) if err != nil { ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return @@ -1722,7 +1722,7 @@ func ViewIssue(ctx *context.Context) { } hiddenCommentTypes, _ = new(big.Int).SetString(val, 10) // we can safely ignore the failed conversion here } - ctx.Data["ShouldShowCommentType"] = func(commentType models.CommentType) bool { + ctx.Data["ShouldShowCommentType"] = func(commentType issues_model.CommentType) bool { return hiddenCommentTypes == nil || hiddenCommentTypes.Bit(int(commentType)) == 0 } @@ -1730,10 +1730,10 @@ func ViewIssue(ctx *context.Context) { } // GetActionIssue will return the issue which is used in the context. -func GetActionIssue(ctx *context.Context) *models.Issue { - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func GetActionIssue(ctx *context.Context) *issues_model.Issue { + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - ctx.NotFoundOrServerError("GetIssueByIndex", models.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError("GetIssueByIndex", issues_model.IsErrIssueNotExist, err) return nil } issue.Repo = ctx.Repo.Repository @@ -1741,21 +1741,21 @@ func GetActionIssue(ctx *context.Context) *models.Issue { if ctx.Written() { return nil } - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(ctx); err != nil { ctx.ServerError("LoadAttributes", nil) return nil } return issue } -func checkIssueRights(ctx *context.Context, issue *models.Issue) { +func checkIssueRights(ctx *context.Context, issue *issues_model.Issue) { if issue.IsPull && !ctx.Repo.CanRead(unit.TypePullRequests) || !issue.IsPull && !ctx.Repo.CanRead(unit.TypeIssues) { ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) } } -func getActionIssues(ctx *context.Context) []*models.Issue { +func getActionIssues(ctx *context.Context) []*issues_model.Issue { commaSeparatedIssueIDs := ctx.FormString("issue_ids") if len(commaSeparatedIssueIDs) == 0 { return nil @@ -1769,7 +1769,7 @@ func getActionIssues(ctx *context.Context) []*models.Issue { } issueIDs = append(issueIDs, issueID) } - issues, err := models.GetIssuesByIDs(ctx, issueIDs) + issues, err := issues_model.GetIssuesByIDs(ctx, issueIDs) if err != nil { ctx.ServerError("GetIssuesByIDs", err) return nil @@ -1782,7 +1782,7 @@ func getActionIssues(ctx *context.Context) []*models.Issue { ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) return nil } - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(ctx); err != nil { ctx.ServerError("LoadAttributes", err) return nil } @@ -1792,9 +1792,9 @@ func getActionIssues(ctx *context.Context) []*models.Issue { // GetIssueInfo get an issue of a repository func GetIssueInfo(ctx *context.Context) { - issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.Error(http.StatusNotFound) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err.Error()) @@ -1916,9 +1916,9 @@ func UpdateIssueContent(ctx *context.Context) { // UpdateIssueDeadline updates an issue deadline func UpdateIssueDeadline(ctx *context.Context) { form := web.GetForm(ctx).(*api.EditDeadlineOption) - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound("GetIssueByIndex", err) } else { ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err.Error()) @@ -1939,7 +1939,7 @@ func UpdateIssueDeadline(ctx *context.Context) { deadlineUnix = timeutil.TimeStamp(deadline.Unix()) } - if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { + if err := issues_model.UpdateIssueDeadline(issue, deadlineUnix, ctx.Doer); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err.Error()) return } @@ -2002,7 +2002,7 @@ func UpdateIssueAssignee(ctx *context.Context) { return } if !valid { - ctx.ServerError("canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name}) + ctx.ServerError("canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name}) return } @@ -2080,7 +2080,7 @@ func UpdatePullReviewRequest(ctx *context.Context) { err = issue_service.IsValidTeamReviewRequest(ctx, team, ctx.Doer, action == "attach", issue) if err != nil { - if models.IsErrNotValidReviewRequest(err) { + if issues_model.IsErrNotValidReviewRequest(err) { log.Warn( "UpdatePullReviewRequest: refusing to add invalid team review request for UID[%d] team %s to %s#%d owned by UID[%d]: Error: %v", team.OrgID, team.Name, issue.Repo.FullName(), issue.Index, issue.Repo.ID, @@ -2118,7 +2118,7 @@ func UpdatePullReviewRequest(ctx *context.Context) { err = issue_service.IsValidReviewRequest(ctx, reviewer, ctx.Doer, action == "attach", issue, nil) if err != nil { - if models.IsErrNotValidReviewRequest(err) { + if issues_model.IsErrNotValidReviewRequest(err) { log.Warn( "UpdatePullReviewRequest: refusing to add invalid review request for %-v to %-v#%d: Error: %v", reviewer, issue.Repo, issue.Index, @@ -2215,7 +2215,7 @@ func SearchIssues(ctx *context.Context) { return } - var issues []*models.Issue + var issues []*issues_model.Issue var filteredCount int64 keyword := ctx.FormTrim("q") @@ -2264,7 +2264,7 @@ func SearchIssues(ctx *context.Context) { // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(includedLabelNames) > 0 || len(includedMilestones) > 0 { - issuesOpt := &models.IssuesOptions{ + issuesOpt := &issues_model.IssuesOptions{ ListOptions: db.ListOptions{ Page: ctx.FormInt("page"), PageSize: limit, @@ -2300,7 +2300,7 @@ func SearchIssues(ctx *context.Context) { issuesOpt.ReviewRequestedID = ctxUserID } - if issues, err = models.Issues(issuesOpt); err != nil { + if issues, err = issues_model.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "Issues", err.Error()) return } @@ -2308,7 +2308,7 @@ func SearchIssues(ctx *context.Context) { issuesOpt.ListOptions = db.ListOptions{ Page: -1, } - if filteredCount, err = models.CountIssues(issuesOpt); err != nil { + if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, "CountIssues", err.Error()) return } @@ -2356,7 +2356,7 @@ func ListIssues(ctx *context.Context) { isClosed = util.OptionalBoolFalse } - var issues []*models.Issue + var issues []*issues_model.Issue var filteredCount int64 keyword := ctx.FormTrim("q") @@ -2374,7 +2374,7 @@ func ListIssues(ctx *context.Context) { } if splitted := strings.Split(ctx.FormString("labels"), ","); len(splitted) > 0 { - labelIDs, err = models.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) + labelIDs, err = issues_model.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return @@ -2443,7 +2443,7 @@ func ListIssues(ctx *context.Context) { // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { - issuesOpt := &models.IssuesOptions{ + issuesOpt := &issues_model.IssuesOptions{ ListOptions: listOptions, RepoID: ctx.Repo.Repository.ID, IsClosed: isClosed, @@ -2458,7 +2458,7 @@ func ListIssues(ctx *context.Context) { MentionedID: mentionedByID, } - if issues, err = models.Issues(issuesOpt); err != nil { + if issues, err = issues_model.Issues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return } @@ -2466,7 +2466,7 @@ func ListIssues(ctx *context.Context) { issuesOpt.ListOptions = db.ListOptions{ Page: -1, } - if filteredCount, err = models.CountIssues(issuesOpt); err != nil { + if filteredCount, err = issues_model.CountIssues(issuesOpt); err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return } @@ -2493,14 +2493,14 @@ func UpdateIssueStatus(ctx *context.Context) { log.Warn("Unrecognized action: %s", action) } - if _, err := models.IssueList(issues).LoadRepositories(); err != nil { + if _, err := issues_model.IssueList(issues).LoadRepositories(); err != nil { ctx.ServerError("LoadRepositories", err) return } for _, issue := range issues { if issue.IsClosed != isClosed { if err := issue_service.ChangeStatus(issue, ctx.Doer, isClosed); err != nil { - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { ctx.JSON(http.StatusPreconditionFailed, map[string]interface{}{ "error": "cannot close this issue because it still has open dependencies", }) @@ -2564,7 +2564,7 @@ func NewComment(ctx *context.Context) { return } - var comment *models.Comment + var comment *issues_model.Comment defer func() { // Check if issue admin/poster changes the status of issue. if (ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) || (ctx.IsSigned && issue.IsPoster(ctx.Doer.ID))) && @@ -2572,14 +2572,14 @@ func NewComment(ctx *context.Context) { !(issue.IsPull && issue.PullRequest.HasMerged) { // Duplication and conflict check should apply to reopen pull request. - var pr *models.PullRequest + var pr *issues_model.PullRequest if form.Status == "reopen" && issue.IsPull { pull := issue.PullRequest var err error - pr, err = models.GetUnmergedPullRequest(pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch, pull.Flow) + pr, err = issues_model.GetUnmergedPullRequest(pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch, pull.Flow) if err != nil { - if !models.IsErrPullRequestNotExist(err) { + if !issues_model.IsErrPullRequestNotExist(err) { ctx.ServerError("GetUnmergedPullRequest", err) return } @@ -2599,7 +2599,7 @@ func NewComment(ctx *context.Context) { if err := issue_service.ChangeStatus(issue, ctx.Doer, isClosed); err != nil { log.Error("ChangeStatus: %v", err) - if models.IsErrDependenciesLeft(err) { + if issues_model.IsErrDependenciesLeft(err) { if issue.IsPull { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.pr_close_blocked")) ctx.Redirect(fmt.Sprintf("%s/pulls/%d", ctx.Repo.RepoLink, issue.Index)) @@ -2648,14 +2648,14 @@ func NewComment(ctx *context.Context) { // UpdateCommentContent change comment of issue's content func UpdateCommentContent(ctx *context.Context) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err) return } if err := comment.LoadIssue(); err != nil { - ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err) return } @@ -2664,7 +2664,7 @@ func UpdateCommentContent(ctx *context.Context) { return } - if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeReview && comment.Type != models.CommentTypeCode { + if comment.Type != issues_model.CommentTypeComment && comment.Type != issues_model.CommentTypeReview && comment.Type != issues_model.CommentTypeCode { ctx.Error(http.StatusNoContent) return } @@ -2714,21 +2714,21 @@ func UpdateCommentContent(ctx *context.Context) { // DeleteComment delete comment of issue func DeleteComment(ctx *context.Context) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err) return } if err := comment.LoadIssue(); err != nil { - ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err) return } if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { ctx.Error(http.StatusForbidden) return - } else if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode { + } else if comment.Type != issues_model.CommentTypeComment && comment.Type != issues_model.CommentTypeCode { ctx.Error(http.StatusNoContent) return } @@ -2790,7 +2790,7 @@ func ChangeIssueReaction(ctx *context.Context) { } // Reload new reactions issue.Reactions = nil - if err = issue.LoadAttributes(); err != nil { + if err = issue.LoadAttributes(ctx); err != nil { log.Info("issue.LoadAttributes: %s", err) break } @@ -2804,7 +2804,7 @@ func ChangeIssueReaction(ctx *context.Context) { // Reload new reactions issue.Reactions = nil - if err := issue.LoadAttributes(); err != nil { + if err := issue.LoadAttributes(ctx); err != nil { log.Info("issue.LoadAttributes: %s", err) break } @@ -2840,14 +2840,14 @@ func ChangeIssueReaction(ctx *context.Context) { // ChangeCommentReaction create a reaction for comment func ChangeCommentReaction(ctx *context.Context) { form := web.GetForm(ctx).(*forms.ReactionForm) - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err) return } if err := comment.LoadIssue(); err != nil { - ctx.NotFoundOrServerError("LoadIssue", models.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError("LoadIssue", issues_model.IsErrIssueNotExist, err) return } @@ -2874,7 +2874,7 @@ func ChangeCommentReaction(ctx *context.Context) { return } - if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode && comment.Type != models.CommentTypeReview { + if comment.Type != issues_model.CommentTypeComment && comment.Type != issues_model.CommentTypeCode && comment.Type != issues_model.CommentTypeReview { ctx.Error(http.StatusNoContent) return } @@ -2948,11 +2948,11 @@ func addParticipant(poster *user_model.User, participants []*user_model.User) [] return append(participants, poster) } -func filterXRefComments(ctx *context.Context, issue *models.Issue) error { +func filterXRefComments(ctx *context.Context, issue *issues_model.Issue) error { // Remove comments that the user has no permissions to see for i := 0; i < len(issue.Comments); { c := issue.Comments[i] - if models.CommentTypeIsRef(c.Type) && c.RefRepoID != issue.RepoID && c.RefRepoID != 0 { + if issues_model.CommentTypeIsRef(c.Type) && c.RefRepoID != issue.RepoID && c.RefRepoID != 0 { var err error // Set RefRepo for description in template c.RefRepo, err = repo_model.GetRepositoryByID(c.RefRepoID) @@ -2985,13 +2985,13 @@ func GetIssueAttachments(ctx *context.Context) { // GetCommentAttachments returns attachments for the comment func GetCommentAttachments(ctx *context.Context) { - comment, err := models.GetCommentByID(ctx, ctx.ParamsInt64(":id")) + comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id")) if err != nil { - ctx.NotFoundOrServerError("GetCommentByID", models.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err) return } attachments := make([]*api.Attachment, 0) - if comment.Type == models.CommentTypeComment { + if comment.Type == issues_model.CommentTypeComment { if err := comment.LoadAttachments(); err != nil { ctx.ServerError("LoadAttachments", err) return @@ -3006,9 +3006,9 @@ func GetCommentAttachments(ctx *context.Context) { func updateAttachments(ctx *context.Context, item interface{}, files []string) error { var attachments []*repo_model.Attachment switch content := item.(type) { - case *models.Issue: + case *issues_model.Issue: attachments = content.Attachments - case *models.Comment: + case *issues_model.Comment: attachments = content.Attachments default: return fmt.Errorf("unknown Type: %T", content) @@ -3024,9 +3024,9 @@ func updateAttachments(ctx *context.Context, item interface{}, files []string) e var err error if len(files) > 0 { switch content := item.(type) { - case *models.Issue: - err = models.UpdateIssueAttachments(content.ID, files) - case *models.Comment: + case *issues_model.Issue: + err = issues_model.UpdateIssueAttachments(content.ID, files) + case *issues_model.Comment: err = content.UpdateAttachments(files) default: return fmt.Errorf("unknown Type: %T", content) @@ -3036,9 +3036,9 @@ func updateAttachments(ctx *context.Context, item interface{}, files []string) e } } switch content := item.(type) { - case *models.Issue: + case *issues_model.Issue: content.Attachments, err = repo_model.GetAttachmentsByIssueID(ctx, content.ID) - case *models.Comment: + case *issues_model.Comment: content.Attachments, err = repo_model.GetAttachmentsByCommentID(ctx, content.ID) default: return fmt.Errorf("unknown Type: %T", content) @@ -3060,17 +3060,17 @@ func attachmentsHTML(ctx *context.Context, attachments []*repo_model.Attachment, } // combineLabelComments combine the nearby label comments as one. -func combineLabelComments(issue *models.Issue) { - var prev, cur *models.Comment +func combineLabelComments(issue *issues_model.Issue) { + var prev, cur *issues_model.Comment for i := 0; i < len(issue.Comments); i++ { cur = issue.Comments[i] if i > 0 { prev = issue.Comments[i-1] } - if i == 0 || cur.Type != models.CommentTypeLabel || + if i == 0 || cur.Type != issues_model.CommentTypeLabel || (prev != nil && prev.PosterID != cur.PosterID) || (prev != nil && cur.CreatedUnix-prev.CreatedUnix >= 60) { - if cur.Type == models.CommentTypeLabel && cur.Label != nil { + if cur.Type == issues_model.CommentTypeLabel && cur.Label != nil { if cur.Content != "1" { cur.RemovedLabels = append(cur.RemovedLabels, cur.Label) } else { @@ -3081,7 +3081,7 @@ func combineLabelComments(issue *models.Issue) { } if cur.Label != nil { // now cur MUST be label comment - if prev.Type == models.CommentTypeLabel { // we can combine them only prev is a label comment + if prev.Type == issues_model.CommentTypeLabel { // we can combine them only prev is a label comment if cur.Content != "1" { // remove labels from the AddedLabels list if the label that was removed is already // in this list, and if it's not in this list, add the label to RemovedLabels diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index 407832dffe..d8a21c7fd7 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -11,8 +11,7 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" - issuesModel "code.gitea.io/gitea/models/issues" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" @@ -31,7 +30,7 @@ func GetContentHistoryOverview(ctx *context.Context) { } lang := ctx.Locale.Language() - editedHistoryCountMap, _ := issuesModel.QueryIssueContentHistoryEditedCountMap(ctx, issue.ID) + editedHistoryCountMap, _ := issues_model.QueryIssueContentHistoryEditedCountMap(ctx, issue.ID) ctx.JSON(http.StatusOK, map[string]interface{}{ "i18n": map[string]interface{}{ "textEdited": i18n.Tr(lang, "repo.issues.content_history.edited"), @@ -51,7 +50,7 @@ func GetContentHistoryList(ctx *context.Context) { return } - items, _ := issuesModel.FetchIssueContentHistoryList(ctx, issue.ID, commentID) + items, _ := issues_model.FetchIssueContentHistoryList(ctx, issue.ID, commentID) // render history list to HTML for frontend dropdown items: (name, value) // name is HTML of "avatar + userName + userAction + timeSince" @@ -89,8 +88,8 @@ func GetContentHistoryList(ctx *context.Context) { // canSoftDeleteContentHistory checks whether current user can soft-delete a history revision // Admins or owners can always delete history revisions. Normal users can only delete own history revisions. -func canSoftDeleteContentHistory(ctx *context.Context, issue *models.Issue, comment *models.Comment, - history *issuesModel.ContentHistory, +func canSoftDeleteContentHistory(ctx *context.Context, issue *issues_model.Issue, comment *issues_model.Comment, + history *issues_model.ContentHistory, ) bool { canSoftDelete := false if ctx.Repo.IsOwner() { @@ -118,7 +117,7 @@ func GetContentHistoryDetail(ctx *context.Context) { } historyID := ctx.FormInt64("history_id") - history, prevHistory, err := issuesModel.GetIssueContentHistoryAndPrev(ctx, historyID) + history, prevHistory, err := issues_model.GetIssueContentHistoryAndPrev(ctx, historyID) if err != nil { ctx.JSON(http.StatusNotFound, map[string]interface{}{ "message": "Can not find the content history", @@ -127,10 +126,10 @@ func GetContentHistoryDetail(ctx *context.Context) { } // get the related comment if this history revision is for a comment, otherwise the history revision is for an issue. - var comment *models.Comment + var comment *issues_model.Comment if history.CommentID != 0 { var err error - if comment, err = models.GetCommentByID(ctx, history.CommentID); err != nil { + if comment, err = issues_model.GetCommentByID(ctx, history.CommentID); err != nil { log.Error("can not get comment for issue content history %v. err=%v", historyID, err) return } @@ -186,16 +185,16 @@ func SoftDeleteContentHistory(ctx *context.Context) { commentID := ctx.FormInt64("comment_id") historyID := ctx.FormInt64("history_id") - var comment *models.Comment - var history *issuesModel.ContentHistory + var comment *issues_model.Comment + var history *issues_model.ContentHistory var err error if commentID != 0 { - if comment, err = models.GetCommentByID(ctx, commentID); err != nil { + if comment, err = issues_model.GetCommentByID(ctx, commentID); err != nil { log.Error("can not get comment for issue content history %v. err=%v", historyID, err) return } } - if history, err = issuesModel.GetIssueContentHistoryByID(ctx, historyID); err != nil { + if history, err = issues_model.GetIssueContentHistoryByID(ctx, historyID); err != nil { log.Error("can not get issue content history %v. err=%v", historyID, err) return } @@ -208,7 +207,7 @@ func SoftDeleteContentHistory(ctx *context.Context) { return } - err = issuesModel.SoftDeleteIssueContentHistory(ctx, historyID) + err = issues_model.SoftDeleteIssueContentHistory(ctx, historyID) log.Debug("soft delete issue content history. issue=%d, comment=%d, history=%d", issue.ID, commentID, historyID) ctx.JSON(http.StatusOK, map[string]interface{}{ "ok": err == nil, diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go index ec713238c6..d8d934ea1c 100644 --- a/routers/web/repo/issue_dependency.go +++ b/routers/web/repo/issue_dependency.go @@ -7,7 +7,7 @@ package repo import ( "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" ) @@ -15,7 +15,7 @@ import ( // AddDependency adds new dependencies func AddDependency(ctx *context.Context) { issueIndex := ctx.ParamsInt64("index") - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) if err != nil { ctx.ServerError("GetIssueByIndex", err) return @@ -38,7 +38,7 @@ func AddDependency(ctx *context.Context) { defer ctx.Redirect(issue.HTMLURL()) // Dependency - dep, err := models.GetIssueByID(depID) + dep, err := issues_model.GetIssueByID(ctx, depID) if err != nil { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_issue_not_exist")) return @@ -56,12 +56,12 @@ func AddDependency(ctx *context.Context) { return } - err = models.CreateIssueDependency(ctx.Doer, issue, dep) + err = issues_model.CreateIssueDependency(ctx.Doer, issue, dep) if err != nil { - if models.IsErrDependencyExists(err) { + if issues_model.IsErrDependencyExists(err) { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_exists")) return - } else if models.IsErrCircularDependency(err) { + } else if issues_model.IsErrCircularDependency(err) { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_cannot_create_circular")) return } else { @@ -74,7 +74,7 @@ func AddDependency(ctx *context.Context) { // RemoveDependency removes the dependency func RemoveDependency(ctx *context.Context) { issueIndex := ctx.ParamsInt64("index") - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, issueIndex) if err != nil { ctx.ServerError("GetIssueByIndex", err) return @@ -96,27 +96,27 @@ func RemoveDependency(ctx *context.Context) { // Dependency Type depTypeStr := ctx.Req.PostForm.Get("dependencyType") - var depType models.DependencyType + var depType issues_model.DependencyType switch depTypeStr { case "blockedBy": - depType = models.DependencyTypeBlockedBy + depType = issues_model.DependencyTypeBlockedBy case "blocking": - depType = models.DependencyTypeBlocking + depType = issues_model.DependencyTypeBlocking default: ctx.Error(http.StatusBadRequest, "GetDependecyType") return } // Dependency - dep, err := models.GetIssueByID(depID) + dep, err := issues_model.GetIssueByID(ctx, depID) if err != nil { ctx.ServerError("GetIssueByID", err) return } - if err = models.RemoveIssueDependency(ctx.Doer, issue, dep, depType); err != nil { - if models.IsErrDependencyNotExists(err) { + if err = issues_model.RemoveIssueDependency(ctx.Doer, issue, dep, depType); err != nil { + if issues_model.IsErrDependencyNotExists(err) { ctx.Flash.Error(ctx.Tr("repo.issues.dependency.add_error_dep_not_exist")) return } diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go index 2e72d659be..7af415a8fa 100644 --- a/routers/web/repo/issue_label.go +++ b/routers/web/repo/issue_label.go @@ -7,8 +7,8 @@ package repo import ( "net/http" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -56,7 +56,7 @@ func InitializeLabels(ctx *context.Context) { // RetrieveLabels find all the labels of a repository and organization func RetrieveLabels(ctx *context.Context) { - labels, err := models.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("RetrieveLabels.GetLabels", err) return @@ -69,7 +69,7 @@ func RetrieveLabels(ctx *context.Context) { ctx.Data["Labels"] = labels if ctx.Repo.Owner.IsOrganization() { - orgLabels, err := models.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) + orgLabels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Repo.Owner.ID, ctx.FormString("sort"), db.ListOptions{}) if err != nil { ctx.ServerError("GetLabelsByOrgID", err) return @@ -111,13 +111,13 @@ func NewLabel(ctx *context.Context) { return } - l := &models.Label{ + l := &issues_model.Label{ RepoID: ctx.Repo.Repository.ID, Name: form.Title, Description: form.Description, Color: form.Color, } - if err := models.NewLabel(ctx, l); err != nil { + if err := issues_model.NewLabel(ctx, l); err != nil { ctx.ServerError("NewLabel", err) return } @@ -127,10 +127,10 @@ func NewLabel(ctx *context.Context) { // UpdateLabel update a label's name and color func UpdateLabel(ctx *context.Context) { form := web.GetForm(ctx).(*forms.CreateLabelForm) - l, err := models.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, form.ID) + l, err := issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, form.ID) if err != nil { switch { - case models.IsErrRepoLabelNotExist(err): + case issues_model.IsErrRepoLabelNotExist(err): ctx.Error(http.StatusNotFound) default: ctx.ServerError("UpdateLabel", err) @@ -141,7 +141,7 @@ func UpdateLabel(ctx *context.Context) { l.Name = form.Title l.Description = form.Description l.Color = form.Color - if err := models.UpdateLabel(l); err != nil { + if err := issues_model.UpdateLabel(l); err != nil { ctx.ServerError("UpdateLabel", err) return } @@ -150,7 +150,7 @@ func UpdateLabel(ctx *context.Context) { // DeleteLabel delete a label func DeleteLabel(ctx *context.Context) { - if err := models.DeleteLabel(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil { + if err := issues_model.DeleteLabel(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil { ctx.Flash.Error("DeleteLabel: " + err.Error()) } else { ctx.Flash.Success(ctx.Tr("repo.issues.label_deletion_success")) @@ -177,9 +177,9 @@ func UpdateIssueLabel(ctx *context.Context) { } } case "attach", "detach", "toggle": - label, err := models.GetLabelByID(ctx, ctx.FormInt64("id")) + label, err := issues_model.GetLabelByID(ctx, ctx.FormInt64("id")) if err != nil { - if models.IsErrRepoLabelNotExist(err) { + if issues_model.IsErrRepoLabelNotExist(err) { ctx.Error(http.StatusNotFound, "GetLabelByID") } else { ctx.ServerError("GetLabelByID", err) @@ -191,7 +191,7 @@ func UpdateIssueLabel(ctx *context.Context) { // detach if any issues already have label, otherwise attach action = "attach" for _, issue := range issues { - if models.HasIssueLabel(ctx, issue.ID, label.ID) { + if issues_model.HasIssueLabel(ctx, issue.ID, label.ID) { action = "detach" break } diff --git a/routers/web/repo/issue_label_test.go b/routers/web/repo/issue_label_test.go index 5d7a29ee93..ea078e215c 100644 --- a/routers/web/repo/issue_label_test.go +++ b/routers/web/repo/issue_label_test.go @@ -9,7 +9,7 @@ import ( "strconv" "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/web" @@ -37,7 +37,7 @@ func TestInitializeLabels(t *testing.T) { web.SetForm(ctx, &forms.InitializeLabelsForm{TemplateName: "Default"}) InitializeLabels(ctx) assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) - unittest.AssertExistsAndLoadBean(t, &models.Label{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ RepoID: 2, Name: "enhancement", Color: "#84b6eb", @@ -62,7 +62,7 @@ func TestRetrieveLabels(t *testing.T) { ctx.Req.Form.Set("sort", testCase.Sort) RetrieveLabels(ctx) assert.False(t, ctx.Written()) - labels, ok := ctx.Data["Labels"].([]*models.Label) + labels, ok := ctx.Data["Labels"].([]*issues_model.Label) assert.True(t, ok) if assert.Len(t, labels, len(testCase.ExpectedLabelIDs)) { for i, label := range labels { @@ -83,7 +83,7 @@ func TestNewLabel(t *testing.T) { }) NewLabel(ctx) assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) - unittest.AssertExistsAndLoadBean(t, &models.Label{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ Name: "newlabel", Color: "#abcdef", }) @@ -102,7 +102,7 @@ func TestUpdateLabel(t *testing.T) { }) UpdateLabel(ctx) assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) - unittest.AssertExistsAndLoadBean(t, &models.Label{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ ID: 2, Name: "newnameforlabel", Color: "#abcdef", @@ -118,8 +118,8 @@ func TestDeleteLabel(t *testing.T) { ctx.Req.Form.Set("id", "2") DeleteLabel(ctx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) - unittest.AssertNotExistsBean(t, &models.Label{ID: 2}) - unittest.AssertNotExistsBean(t, &models.IssueLabel{LabelID: 2}) + unittest.AssertNotExistsBean(t, &issues_model.Label{ID: 2}) + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{LabelID: 2}) assert.Equal(t, ctx.Tr("repo.issues.label_deletion_success"), ctx.Flash.SuccessMsg) } @@ -132,9 +132,9 @@ func TestUpdateIssueLabel_Clear(t *testing.T) { ctx.Req.Form.Set("action", "clear") UpdateIssueLabel(ctx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) - unittest.AssertNotExistsBean(t, &models.IssueLabel{IssueID: 1}) - unittest.AssertNotExistsBean(t, &models.IssueLabel{IssueID: 3}) - unittest.CheckConsistencyFor(t, &models.Label{}) + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: 1}) + unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: 3}) + unittest.CheckConsistencyFor(t, &issues_model.Label{}) } func TestUpdateIssueLabel_Toggle(t *testing.T) { @@ -159,11 +159,11 @@ func TestUpdateIssueLabel_Toggle(t *testing.T) { UpdateIssueLabel(ctx) assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) for _, issueID := range testCase.IssueIDs { - unittest.AssertExistsIf(t, testCase.ExpectedAdd, &models.IssueLabel{ + unittest.AssertExistsIf(t, testCase.ExpectedAdd, &issues_model.IssueLabel{ IssueID: issueID, LabelID: testCase.LabelID, }) } - unittest.CheckConsistencyFor(t, &models.Label{}) + unittest.CheckConsistencyFor(t, &issues_model.Label{}) } } diff --git a/routers/web/repo/issue_lock.go b/routers/web/repo/issue_lock.go index 5ac5cac52e..a89ea47571 100644 --- a/routers/web/repo/issue_lock.go +++ b/routers/web/repo/issue_lock.go @@ -5,7 +5,7 @@ package repo import ( - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/forms" @@ -32,7 +32,7 @@ func LockIssue(ctx *context.Context) { return } - if err := models.LockIssue(&models.IssueLockOptions{ + if err := issues_model.LockIssue(&issues_model.IssueLockOptions{ Doer: ctx.Doer, Issue: issue, Reason: form.Reason, @@ -57,7 +57,7 @@ func UnlockIssue(ctx *context.Context) { return } - if err := models.UnlockIssue(&models.IssueLockOptions{ + if err := issues_model.UnlockIssue(&issues_model.IssueLockOptions{ Doer: ctx.Doer, Issue: issue, }); err != nil { diff --git a/routers/web/repo/issue_stopwatch.go b/routers/web/repo/issue_stopwatch.go index 4e1f6af039..68f89b258d 100644 --- a/routers/web/repo/issue_stopwatch.go +++ b/routers/web/repo/issue_stopwatch.go @@ -8,8 +8,8 @@ import ( "net/http" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/eventsource" ) @@ -23,7 +23,7 @@ func IssueStopwatch(c *context.Context) { var showSuccessMessage bool - if !models.StopwatchExists(c.Doer.ID, issue.ID) { + if !issues_model.StopwatchExists(c.Doer.ID, issue.ID) { showSuccessMessage = true } @@ -32,7 +32,7 @@ func IssueStopwatch(c *context.Context) { return } - if err := models.CreateOrStopIssueStopwatch(c.Doer, issue); err != nil { + if err := issues_model.CreateOrStopIssueStopwatch(c.Doer, issue); err != nil { c.ServerError("CreateOrStopIssueStopwatch", err) return } @@ -56,12 +56,12 @@ func CancelStopwatch(c *context.Context) { return } - if err := models.CancelStopwatch(c.Doer, issue); err != nil { + if err := issues_model.CancelStopwatch(c.Doer, issue); err != nil { c.ServerError("CancelStopwatch", err) return } - stopwatches, err := models.GetUserStopwatches(c.Doer.ID, db.ListOptions{}) + stopwatches, err := issues_model.GetUserStopwatches(c.Doer.ID, db.ListOptions{}) if err != nil { c.ServerError("GetUserStopwatches", err) return @@ -87,7 +87,7 @@ func GetActiveStopwatch(ctx *context.Context) { return } - _, sw, err := models.HasUserStopwatch(ctx, ctx.Doer.ID) + _, sw, err := issues_model.HasUserStopwatch(ctx, ctx.Doer.ID) if err != nil { ctx.ServerError("HasUserStopwatch", err) return @@ -97,7 +97,7 @@ func GetActiveStopwatch(ctx *context.Context) { return } - issue, err := models.GetIssueByID(sw.IssueID) + issue, err := issues_model.GetIssueByID(ctx, sw.IssueID) if err != nil || issue == nil { ctx.ServerError("GetIssueByID", err) return diff --git a/routers/web/repo/issue_test.go b/routers/web/repo/issue_test.go index debd2a8a3c..ad82fe0f36 100644 --- a/routers/web/repo/issue_test.go +++ b/routers/web/repo/issue_test.go @@ -7,7 +7,7 @@ package repo import ( "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "github.com/stretchr/testify/assert" ) @@ -15,50 +15,50 @@ import ( func TestCombineLabelComments(t *testing.T) { kases := []struct { name string - beforeCombined []*models.Comment - afterCombined []*models.Comment + beforeCombined []*issues_model.Comment + afterCombined []*issues_model.Comment }{ { name: "kase 1", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", CreatedUnix: 0, - AddedLabels: []*models.Label{}, - Label: &models.Label{ + AddedLabels: []*issues_model.Label{}, + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, @@ -67,63 +67,63 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 2", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 70, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", CreatedUnix: 0, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", CreatedUnix: 70, - RemovedLabels: []*models.Label{ + RemovedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, @@ -132,63 +132,63 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 3", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 2, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", CreatedUnix: 0, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 2, Content: "", CreatedUnix: 0, - RemovedLabels: []*models.Label{ + RemovedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 1, Content: "test", CreatedUnix: 0, @@ -197,33 +197,33 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 4", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/backport", }, CreatedUnix: 10, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", CreatedUnix: 10, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "kind/bug", }, @@ -231,7 +231,7 @@ func TestCombineLabelComments(t *testing.T) { Name: "kind/backport", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, }, @@ -239,41 +239,41 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 5", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 2, Content: "testtest", CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "kind/bug", }, @@ -281,21 +281,21 @@ func TestCombineLabelComments(t *testing.T) { CreatedUnix: 0, }, { - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, PosterID: 2, Content: "testtest", CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - RemovedLabels: []*models.Label{ + RemovedLabels: []*issues_model.Label{ { Name: "kind/bug", }, }, - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, @@ -304,53 +304,53 @@ func TestCombineLabelComments(t *testing.T) { }, { name: "kase 6", - beforeCombined: []*models.Comment{ + beforeCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "reviewed/confirmed", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, CreatedUnix: 0, }, { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/feature", }, CreatedUnix: 0, }, }, - afterCombined: []*models.Comment{ + afterCombined: []*issues_model.Comment{ { - Type: models.CommentTypeLabel, + Type: issues_model.CommentTypeLabel, PosterID: 1, Content: "1", - Label: &models.Label{ + Label: &issues_model.Label{ Name: "kind/bug", }, - AddedLabels: []*models.Label{ + AddedLabels: []*issues_model.Label{ { Name: "reviewed/confirmed", }, @@ -366,7 +366,7 @@ func TestCombineLabelComments(t *testing.T) { for _, kase := range kases { t.Run(kase.name, func(t *testing.T) { - issue := models.Issue{ + issue := issues_model.Issue{ Comments: kase.beforeCombined, } combineLabelComments(&issue) diff --git a/routers/web/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go index 28274a7f7b..817a2c6d20 100644 --- a/routers/web/repo/issue_timetrack.go +++ b/routers/web/repo/issue_timetrack.go @@ -8,8 +8,8 @@ import ( "net/http" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -43,7 +43,7 @@ func AddTimeManually(c *context.Context) { return } - if _, err := models.AddTime(c.Doer, issue, int64(total.Seconds()), time.Now()); err != nil { + if _, err := issues_model.AddTime(c.Doer, issue, int64(total.Seconds()), time.Now()); err != nil { c.ServerError("AddTime", err) return } @@ -62,7 +62,7 @@ func DeleteTime(c *context.Context) { return } - t, err := models.GetTrackedTimeByID(c.ParamsInt64(":timeid")) + t, err := issues_model.GetTrackedTimeByID(c.ParamsInt64(":timeid")) if err != nil { if db.IsErrNotExist(err) { c.NotFound("time not found", err) @@ -78,7 +78,7 @@ func DeleteTime(c *context.Context) { return } - if err = models.DeleteTime(t); err != nil { + if err = issues_model.DeleteTime(t); err != nil { c.ServerError("DeleteTime", err) return } diff --git a/routers/web/repo/issue_watch.go b/routers/web/repo/issue_watch.go index 53fec11cdc..5210ecf777 100644 --- a/routers/web/repo/issue_watch.go +++ b/routers/web/repo/issue_watch.go @@ -8,7 +8,7 @@ import ( "net/http" "strconv" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" ) @@ -48,7 +48,7 @@ func IssueWatch(ctx *context.Context) { return } - if err := models.CreateOrUpdateIssueWatch(ctx.Doer.ID, issue.ID, watch); err != nil { + if err := issues_model.CreateOrUpdateIssueWatch(ctx.Doer.ID, issue.ID, watch); err != nil { ctx.ServerError("CreateOrUpdateIssueWatch", err) return } diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index c1805944db..51c891dbf0 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -10,7 +10,7 @@ import ( "net/url" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" project_model "code.gitea.io/gitea/models/project" "code.gitea.io/gitea/models/unit" @@ -296,13 +296,13 @@ func ViewProject(ctx *context.Context) { boards[0].Title = ctx.Tr("repo.projects.type.uncategorized") } - issuesMap, err := models.LoadIssuesFromBoardList(boards) + issuesMap, err := issues_model.LoadIssuesFromBoardList(boards) if err != nil { ctx.ServerError("LoadIssuesOfBoards", err) return } - linkedPrsMap := make(map[int64][]*models.Issue) + linkedPrsMap := make(map[int64][]*issues_model.Issue) for _, issuesList := range issuesMap { for _, issue := range issuesList { var referencedIds []int64 @@ -313,7 +313,7 @@ func ViewProject(ctx *context.Context) { } if len(referencedIds) > 0 { - if linkedPrs, err := models.Issues(&models.IssuesOptions{ + if linkedPrs, err := issues_model.Issues(&issues_model.IssuesOptions{ IssueIDs: referencedIds, IsPull: util.OptionalBoolTrue, }); err == nil { @@ -358,7 +358,7 @@ func UpdateIssueProject(ctx *context.Context) { continue } - if err := models.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { + if err := issues_model.ChangeProjectAssign(issue, ctx.Doer, projectID); err != nil { ctx.ServerError("ChangeProjectAssign", err) return } @@ -622,9 +622,9 @@ func MoveIssues(ctx *context.Context) { issueIDs = append(issueIDs, issue.IssueID) sortedIssueIDs[issue.Sorting] = issue.IssueID } - movedIssues, err := models.GetIssuesByIDs(ctx, issueIDs) + movedIssues, err := issues_model.GetIssuesByIDs(ctx, issueIDs) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound("IssueNotExisting", nil) } else { ctx.ServerError("GetIssueByID", err) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index c1a59ca8c0..6e8f575ad5 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/models" "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/models/organization" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" @@ -256,10 +257,10 @@ func ForkPost(ctx *context.Context) { ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name)) } -func checkPullInfo(ctx *context.Context) *models.Issue { - issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) +func checkPullInfo(ctx *context.Context) *issues_model.Issue { + issue, err := issues_model.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { ctx.NotFound("GetIssueByIndex", err) } else { ctx.ServerError("GetIssueByIndex", err) @@ -294,7 +295,7 @@ func checkPullInfo(ctx *context.Context) *models.Issue { if ctx.IsSigned { // Update issue-user. - if err = issue.ReadBy(ctx, ctx.Doer.ID); err != nil { + if err = models.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) return nil } @@ -303,7 +304,7 @@ func checkPullInfo(ctx *context.Context) *models.Issue { return issue } -func setMergeTarget(ctx *context.Context, pull *models.PullRequest) { +func setMergeTarget(ctx *context.Context, pull *issues_model.PullRequest) { if ctx.Repo.Owner.Name == pull.MustHeadUserName() { ctx.Data["HeadTarget"] = pull.HeadBranch } else if pull.HeadRepo == nil { @@ -317,7 +318,7 @@ func setMergeTarget(ctx *context.Context, pull *models.PullRequest) { } // PrepareMergedViewPullInfo show meta information for a merged pull request view page -func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) *git.CompareInfo { +func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { pull := issue.PullRequest setMergeTarget(ctx, pull) @@ -395,7 +396,7 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *models.Issue) *git.C } // PrepareViewPullInfo show meta information for a pull request preview page -func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.CompareInfo { +func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo { ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes repo := ctx.Repo.Repository @@ -482,14 +483,14 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare } defer headGitRepo.Close() - if pull.Flow == models.PullRequestFlowGithub { + if pull.Flow == issues_model.PullRequestFlowGithub { headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch) } else { headBranchExist = git.IsReferenceExist(ctx, baseGitRepo.Path, pull.GetGitRefName()) } if headBranchExist { - if pull.Flow != models.PullRequestFlowGithub { + if pull.Flow != issues_model.PullRequestFlowGithub { headBranchSha, err = baseGitRepo.GetRefCommitID(pull.GetGitRefName()) } else { headBranchSha, err = headGitRepo.GetBranchCommitID(pull.HeadBranch) @@ -752,7 +753,7 @@ func ViewPullFiles(ctx *context.Context) { } if ctx.IsSigned && ctx.Doer != nil { - if ctx.Data["CanMarkConversation"], err = models.CanMarkConversation(issue, ctx.Doer); err != nil { + if ctx.Data["CanMarkConversation"], err = issues_model.CanMarkConversation(issue, ctx.Doer); err != nil { ctx.ServerError("CanMarkConversation", err) return } @@ -770,15 +771,15 @@ func ViewPullFiles(ctx *context.Context) { return } - currentReview, err := models.GetCurrentReview(ctx, ctx.Doer, issue) - if err != nil && !models.IsErrReviewNotExist(err) { + currentReview, err := issues_model.GetCurrentReview(ctx, ctx.Doer, issue) + if err != nil && !issues_model.IsErrReviewNotExist(err) { ctx.ServerError("GetCurrentReview", err) return } numPendingCodeComments := int64(0) if currentReview != nil { - numPendingCodeComments, err = models.CountComments(&models.FindCommentsOptions{ - Type: models.CommentTypeCode, + numPendingCodeComments, err = issues_model.CountComments(&issues_model.FindCommentsOptions{ + Type: issues_model.CommentTypeCode, ReviewID: currentReview.ID, IssueID: issue.ID, }) @@ -1062,7 +1063,7 @@ func MergePullRequest(ctx *context.Context) { if form.DeleteBranchAfterMerge { // Don't cleanup when other pr use this branch as head branch - exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) if err != nil { ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return @@ -1109,9 +1110,9 @@ func CancelAutoMergePullRequest(ctx *context.Context) { ctx.Redirect(fmt.Sprintf("%s/pulls/%d", ctx.Repo.RepoLink, issue.Index)) } -func stopTimerIfAvailable(user *user_model.User, issue *models.Issue) error { - if models.StopwatchExists(user.ID, issue.ID) { - if err := models.CreateOrStopIssueStopwatch(user, issue); err != nil { +func stopTimerIfAvailable(user *user_model.User, issue *issues_model.Issue) error { + if issues_model.StopwatchExists(user.ID, issue.ID) { + if err := issues_model.CreateOrStopIssueStopwatch(user, issue); err != nil { return err } } @@ -1190,7 +1191,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { return } - pullIssue := &models.Issue{ + pullIssue := &issues_model.Issue{ RepoID: repo.ID, Repo: repo, Title: form.Title, @@ -1200,7 +1201,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { IsPull: true, Content: form.Content, } - pullRequest := &models.PullRequest{ + pullRequest := &issues_model.PullRequest{ HeadRepoID: ci.HeadRepo.ID, BaseRepoID: repo.ID, HeadBranch: ci.HeadBranch, @@ -1208,14 +1209,14 @@ func CompareAndPullRequestPost(ctx *context.Context) { HeadRepo: ci.HeadRepo, BaseRepo: repo, MergeBase: ci.CompareInfo.MergeBase, - Type: models.PullRequestGitea, + Type: issues_model.PullRequestGitea, AllowMaintainerEdit: form.AllowMaintainerEdit, } // FIXME: check error in the case two people send pull request at almost same time, give nice error prompt // instead of 500. if err := pull_service.NewPullRequest(ctx, repo, pullIssue, labelIDs, attachments, pullRequest, assigneeIDs); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) return } else if git.IsErrPushRejected(err) { @@ -1262,7 +1263,7 @@ func CleanUpPullRequest(ctx *context.Context) { } // Don't cleanup when there are other PR's that use this branch as head branch. - exist, err := models.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) if err != nil { ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return @@ -1356,7 +1357,7 @@ func CleanUpPullRequest(ctx *context.Context) { deleteBranch(ctx, pr, gitRepo) } -func deleteBranch(ctx *context.Context, pr *models.PullRequest, gitRepo *git.Repository) { +func deleteBranch(ctx *context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository) { fullBranchName := pr.HeadRepo.Owner.Name + "/" + pr.HeadBranch if err := repo_service.DeleteBranch(ctx.Doer, pr.HeadRepo, gitRepo, pr.HeadBranch); err != nil { switch { @@ -1373,7 +1374,7 @@ func deleteBranch(ctx *context.Context, pr *models.PullRequest, gitRepo *git.Rep return } - if err := models.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.IssueID, pr.HeadBranch); err != nil { + if err := issues_model.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.IssueID, pr.HeadBranch); err != nil { // Do not fail here as branch has already been deleted log.Error("DeleteBranch: %v", err) } @@ -1393,9 +1394,9 @@ func DownloadPullPatch(ctx *context.Context) { // DownloadPullDiffOrPatch render a pull's raw diff or patch func DownloadPullDiffOrPatch(ctx *context.Context, patch bool) { - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.ServerError("GetPullRequestByIndex", err) @@ -1435,8 +1436,8 @@ func UpdatePullRequestTarget(ctx *context.Context) { } if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.Doer, targetBranch); err != nil { - if models.IsErrPullRequestAlreadyExists(err) { - err := err.(models.ErrPullRequestAlreadyExists) + if issues_model.IsErrPullRequestAlreadyExists(err) { + err := err.(issues_model.ErrPullRequestAlreadyExists) RepoRelPath := ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name errorMessage := ctx.Tr("repo.pulls.has_pull_request", html.EscapeString(ctx.Repo.RepoLink+"/pulls/"+strconv.FormatInt(err.IssueID, 10)), html.EscapeString(RepoRelPath), err.IssueID) // FIXME: Creates url insidde locale string @@ -1446,7 +1447,7 @@ func UpdatePullRequestTarget(ctx *context.Context) { "error": err.Error(), "user_error": errorMessage, }) - } else if models.IsErrIssueIsClosed(err) { + } else if issues_model.IsErrIssueIsClosed(err) { errorMessage := ctx.Tr("repo.pulls.is_closed") ctx.Flash.Error(errorMessage) @@ -1486,9 +1487,9 @@ func UpdatePullRequestTarget(ctx *context.Context) { func SetAllowEdits(ctx *context.Context) { form := web.GetForm(ctx).(*forms.UpdateAllowEditsForm) - pr, err := models.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) + pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { ctx.ServerError("GetPullRequestByIndex", err) diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go index e051290200..cc7ae9bbfa 100644 --- a/routers/web/repo/pull_review.go +++ b/routers/web/repo/pull_review.go @@ -8,7 +8,7 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" pull_model "code.gitea.io/gitea/models/pull" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -31,8 +31,8 @@ func RenderNewCodeCommentForm(ctx *context.Context) { if !issue.IsPull { return } - currentReview, err := models.GetCurrentReview(ctx, ctx.Doer, issue) - if err != nil && !models.IsErrReviewNotExist(err) { + currentReview, err := issues_model.GetCurrentReview(ctx, ctx.Doer, issue) + if err != nil && !issues_model.IsErrReviewNotExist(err) { ctx.ServerError("GetCurrentReview", err) return } @@ -107,7 +107,7 @@ func UpdateResolveConversation(ctx *context.Context) { action := ctx.FormString("action") commentID := ctx.FormInt64("comment_id") - comment, err := models.GetCommentByID(ctx, commentID) + comment, err := issues_model.GetCommentByID(ctx, commentID) if err != nil { ctx.ServerError("GetIssueByID", err) return @@ -119,7 +119,7 @@ func UpdateResolveConversation(ctx *context.Context) { } var permResult bool - if permResult, err = models.CanMarkConversation(comment.Issue, ctx.Doer); err != nil { + if permResult, err = issues_model.CanMarkConversation(comment.Issue, ctx.Doer); err != nil { ctx.ServerError("CanMarkConversation", err) return } @@ -134,7 +134,7 @@ func UpdateResolveConversation(ctx *context.Context) { } if action == "Resolve" || action == "UnResolve" { - err = models.MarkConversation(comment, ctx.Doer, action == "Resolve") + err = issues_model.MarkConversation(comment, ctx.Doer, action == "Resolve") if err != nil { ctx.ServerError("MarkConversation", err) return @@ -153,8 +153,8 @@ func UpdateResolveConversation(ctx *context.Context) { }) } -func renderConversation(ctx *context.Context, comment *models.Comment) { - comments, err := models.FetchCodeCommentsByLine(ctx, comment.Issue, ctx.Doer, comment.TreePath, comment.Line) +func renderConversation(ctx *context.Context, comment *issues_model.Comment) { + comments, err := issues_model.FetchCodeCommentsByLine(ctx, comment.Issue, ctx.Doer, comment.TreePath, comment.Line) if err != nil { ctx.ServerError("FetchCodeCommentsByLine", err) return @@ -194,15 +194,15 @@ func SubmitReview(ctx *context.Context) { reviewType := form.ReviewType() switch reviewType { - case models.ReviewTypeUnknown: + case issues_model.ReviewTypeUnknown: ctx.ServerError("ReviewType", fmt.Errorf("unknown ReviewType: %s", form.Type)) return // can not approve/reject your own PR - case models.ReviewTypeApprove, models.ReviewTypeReject: + case issues_model.ReviewTypeApprove, issues_model.ReviewTypeReject: if issue.IsPoster(ctx.Doer.ID) { var translated string - if reviewType == models.ReviewTypeApprove { + if reviewType == issues_model.ReviewTypeApprove { translated = ctx.Tr("repo.issues.review.self.approval") } else { translated = ctx.Tr("repo.issues.review.self.rejection") @@ -221,7 +221,7 @@ func SubmitReview(ctx *context.Context) { _, comm, err := pull_service.SubmitReview(ctx, ctx.Doer, ctx.Repo.GitRepo, issue, reviewType, form.Content, form.CommitID, attachments) if err != nil { - if models.IsContentEmptyErr(err) { + if issues_model.IsContentEmptyErr(err) { ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty")) ctx.Redirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index)) } else { diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 9b4fc652f1..7fe80a2a4b 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -385,17 +385,17 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { viewType = ctx.FormString("type") switch viewType { case "assigned": - filterMode = models.FilterModeAssign + filterMode = issues_model.FilterModeAssign case "created_by": - filterMode = models.FilterModeCreate + filterMode = issues_model.FilterModeCreate case "mentioned": - filterMode = models.FilterModeMention + filterMode = issues_model.FilterModeMention case "review_requested": - filterMode = models.FilterModeReviewRequested + filterMode = issues_model.FilterModeReviewRequested case "your_repositories": fallthrough default: - filterMode = models.FilterModeYourRepositories + filterMode = issues_model.FilterModeYourRepositories viewType = "your_repositories" } @@ -416,7 +416,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { } isPullList := unitType == unit.TypePullRequests - opts := &models.IssuesOptions{ + opts := &issues_model.IssuesOptions{ IsPull: util.OptionalBoolOf(isPullList), SortType: sortType, IsArchived: util.OptionalBoolFalse, @@ -450,15 +450,15 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { } switch filterMode { - case models.FilterModeAll: - case models.FilterModeYourRepositories: - case models.FilterModeAssign: + case issues_model.FilterModeAll: + case issues_model.FilterModeYourRepositories: + case issues_model.FilterModeAssign: opts.AssigneeID = ctx.Doer.ID - case models.FilterModeCreate: + case issues_model.FilterModeCreate: opts.PosterID = ctx.Doer.ID - case models.FilterModeMention: + case issues_model.FilterModeMention: opts.MentionedID = ctx.Doer.ID - case models.FilterModeReviewRequested: + case issues_model.FilterModeReviewRequested: opts.ReviewRequestedID = ctx.Doer.ID } @@ -491,7 +491,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // USING NON-FINAL STATE OF opts FOR A QUERY. var issueCountByRepo map[int64]int64 if !forceEmpty { - issueCountByRepo, err = models.CountIssuesByRepo(opts) + issueCountByRepo, err = issues_model.CountIssuesByRepo(opts) if err != nil { ctx.ServerError("CountIssuesByRepo", err) return @@ -532,15 +532,15 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // Slice of Issues that will be displayed on the overview page // USING FINAL STATE OF opts FOR A QUERY. - var issues []*models.Issue + var issues []*issues_model.Issue if !forceEmpty { - issues, err = models.Issues(opts) + issues, err = issues_model.Issues(opts) if err != nil { ctx.ServerError("Issues", err) return } } else { - issues = []*models.Issue{} + issues = []*issues_model.Issue{} } // ---------------------------------- @@ -578,9 +578,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // ------------------------------- // Fill stats to post to ctx.Data. // ------------------------------- - var issueStats *models.IssueStats + var issueStats *issues_model.IssueStats if !forceEmpty { - statsOpts := models.UserIssueStatsOptions{ + statsOpts := issues_model.UserIssueStatsOptions{ UserID: ctx.Doer.ID, FilterMode: filterMode, IsPull: isPullList, @@ -592,13 +592,13 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { Team: team, } - issueStats, err = models.GetUserIssueStats(statsOpts) + issueStats, err = issues_model.GetUserIssueStats(statsOpts) if err != nil { ctx.ServerError("GetUserIssueStats Shown", err) return } } else { - issueStats = &models.IssueStats{} + issueStats = &issues_model.IssueStats{} } // Will be posted to ctx.Data. @@ -623,7 +623,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { ctx.Data["Issues"] = issues - approvalCounts, err := models.IssueList(issues).GetApprovalCounts(ctx) + approvalCounts, err := issues_model.IssueList(issues).GetApprovalCounts(ctx) if err != nil { ctx.ServerError("ApprovalCounts", err) return @@ -633,11 +633,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { if !ok || len(counts) == 0 { return 0 } - reviewTyp := models.ReviewTypeApprove + reviewTyp := issues_model.ReviewTypeApprove if typ == "reject" { - reviewTyp = models.ReviewTypeReject + reviewTyp = issues_model.ReviewTypeReject } else if typ == "waiting" { - reviewTyp = models.ReviewTypeRequest + reviewTyp = issues_model.ReviewTypeRequest } for _, count := range counts { if count.Type == reviewTyp { @@ -708,12 +708,12 @@ func getRepoIDs(reposQuery string) []int64 { return repoIDs } -func issueIDsFromSearch(ctx *context.Context, ctxUser *user_model.User, keyword string, opts *models.IssuesOptions) ([]int64, error) { +func issueIDsFromSearch(ctx *context.Context, ctxUser *user_model.User, keyword string, opts *issues_model.IssuesOptions) ([]int64, error) { if len(keyword) == 0 { return []int64{}, nil } - searchRepoIDs, err := models.GetRepoIDsForIssuesOptions(opts, ctxUser) + searchRepoIDs, err := issues_model.GetRepoIDsForIssuesOptions(opts, ctxUser) if err != nil { return nil, fmt.Errorf("GetRepoIDsForIssuesOptions: %v", err) } diff --git a/routers/web/user/stop_watch.go b/routers/web/user/stop_watch.go index 4b16c9aeda..f40d850fc1 100644 --- a/routers/web/user/stop_watch.go +++ b/routers/web/user/stop_watch.go @@ -7,15 +7,15 @@ package user import ( "net/http" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" ) // GetStopwatches get all stopwatches func GetStopwatches(ctx *context.Context) { - sws, err := models.GetUserStopwatches(ctx.Doer.ID, db.ListOptions{ + sws, err := issues_model.GetUserStopwatches(ctx.Doer.ID, db.ListOptions{ Page: ctx.FormInt("page"), PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), }) @@ -24,7 +24,7 @@ func GetStopwatches(ctx *context.Context) { return } - count, err := models.CountUserStopwatches(ctx.Doer.ID) + count, err := issues_model.CountUserStopwatches(ctx.Doer.ID) if err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return diff --git a/services/agit/agit.go b/services/agit/agit.go index cc520dbc76..7666093c51 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -10,7 +10,8 @@ import ( "os" "strings" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -97,9 +98,9 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva headBranch = curentTopicBranch } - pr, err := models.GetUnmergedPullRequest(repo.ID, repo.ID, headBranch, baseBranchName, models.PullRequestFlowAGit) + pr, err := issues_model.GetUnmergedPullRequest(repo.ID, repo.ID, headBranch, baseBranchName, issues_model.PullRequestFlowAGit) if err != nil { - if !models.IsErrPullRequestNotExist(err) { + if !issues_model.IsErrPullRequestNotExist(err) { log.Error("Failed to get unmerged agit flow pull request in repository: %s/%s Error: %v", ownerName, repoName, err) ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ "Err": fmt.Sprintf("Failed to get unmerged agit flow pull request in repository: %s/%s Error: %v", ownerName, repoName, err), @@ -134,7 +135,7 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva return nil } - prIssue := &models.Issue{ + prIssue := &issues_model.Issue{ RepoID: repo.ID, Title: title, PosterID: pusher.ID, @@ -143,7 +144,7 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva Content: description, } - pr := &models.PullRequest{ + pr := &issues_model.PullRequest{ HeadRepoID: repo.ID, BaseRepoID: repo.ID, HeadBranch: headBranch, @@ -152,12 +153,12 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva HeadRepo: repo, BaseRepo: repo, MergeBase: "", - Type: models.PullRequestGitea, - Flow: models.PullRequestFlowAGit, + Type: issues_model.PullRequestGitea, + Flow: issues_model.PullRequestFlowAGit, } if err := pull_service.NewPullRequest(ctx, repo, prIssue, []int64{}, []string{}, pr, []int64{}); err != nil { - if models.IsErrUserDoesNotHaveAccessToRepo(err) { + if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) return nil } @@ -249,7 +250,7 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva }) return nil } - comment, err := models.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i]) + comment, err := issues_model.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i]) if err == nil && comment != nil { notification.NotifyPullRequestPushCommits(pusher, pr, comment) } @@ -270,7 +271,7 @@ func ProcReceive(ctx *context.PrivateContext, opts *private.HookOptions) []priva // UserNameChanged handle user name change for agit flow pull func UserNameChanged(user *user_model.User, newName string) error { - pulls, err := models.GetAllUnmergedAgitPullRequestByPoster(user.ID) + pulls, err := issues_model.GetAllUnmergedAgitPullRequestByPoster(user.ID) if err != nil { return err } diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go index 0f74cd4b2a..edfd0f6cad 100644 --- a/services/asymkey/sign.go +++ b/services/asymkey/sign.go @@ -9,11 +9,11 @@ import ( "fmt" "strings" - "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + 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" @@ -271,7 +271,7 @@ Loop: } // SignMerge determines if we should sign a PR merge commit to the base repository -func SignMerge(ctx context.Context, pr *models.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) { +func SignMerge(ctx context.Context, pr *issues_model.PullRequest, u *user_model.User, tmpBasePath, baseCommit, headCommit string) (bool, string, *git.Signature, error) { if err := pr.LoadBaseRepoCtx(ctx); err != nil { log.Error("Unable to get Base Repo for pull request") return false, "", nil, err @@ -318,7 +318,7 @@ Loop: if protectedBranch == nil { return false, "", nil, &ErrWontSign{approved} } - if models.GetGrantedApprovalsCount(ctx, protectedBranch, pr) < 1 { + if issues_model.GetGrantedApprovalsCount(ctx, protectedBranch, pr) < 1 { return false, "", nil, &ErrWontSign{approved} } case baseSigned: diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index 3c7346ab58..d0f83f4a93 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -11,8 +11,8 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" repo_model "code.gitea.io/gitea/models/repo" @@ -52,7 +52,7 @@ func handle(data ...queue.Data) []queue.Data { return nil } -func addToQueue(pr *models.PullRequest, sha string) { +func addToQueue(pr *issues_model.PullRequest, sha string) { if err := prAutoMergeQueue.PushFunc(fmt.Sprintf("%d_%s", pr.ID, sha), func() error { log.Trace("Adding pullID: %d to the pull requests patch checking queue with sha %s", pr.ID, sha) return nil @@ -62,7 +62,7 @@ func addToQueue(pr *models.PullRequest, sha string) { } // ScheduleAutoMerge if schedule is false and no error, pull can be merged directly -func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *models.PullRequest, style repo_model.MergeStyle, message string) (scheduled bool, err error) { +func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest, style repo_model.MergeStyle, message string) (scheduled bool, err error) { err = db.WithTx(func(ctx context.Context) error { lastCommitStatus, err := pull_service.GetPullRequestCommitStatusState(ctx, pull) if err != nil { @@ -79,27 +79,27 @@ func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *models. } scheduled = true - _, err = models.CreateAutoMergeComment(ctx, models.CommentTypePRScheduledToAutoMerge, pull, doer) + _, err = issues_model.CreateAutoMergeComment(ctx, issues_model.CommentTypePRScheduledToAutoMerge, pull, doer) return err }, ctx) return } // RemoveScheduledAutoMerge cancels a previously scheduled pull request -func RemoveScheduledAutoMerge(ctx context.Context, doer *user_model.User, pull *models.PullRequest) error { +func RemoveScheduledAutoMerge(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest) error { return db.WithTx(func(ctx context.Context) error { if err := pull_model.DeleteScheduledAutoMerge(ctx, pull.ID); err != nil { return err } - _, err := models.CreateAutoMergeComment(ctx, models.CommentTypePRUnScheduledToAutoMerge, pull, doer) + _, err := issues_model.CreateAutoMergeComment(ctx, issues_model.CommentTypePRUnScheduledToAutoMerge, pull, doer) return err }, ctx) } // MergeScheduledPullRequest merges a previously scheduled pull request when all checks succeeded func MergeScheduledPullRequest(ctx context.Context, sha string, repo *repo_model.Repository) error { - pulls, err := getPullRequestsByHeadSHA(ctx, sha, repo, func(pr *models.PullRequest) bool { + pulls, err := getPullRequestsByHeadSHA(ctx, sha, repo, func(pr *issues_model.PullRequest) bool { return !pr.HasMerged && pr.CanAutoMerge() }) if err != nil { @@ -113,7 +113,7 @@ func MergeScheduledPullRequest(ctx context.Context, sha string, repo *repo_model return nil } -func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*models.PullRequest) bool) (map[int64]*models.PullRequest, error) { +func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*issues_model.PullRequest) bool) (map[int64]*issues_model.PullRequest, error) { gitRepo, err := git.OpenRepository(ctx, repo.RepoPath()) if err != nil { return nil, err @@ -125,7 +125,7 @@ func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model. return nil, err } - pulls := make(map[int64]*models.PullRequest) + pulls := make(map[int64]*issues_model.PullRequest) for _, ref := range refs { // Each pull branch starts with refs/pull/ we then go from there to find the index of the pr and then @@ -145,10 +145,10 @@ func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model. continue } - p, err := models.GetPullRequestByIndex(ctx, repo.ID, prIndex) + p, err := issues_model.GetPullRequestByIndex(ctx, repo.ID, prIndex) if err != nil { // If there is no pull request for this branch, we don't try to merge it. - if models.IsErrPullRequestNotExist(err) { + if issues_model.IsErrPullRequestNotExist(err) { continue } return nil, err @@ -168,7 +168,7 @@ func handlePull(pullID int64, sha string) { fmt.Sprintf("Handle AutoMerge of pull[%d] with sha[%s]", pullID, sha)) defer finished() - pr, err := models.GetPullRequestByID(ctx, pullID) + pr, err := issues_model.GetPullRequestByID(ctx, pullID) if err != nil { log.Error("GetPullRequestByID[%d]: %v", pullID, err) return diff --git a/services/comments/comments.go b/services/comments/comments.go index b80fddf93f..c40631359b 100644 --- a/services/comments/comments.go +++ b/services/comments/comments.go @@ -5,9 +5,8 @@ package comments import ( - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/issues" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" @@ -15,9 +14,9 @@ import ( ) // CreateIssueComment creates a plain issue comment. -func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issue *models.Issue, content string, attachments []string) (*models.Comment, error) { - comment, err := models.CreateComment(&models.CreateCommentOptions{ - Type: models.CommentTypeComment, +func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content string, attachments []string) (*issues_model.Comment, error) { + comment, err := issues_model.CreateComment(&issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeComment, Doer: doer, Repo: repo, Issue: issue, @@ -28,7 +27,7 @@ func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issu return nil, err } - mentions, err := models.FindAndUpdateIssueMentions(db.DefaultContext, issue, doer, comment.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(db.DefaultContext, issue, doer, comment.Content) if err != nil { return nil, err } @@ -39,28 +38,28 @@ func CreateIssueComment(doer *user_model.User, repo *repo_model.Repository, issu } // UpdateComment updates information of comment. -func UpdateComment(c *models.Comment, doer *user_model.User, oldContent string) error { +func UpdateComment(c *issues_model.Comment, doer *user_model.User, oldContent string) error { needsContentHistory := c.Content != oldContent && - (c.Type == models.CommentTypeComment || c.Type == models.CommentTypeReview || c.Type == models.CommentTypeCode) + (c.Type == issues_model.CommentTypeComment || c.Type == issues_model.CommentTypeReview || c.Type == issues_model.CommentTypeCode) if needsContentHistory { - hasContentHistory, err := issues.HasIssueContentHistory(db.DefaultContext, c.IssueID, c.ID) + hasContentHistory, err := issues_model.HasIssueContentHistory(db.DefaultContext, c.IssueID, c.ID) if err != nil { return err } if !hasContentHistory { - if err = issues.SaveIssueContentHistory(db.DefaultContext, c.PosterID, c.IssueID, c.ID, + if err = issues_model.SaveIssueContentHistory(db.DefaultContext, c.PosterID, c.IssueID, c.ID, c.CreatedUnix, oldContent, true); err != nil { return err } } } - if err := models.UpdateComment(c, doer); err != nil { + if err := issues_model.UpdateComment(c, doer); err != nil { return err } if needsContentHistory { - err := issues.SaveIssueContentHistory(db.DefaultContext, doer.ID, c.IssueID, c.ID, timeutil.TimeStampNow(), c.Content, false) + err := issues_model.SaveIssueContentHistory(db.DefaultContext, doer.ID, c.IssueID, c.ID, timeutil.TimeStampNow(), c.Content, false) if err != nil { return err } @@ -72,8 +71,17 @@ func UpdateComment(c *models.Comment, doer *user_model.User, oldContent string) } // DeleteComment deletes the comment -func DeleteComment(doer *user_model.User, comment *models.Comment) error { - if err := models.DeleteComment(comment); err != nil { +func DeleteComment(doer *user_model.User, comment *issues_model.Comment) error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + if err := issues_model.DeleteComment(ctx, comment); err != nil { + return err + } + if err := committer.Commit(); err != nil { return err } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 23ac1abe3c..c9327bbd9b 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -11,6 +11,7 @@ import ( "strings" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" project_model "code.gitea.io/gitea/models/project" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" @@ -636,18 +637,18 @@ func (f *SubmitReviewForm) Validate(req *http.Request, errs binding.Errors) bind } // ReviewType will return the corresponding ReviewType for type -func (f SubmitReviewForm) ReviewType() models.ReviewType { +func (f SubmitReviewForm) ReviewType() issues_model.ReviewType { switch f.Type { case "approve": - return models.ReviewTypeApprove + return issues_model.ReviewTypeApprove case "comment": - return models.ReviewTypeComment + return issues_model.ReviewTypeComment case "reject": - return models.ReviewTypeReject + return issues_model.ReviewTypeReject case "": - return models.ReviewTypeComment // default to comment when doing quick-submit (Ctrl+Enter) on the review form + return issues_model.ReviewTypeComment // default to comment when doing quick-submit (Ctrl+Enter) on the review form default: - return models.ReviewTypeUnknown + return issues_model.ReviewTypeUnknown } } @@ -655,7 +656,7 @@ func (f SubmitReviewForm) ReviewType() models.ReviewType { func (f SubmitReviewForm) HasEmptyContent() bool { reviewType := f.ReviewType() - return (reviewType == models.ReviewTypeComment || reviewType == models.ReviewTypeReject) && + return (reviewType == issues_model.ReviewTypeComment || reviewType == issues_model.ReviewTypeReject) && len(strings.TrimSpace(f.Content)) == 0 } diff --git a/services/forms/user_form_hidden_comments.go b/services/forms/user_form_hidden_comments.go index e0c26e8ddf..35c1a6dd2a 100644 --- a/services/forms/user_form_hidden_comments.go +++ b/services/forms/user_form_hidden_comments.go @@ -7,69 +7,69 @@ package forms import ( "math/big" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" ) -type hiddenCommentTypeGroupsType map[string][]models.CommentType +type hiddenCommentTypeGroupsType map[string][]issues_model.CommentType // hiddenCommentTypeGroups maps the group names to comment types, these group names comes from the Web UI (appearance.tmpl) var hiddenCommentTypeGroups = hiddenCommentTypeGroupsType{ "reference": { - /*3*/ models.CommentTypeIssueRef, - /*4*/ models.CommentTypeCommitRef, - /*5*/ models.CommentTypeCommentRef, - /*6*/ models.CommentTypePullRef, + /*3*/ issues_model.CommentTypeIssueRef, + /*4*/ issues_model.CommentTypeCommitRef, + /*5*/ issues_model.CommentTypeCommentRef, + /*6*/ issues_model.CommentTypePullRef, }, "label": { - /*7*/ models.CommentTypeLabel, + /*7*/ issues_model.CommentTypeLabel, }, "milestone": { - /*8*/ models.CommentTypeMilestone, + /*8*/ issues_model.CommentTypeMilestone, }, "assignee": { - /*9*/ models.CommentTypeAssignees, + /*9*/ issues_model.CommentTypeAssignees, }, "title": { - /*10*/ models.CommentTypeChangeTitle, + /*10*/ issues_model.CommentTypeChangeTitle, }, "branch": { - /*11*/ models.CommentTypeDeleteBranch, - /*25*/ models.CommentTypeChangeTargetBranch, + /*11*/ issues_model.CommentTypeDeleteBranch, + /*25*/ issues_model.CommentTypeChangeTargetBranch, }, "time_tracking": { - /*12*/ models.CommentTypeStartTracking, - /*13*/ models.CommentTypeStopTracking, - /*14*/ models.CommentTypeAddTimeManual, - /*15*/ models.CommentTypeCancelTracking, - /*26*/ models.CommentTypeDeleteTimeManual, + /*12*/ issues_model.CommentTypeStartTracking, + /*13*/ issues_model.CommentTypeStopTracking, + /*14*/ issues_model.CommentTypeAddTimeManual, + /*15*/ issues_model.CommentTypeCancelTracking, + /*26*/ issues_model.CommentTypeDeleteTimeManual, }, "deadline": { - /*16*/ models.CommentTypeAddedDeadline, - /*17*/ models.CommentTypeModifiedDeadline, - /*18*/ models.CommentTypeRemovedDeadline, + /*16*/ issues_model.CommentTypeAddedDeadline, + /*17*/ issues_model.CommentTypeModifiedDeadline, + /*18*/ issues_model.CommentTypeRemovedDeadline, }, "dependency": { - /*19*/ models.CommentTypeAddDependency, - /*20*/ models.CommentTypeRemoveDependency, + /*19*/ issues_model.CommentTypeAddDependency, + /*20*/ issues_model.CommentTypeRemoveDependency, }, "lock": { - /*23*/ models.CommentTypeLock, - /*24*/ models.CommentTypeUnlock, + /*23*/ issues_model.CommentTypeLock, + /*24*/ issues_model.CommentTypeUnlock, }, "review_request": { - /*27*/ models.CommentTypeReviewRequest, + /*27*/ issues_model.CommentTypeReviewRequest, }, "pull_request_push": { - /*29*/ models.CommentTypePullRequestPush, + /*29*/ issues_model.CommentTypePullRequestPush, }, "project": { - /*30*/ models.CommentTypeProject, - /*31*/ models.CommentTypeProjectBoard, + /*30*/ issues_model.CommentTypeProject, + /*31*/ issues_model.CommentTypeProjectBoard, }, "issue_ref": { - /*33*/ models.CommentTypeChangeIssueRef, + /*33*/ issues_model.CommentTypeChangeIssueRef, }, } diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index e56c2de8fa..97daadbc67 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -20,9 +20,9 @@ import ( "strings" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" pull_model "code.gitea.io/gitea/models/pull" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/analyze" @@ -82,7 +82,7 @@ type DiffLine struct { Match int Type DiffLineType Content string - Comments []*models.Comment + Comments []*issues_model.Comment SectionInfo *DiffLineSectionInfo } @@ -704,8 +704,8 @@ type Diff struct { } // LoadComments loads comments into each line -func (diff *Diff) LoadComments(ctx context.Context, issue *models.Issue, currentUser *user_model.User) error { - allComments, err := models.FetchCodeComments(ctx, issue, currentUser) +func (diff *Diff) LoadComments(ctx context.Context, issue *issues_model.Issue, currentUser *user_model.User) error { + allComments, err := issues_model.FetchCodeComments(ctx, issue, currentUser) if err != nil { return err } @@ -1520,7 +1520,7 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff // SyncAndGetUserSpecificDiff is like GetDiff, except that user specific data such as which files the given user has already viewed on the given PR will also be set // Additionally, the database asynchronously is updated if files have changed since the last review -func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *models.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) { +func SyncAndGetUserSpecificDiff(ctx context.Context, userID int64, pull *issues_model.PullRequest, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) { diff, err := GetDiff(gitRepo, opts, files...) if err != nil { return nil, err @@ -1583,7 +1583,7 @@ outer: } // CommentAsDiff returns c.Patch as *Diff -func CommentAsDiff(c *models.Comment) (*Diff, error) { +func CommentAsDiff(c *issues_model.Comment) (*Diff, error) { diff, err := ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(c.Patch), "") if err != nil { @@ -1601,7 +1601,7 @@ func CommentAsDiff(c *models.Comment) (*Diff, error) { } // CommentMustAsDiff executes AsDiff and logs the error instead of returning -func CommentMustAsDiff(c *models.Comment) *Diff { +func CommentMustAsDiff(c *issues_model.Comment) *Diff { if c == nil { return nil } diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index 3457785e5d..caca0e91d8 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -12,8 +12,8 @@ import ( "strings" "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -669,7 +669,7 @@ func setupDefaultDiff() *Diff { func TestDiff_LoadComments(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) diff := setupDefaultDiff() assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user)) @@ -678,15 +678,15 @@ func TestDiff_LoadComments(t *testing.T) { func TestDiffLine_CanComment(t *testing.T) { assert.False(t, (&DiffLine{Type: DiffLineSection}).CanComment()) - assert.False(t, (&DiffLine{Type: DiffLineAdd, Comments: []*models.Comment{{Content: "bla"}}}).CanComment()) + assert.False(t, (&DiffLine{Type: DiffLineAdd, Comments: []*issues_model.Comment{{Content: "bla"}}}).CanComment()) assert.True(t, (&DiffLine{Type: DiffLineAdd}).CanComment()) assert.True(t, (&DiffLine{Type: DiffLineDel}).CanComment()) assert.True(t, (&DiffLine{Type: DiffLinePlain}).CanComment()) } func TestDiffLine_GetCommentSide(t *testing.T) { - assert.Equal(t, "previous", (&DiffLine{Comments: []*models.Comment{{Line: -3}}}).GetCommentSide()) - assert.Equal(t, "proposed", (&DiffLine{Comments: []*models.Comment{{Line: 3}}}).GetCommentSide()) + assert.Equal(t, "previous", (&DiffLine{Comments: []*issues_model.Comment{{Line: -3}}}).GetCommentSide()) + assert.Equal(t, "proposed", (&DiffLine{Comments: []*issues_model.Comment{{Line: 3}}}).GetCommentSide()) } func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) { diff --git a/services/gitdiff/main_test.go b/services/gitdiff/main_test.go index d4d9364ebf..17d0da6276 100644 --- a/services/gitdiff/main_test.go +++ b/services/gitdiff/main_test.go @@ -8,6 +8,7 @@ import ( "path/filepath" "testing" + _ "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/unittest" ) diff --git a/services/issue/assignee.go b/services/issue/assignee.go index 8cad03351c..7c00f472dd 100644 --- a/services/issue/assignee.go +++ b/services/issue/assignee.go @@ -7,8 +7,8 @@ package issue import ( "context" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -19,7 +19,7 @@ import ( ) // DeleteNotPassedAssignee deletes all assignees who aren't passed via the "assignees" array -func DeleteNotPassedAssignee(issue *models.Issue, doer *user_model.User, assignees []*user_model.User) (err error) { +func DeleteNotPassedAssignee(issue *issues_model.Issue, doer *user_model.User, assignees []*user_model.User) (err error) { var found bool oriAssignes := make([]*user_model.User, len(issue.Assignees)) _ = copy(oriAssignes, issue.Assignees) @@ -45,8 +45,8 @@ func DeleteNotPassedAssignee(issue *models.Issue, doer *user_model.User, assigne } // ToggleAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it. -func ToggleAssignee(issue *models.Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *models.Comment, err error) { - removed, comment, err = models.ToggleIssueAssignee(issue, doer, assigneeID) +func ToggleAssignee(issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (removed bool, comment *issues_model.Comment, err error) { + removed, comment, err = issues_model.ToggleIssueAssignee(issue, doer, assigneeID) if err != nil { return } @@ -63,11 +63,11 @@ func ToggleAssignee(issue *models.Issue, doer *user_model.User, assigneeID int64 } // ReviewRequest add or remove a review request from a user for this PR, and make comment for it. -func ReviewRequest(issue *models.Issue, doer, reviewer *user_model.User, isAdd bool) (comment *models.Comment, err error) { +func ReviewRequest(issue *issues_model.Issue, doer, reviewer *user_model.User, isAdd bool) (comment *issues_model.Comment, err error) { if isAdd { - comment, err = models.AddReviewRequest(issue, reviewer, doer) + comment, err = issues_model.AddReviewRequest(issue, reviewer, doer) } else { - comment, err = models.RemoveReviewRequest(issue, reviewer, doer) + comment, err = issues_model.RemoveReviewRequest(issue, reviewer, doer) } if err != nil { @@ -82,16 +82,16 @@ func ReviewRequest(issue *models.Issue, doer, reviewer *user_model.User, isAdd b } // IsValidReviewRequest Check permission for ReviewRequest -func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, isAdd bool, issue *models.Issue, permDoer *access_model.Permission) error { +func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, isAdd bool, issue *issues_model.Issue, permDoer *access_model.Permission) error { if reviewer.IsOrganization() { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Organization can't be added as reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, } } if doer.IsOrganization() { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Organization can't be doer to add reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -111,8 +111,8 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, } } - lastreview, err := models.GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID) - if err != nil && !models.IsErrReviewNotExist(err) { + lastreview, err := issues_model.GetReviewByIssueIDAndUserID(ctx, issue.ID, reviewer.ID) + if err != nil && !issues_model.IsErrReviewNotExist(err) { return err } @@ -120,25 +120,25 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, if isAdd { pemResult = permReviewer.CanAccessAny(perm.AccessModeRead, unit.TypePullRequests) if !pemResult { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Reviewer can't read", UserID: doer.ID, RepoID: issue.Repo.ID, } } - if doer.ID == issue.PosterID && issue.OriginalAuthorID == 0 && lastreview != nil && lastreview.Type != models.ReviewTypeRequest { + if doer.ID == issue.PosterID && issue.OriginalAuthorID == 0 && lastreview != nil && lastreview.Type != issues_model.ReviewTypeRequest { return nil } pemResult = permDoer.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests) if !pemResult { - pemResult, err = models.IsOfficialReviewer(ctx, issue, doer) + pemResult, err = issues_model.IsOfficialReviewer(ctx, issue, doer) if err != nil { return err } if !pemResult { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Doer can't choose reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -147,20 +147,20 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, } if reviewer.ID == issue.PosterID && issue.OriginalAuthorID == 0 { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "poster of pr can't be reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, } } } else { - if lastreview != nil && lastreview.Type == models.ReviewTypeRequest && lastreview.ReviewerID == doer.ID { + if lastreview != nil && lastreview.Type == issues_model.ReviewTypeRequest && lastreview.ReviewerID == doer.ID { return nil } pemResult = permDoer.IsAdmin() if !pemResult { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Doer is not admin", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -172,9 +172,9 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, } // IsValidTeamReviewRequest Check permission for ReviewRequest Team -func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, doer *user_model.User, isAdd bool, issue *models.Issue) error { +func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, doer *user_model.User, isAdd bool, issue *issues_model.Issue) error { if doer.IsOrganization() { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Organization can't be doer to add reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -192,7 +192,7 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, hasTeam := organization.HasTeamRepo(ctx, reviewer.OrgID, reviewer.ID, issue.RepoID) if !hasTeam { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Reviewing team can't read repo", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -202,13 +202,13 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, doerCanWrite := permission.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests) if !doerCanWrite { - official, err := models.IsOfficialReviewer(ctx, issue, doer) + official, err := issues_model.IsOfficialReviewer(ctx, issue, doer) if err != nil { log.Error("Unable to Check if IsOfficialReviewer for %-v in %-v#%d", doer, issue.Repo, issue.Index) return err } if !official { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Doer can't choose reviewer", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -216,7 +216,7 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, } } } else if !permission.IsAdmin() { - return models.ErrNotValidReviewRequest{ + return issues_model.ErrNotValidReviewRequest{ Reason: "Only admin users can remove team requests. Doer is not admin", UserID: doer.ID, RepoID: issue.Repo.ID, @@ -227,11 +227,11 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, } // TeamReviewRequest add or remove a review request from a team for this PR, and make comment for it. -func TeamReviewRequest(issue *models.Issue, doer *user_model.User, reviewer *organization.Team, isAdd bool) (comment *models.Comment, err error) { +func TeamReviewRequest(issue *issues_model.Issue, doer *user_model.User, reviewer *organization.Team, isAdd bool) (comment *issues_model.Comment, err error) { if isAdd { - comment, err = models.AddTeamReviewRequest(issue, reviewer, doer) + comment, err = issues_model.AddTeamReviewRequest(issue, reviewer, doer) } else { - comment, err = models.RemoveTeamReviewRequest(issue, reviewer, doer) + comment, err = issues_model.RemoveTeamReviewRequest(issue, reviewer, doer) } if err != nil { diff --git a/services/issue/assignee_test.go b/services/issue/assignee_test.go index ff4d7029eb..5c8b822499 100644 --- a/services/issue/assignee_test.go +++ b/services/issue/assignee_test.go @@ -7,8 +7,8 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -19,7 +19,7 @@ func TestDeleteNotPassedAssignee(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Fake issue with assignees - issue, err := models.GetIssueWithAttrsByID(1) + issue, err := issues_model.GetIssueWithAttrsByID(1) assert.NoError(t, err) assert.EqualValues(t, 1, len(issue.Assignees)) @@ -27,7 +27,7 @@ func TestDeleteNotPassedAssignee(t *testing.T) { assert.NoError(t, err) // Check if he got removed - isAssigned, err := models.IsUserAssignedToIssue(db.DefaultContext, issue, user1) + isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user1) assert.NoError(t, err) assert.True(t, isAssigned) diff --git a/services/issue/commit.go b/services/issue/commit.go index 5140eebed1..1053a81162 100644 --- a/services/issue/commit.go +++ b/services/issue/commit.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" @@ -76,22 +77,22 @@ func timeLogToAmount(str string) int64 { return a } -func issueAddTime(issue *models.Issue, doer *user_model.User, time time.Time, timeLog string) error { +func issueAddTime(issue *issues_model.Issue, doer *user_model.User, time time.Time, timeLog string) error { amount := timeLogToAmount(timeLog) if amount == 0 { return nil } - _, err := models.AddTime(doer, issue, amount, time) + _, err := issues_model.AddTime(doer, issue, amount, time) return err } // getIssueFromRef returns the issue referenced by a ref. Returns a nil *Issue // if the provided ref references a non-existent issue. -func getIssueFromRef(repo *repo_model.Repository, index int64) (*models.Issue, error) { - issue, err := models.GetIssueByIndex(repo.ID, index) +func getIssueFromRef(repo *repo_model.Repository, index int64) (*issues_model.Issue, error) { + issue, err := issues_model.GetIssueByIndex(repo.ID, index) if err != nil { - if models.IsErrIssueNotExist(err) { + if issues_model.IsErrIssueNotExist(err) { return nil, nil } return nil, err @@ -112,7 +113,7 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm refMarked := make(map[markKey]bool) var refRepo *repo_model.Repository - var refIssue *models.Issue + var refIssue *issues_model.Issue var err error for _, ref := range references.FindAllIssueReferences(c.Message) { @@ -153,7 +154,7 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm } message := fmt.Sprintf(`%s`, html.EscapeString(repo.Link()), html.EscapeString(url.PathEscape(c.Sha1)), html.EscapeString(strings.SplitN(c.Message, "\n", 2)[0])) - if err = models.CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil { + if err = issues_model.CreateRefComment(doer, refRepo, refIssue, message, c.Sha1); err != nil { return err } diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go index 37283a7890..ce3f913627 100644 --- a/services/issue/commit_test.go +++ b/services/issue/commit_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -50,16 +51,16 @@ func TestUpdateIssuesCommit(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo.Owner = user - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 1, } - issueBean := &models.Issue{RepoID: repo.ID, Index: 4} + issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4} unittest.AssertNotExistsBean(t, commentBean) - unittest.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") + unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") @@ -77,16 +78,16 @@ func TestUpdateIssuesCommit(t *testing.T) { }, } repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) - commentBean = &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean = &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 6, } - issueBean = &models.Issue{RepoID: repo.ID, Index: 1} + issueBean = &issues_model.Issue{RepoID: repo.ID, Index: 1} unittest.AssertNotExistsBean(t, commentBean) - unittest.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") + unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch")) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") @@ -103,16 +104,16 @@ func TestUpdateIssuesCommit(t *testing.T) { }, } repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) - commentBean = &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean = &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef3", PosterID: user.ID, IssueID: 6, } - issueBean = &models.Issue{RepoID: repo.ID, Index: 1} + issueBean = &issues_model.Issue{RepoID: repo.ID, Index: 1} unittest.AssertNotExistsBean(t, commentBean) - unittest.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") + unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, commentBean) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") @@ -136,9 +137,9 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) repo.Owner = user - issueBean := &models.Issue{RepoID: repo.ID, Index: 4} + issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4} - unittest.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") + unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1") assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch)) unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1") unittest.CheckConsistencyFor(t, &models.Action{}) @@ -161,14 +162,14 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) { } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 7, } - issueBean := &models.Issue{RepoID: repo.ID, Index: 2, ID: 7} + issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 2, ID: 7} unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") @@ -196,14 +197,14 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 1, } - issueBean := &models.Issue{RepoID: 1, Index: 1, ID: 1} + issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1} unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") @@ -231,14 +232,14 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) { } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository) - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef1", PosterID: user.ID, IssueID: 1, } - issueBean := &models.Issue{RepoID: 1, Index: 1, ID: 1} + issueBean := &issues_model.Issue{RepoID: 1, Index: 1, ID: 1} unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, issueBean, "is_closed=1") @@ -274,20 +275,20 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6}).(*repo_model.Repository) - commentBean := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef3", PosterID: user.ID, IssueID: 6, } - commentBean2 := &models.Comment{ - Type: models.CommentTypeCommitRef, + commentBean2 := &issues_model.Comment{ + Type: issues_model.CommentTypeCommitRef, CommitSHA: "abcdef4", PosterID: user.ID, IssueID: 6, } - issueBean := &models.Issue{RepoID: 3, Index: 1, ID: 6} + issueBean := &issues_model.Issue{RepoID: 3, Index: 1, ID: 6} unittest.AssertNotExistsBean(t, commentBean) unittest.AssertNotExistsBean(t, commentBean2) diff --git a/services/issue/content.go b/services/issue/content.go index a60878479b..6f493892f4 100644 --- a/services/issue/content.go +++ b/services/issue/content.go @@ -5,16 +5,16 @@ package issue import ( - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" ) // ChangeContent changes issue content, as the given user. -func ChangeContent(issue *models.Issue, doer *user_model.User, content string) (err error) { +func ChangeContent(issue *issues_model.Issue, doer *user_model.User, content string) (err error) { oldContent := issue.Content - if err := models.ChangeIssueContent(issue, doer, content); err != nil { + if err := issues_model.ChangeIssueContent(issue, doer, content); err != nil { return err } diff --git a/services/issue/issue.go b/services/issue/issue.go index 78a486727a..ded281e209 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -8,18 +8,22 @@ import ( "fmt" "code.gitea.io/gitea/models" + admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" + 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/git" "code.gitea.io/gitea/modules/notification" + "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util" ) // NewIssue creates new issue with labels for repository. -func NewIssue(repo *repo_model.Repository, issue *models.Issue, labelIDs []int64, uuids []string, assigneeIDs []int64) error { - if err := models.NewIssue(repo, issue, labelIDs, uuids); err != nil { +func NewIssue(repo *repo_model.Repository, issue *issues_model.Issue, labelIDs []int64, uuids []string, assigneeIDs []int64) error { + if err := issues_model.NewIssue(repo, issue, labelIDs, uuids); err != nil { return err } @@ -29,7 +33,7 @@ func NewIssue(repo *repo_model.Repository, issue *models.Issue, labelIDs []int64 } } - mentions, err := models.FindAndUpdateIssueMentions(db.DefaultContext, issue, issue.Poster, issue.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(db.DefaultContext, issue, issue.Poster, issue.Content) if err != nil { return err } @@ -46,11 +50,11 @@ func NewIssue(repo *repo_model.Repository, issue *models.Issue, labelIDs []int64 } // ChangeTitle changes the title of this issue, as the given user. -func ChangeTitle(issue *models.Issue, doer *user_model.User, title string) (err error) { +func ChangeTitle(issue *issues_model.Issue, doer *user_model.User, title string) (err error) { oldTitle := issue.Title issue.Title = title - if err = models.ChangeIssueTitle(issue, doer, oldTitle); err != nil { + if err = issues_model.ChangeIssueTitle(issue, doer, oldTitle); err != nil { return } @@ -60,11 +64,11 @@ func ChangeTitle(issue *models.Issue, doer *user_model.User, title string) (err } // ChangeIssueRef changes the branch of this issue, as the given user. -func ChangeIssueRef(issue *models.Issue, doer *user_model.User, ref string) error { +func ChangeIssueRef(issue *issues_model.Issue, doer *user_model.User, ref string) error { oldRef := issue.Ref issue.Ref = ref - if err := models.ChangeIssueRef(issue, doer, oldRef); err != nil { + if err := issues_model.ChangeIssueRef(issue, doer, oldRef); err != nil { return err } @@ -79,7 +83,7 @@ func ChangeIssueRef(issue *models.Issue, doer *user_model.User, ref string) erro // "assignees" (array): Logins for Users to assign to this issue. // Pass one or more user logins to replace the set of assignees on this Issue. // Send an empty array ([]) to clear all assignees from the Issue. -func UpdateAssignees(issue *models.Issue, oneAssignee string, multipleAssignees []string, doer *user_model.User) (err error) { +func UpdateAssignees(issue *issues_model.Issue, oneAssignee string, multipleAssignees []string, doer *user_model.User) (err error) { var allNewAssignees []*user_model.User // Keep the old assignee thingy for compatibility reasons @@ -129,9 +133,9 @@ func UpdateAssignees(issue *models.Issue, oneAssignee string, multipleAssignees } // DeleteIssue deletes an issue -func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *models.Issue) error { +func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue) error { // load issue before deleting it - if err := issue.LoadAttributes(); err != nil { + if err := issue.LoadAttributes(db.DefaultContext); err != nil { return err } if err := issue.LoadPullRequest(); err != nil { @@ -139,7 +143,7 @@ func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *models.I } // delete entries in database - if err := models.DeleteIssue(issue); err != nil { + if err := deleteIssue(issue); err != nil { return err } @@ -157,14 +161,14 @@ func DeleteIssue(doer *user_model.User, gitRepo *git.Repository, issue *models.I // AddAssigneeIfNotAssigned adds an assignee only if he isn't already assigned to the issue. // Also checks for access of assigned user -func AddAssigneeIfNotAssigned(issue *models.Issue, doer *user_model.User, assigneeID int64) (err error) { +func AddAssigneeIfNotAssigned(issue *issues_model.Issue, doer *user_model.User, assigneeID int64) (err error) { assignee, err := user_model.GetUserByID(assigneeID) if err != nil { return err } // Check if the user is already assigned - isAssigned, err := models.IsUserAssignedToIssue(db.DefaultContext, issue, assignee) + isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, assignee) if err != nil { return err } @@ -178,7 +182,7 @@ func AddAssigneeIfNotAssigned(issue *models.Issue, doer *user_model.User, assign return err } if !valid { - return models.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name} + return repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: issue.Repo.Name} } _, _, err = ToggleAssignee(issue, doer, assigneeID) @@ -191,7 +195,7 @@ func AddAssigneeIfNotAssigned(issue *models.Issue, doer *user_model.User, assign // GetRefEndNamesAndURLs retrieves the ref end names (e.g. refs/heads/branch-name -> branch-name) // and their respective URLs. -func GetRefEndNamesAndURLs(issues []*models.Issue, repoLink string) (map[int64]string, map[int64]string) { +func GetRefEndNamesAndURLs(issues []*issues_model.Issue, repoLink string) (map[int64]string, map[int64]string) { issueRefEndNames := make(map[int64]string, len(issues)) issueRefURLs := make(map[int64]string, len(issues)) for _, issue := range issues { @@ -202,3 +206,77 @@ func GetRefEndNamesAndURLs(issues []*models.Issue, repoLink string) (map[int64]s } return issueRefEndNames, issueRefURLs } + +// deleteIssue deletes the issue +func deleteIssue(issue *issues_model.Issue) error { + ctx, committer, err := db.TxContext() + if err != nil { + return err + } + defer committer.Close() + + e := db.GetEngine(ctx) + if _, err := e.ID(issue.ID).NoAutoCondition().Delete(issue); err != nil { + return err + } + + if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, issue.IsClosed); err != nil { + return err + } + + if err := models.DeleteIssueActions(ctx, issue.RepoID, issue.ID); err != nil { + return err + } + + // find attachments related to this issue and remove them + if err := issue.LoadAttributes(ctx); err != nil { + return err + } + + for i := range issue.Attachments { + admin_model.RemoveStorageWithNotice(ctx, storage.Attachments, "Delete issue attachment", issue.Attachments[i].RelativePath()) + } + + // delete all database data still assigned to this issue + if err := issues_model.DeleteInIssue(ctx, issue.ID, + &issues_model.ContentHistory{}, + &issues_model.Comment{}, + &issues_model.IssueLabel{}, + &issues_model.IssueDependency{}, + &issues_model.IssueAssignees{}, + &issues_model.IssueUser{}, + &models.Notification{}, + &issues_model.Reaction{}, + &issues_model.IssueWatch{}, + &issues_model.Stopwatch{}, + &issues_model.TrackedTime{}, + &project_model.ProjectIssue{}, + &repo_model.Attachment{}, + &issues_model.PullRequest{}, + ); err != nil { + return err + } + + // References to this issue in other issues + if _, err := db.DeleteByBean(ctx, &issues_model.Comment{ + RefIssueID: issue.ID, + }); err != nil { + return err + } + + // Delete dependencies for issues in other repositories + if _, err := db.DeleteByBean(ctx, &issues_model.IssueDependency{ + DependencyID: issue.ID, + }); err != nil { + return err + } + + // delete from dependent issues + if _, err := db.DeleteByBean(ctx, &issues_model.Comment{ + DependentIssueID: issue.ID, + }); err != nil { + return err + } + + return committer.Commit() +} diff --git a/services/issue/issue_test.go b/services/issue/issue_test.go index caae773616..20f3a3296c 100644 --- a/services/issue/issue_test.go +++ b/services/issue/issue_test.go @@ -7,13 +7,17 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" "github.com/stretchr/testify/assert" ) func TestGetRefEndNamesAndURLs(t *testing.T) { - issues := []*models.Issue{ + issues := []*issues_model.Issue{ {ID: 1, Ref: "refs/heads/branch1"}, {ID: 2, Ref: "refs/tags/tag1"}, {ID: 3, Ref: "c0ffee"}, @@ -28,3 +32,56 @@ func TestGetRefEndNamesAndURLs(t *testing.T) { 3: repoLink + "/src/commit/c0ffee", }, urls) } + +func TestIssue_DeleteIssue(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + issueIDs, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) + assert.NoError(t, err) + assert.EqualValues(t, 5, len(issueIDs)) + + issue := &issues_model.Issue{ + RepoID: 1, + ID: issueIDs[2], + } + + err = deleteIssue(issue) + assert.NoError(t, err) + issueIDs, err = issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) + assert.NoError(t, err) + assert.EqualValues(t, 4, len(issueIDs)) + + // check attachment removal + attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 4) + assert.NoError(t, err) + issue, err = issues_model.GetIssueByID(db.DefaultContext, 4) + assert.NoError(t, err) + err = deleteIssue(issue) + assert.NoError(t, err) + assert.EqualValues(t, 2, len(attachments)) + for i := range attachments { + attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attachments[i].UUID) + assert.Error(t, err) + assert.True(t, repo_model.IsErrAttachmentNotExist(err)) + assert.Nil(t, attachment) + } + + // check issue dependencies + user, err := user_model.GetUserByID(1) + assert.NoError(t, err) + issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1) + assert.NoError(t, err) + issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2) + assert.NoError(t, err) + err = issues_model.CreateIssueDependency(user, issue1, issue2) + assert.NoError(t, err) + left, err := issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) + assert.NoError(t, err) + assert.False(t, left) + + err = deleteIssue(issue2) + assert.NoError(t, err) + left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1) + assert.NoError(t, err) + assert.True(t, left) +} diff --git a/services/issue/label.go b/services/issue/label.go index 289466f604..bc5f9b910e 100644 --- a/services/issue/label.go +++ b/services/issue/label.go @@ -5,16 +5,16 @@ package issue import ( - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" ) // ClearLabels clears all of an issue's labels -func ClearLabels(issue *models.Issue, doer *user_model.User) (err error) { - if err = models.ClearIssueLabels(issue, doer); err != nil { +func ClearLabels(issue *issues_model.Issue, doer *user_model.User) (err error) { + if err = issues_model.ClearIssueLabels(issue, doer); err != nil { return } @@ -24,18 +24,18 @@ func ClearLabels(issue *models.Issue, doer *user_model.User) (err error) { } // AddLabel adds a new label to the issue. -func AddLabel(issue *models.Issue, doer *user_model.User, label *models.Label) error { - if err := models.NewIssueLabel(issue, label, doer); err != nil { +func AddLabel(issue *issues_model.Issue, doer *user_model.User, label *issues_model.Label) error { + if err := issues_model.NewIssueLabel(issue, label, doer); err != nil { return err } - notification.NotifyIssueChangeLabels(doer, issue, []*models.Label{label}, nil) + notification.NotifyIssueChangeLabels(doer, issue, []*issues_model.Label{label}, nil) return nil } // AddLabels adds a list of new labels to the issue. -func AddLabels(issue *models.Issue, doer *user_model.User, labels []*models.Label) error { - if err := models.NewIssueLabels(issue, labels, doer); err != nil { +func AddLabels(issue *issues_model.Issue, doer *user_model.User, labels []*issues_model.Label) error { + if err := issues_model.NewIssueLabels(issue, labels, doer); err != nil { return err } @@ -44,7 +44,7 @@ func AddLabels(issue *models.Issue, doer *user_model.User, labels []*models.Labe } // RemoveLabel removes a label from issue by given ID. -func RemoveLabel(issue *models.Issue, doer *user_model.User, label *models.Label) error { +func RemoveLabel(issue *issues_model.Issue, doer *user_model.User, label *issues_model.Label) error { ctx, committer, err := db.TxContext() if err != nil { return err @@ -61,12 +61,12 @@ func RemoveLabel(issue *models.Issue, doer *user_model.User, label *models.Label } if !perm.CanWriteIssuesOrPulls(issue.IsPull) { if label.OrgID > 0 { - return models.ErrOrgLabelNotExist{} + return issues_model.ErrOrgLabelNotExist{} } - return models.ErrRepoLabelNotExist{} + return issues_model.ErrRepoLabelNotExist{} } - if err := models.DeleteIssueLabel(ctx, issue, label, doer); err != nil { + if err := issues_model.DeleteIssueLabel(ctx, issue, label, doer); err != nil { return err } @@ -74,18 +74,18 @@ func RemoveLabel(issue *models.Issue, doer *user_model.User, label *models.Label return err } - notification.NotifyIssueChangeLabels(doer, issue, nil, []*models.Label{label}) + notification.NotifyIssueChangeLabels(doer, issue, nil, []*issues_model.Label{label}) return nil } // ReplaceLabels removes all current labels and add new labels to the issue. -func ReplaceLabels(issue *models.Issue, doer *user_model.User, labels []*models.Label) error { - old, err := models.GetLabelsByIssueID(db.DefaultContext, issue.ID) +func ReplaceLabels(issue *issues_model.Issue, doer *user_model.User, labels []*issues_model.Label) error { + old, err := issues_model.GetLabelsByIssueID(db.DefaultContext, issue.ID) if err != nil { return err } - if err := models.ReplaceIssueLabels(issue, labels, doer); err != nil { + if err := issues_model.ReplaceIssueLabels(issue, labels, doer); err != nil { return err } diff --git a/services/issue/label_test.go b/services/issue/label_test.go index 73e30e894f..120c9ea4f1 100644 --- a/services/issue/label_test.go +++ b/services/issue/label_test.go @@ -7,7 +7,7 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -27,15 +27,15 @@ func TestIssue_AddLabels(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: test.issueID}).(*models.Issue) - labels := make([]*models.Label, len(test.labelIDs)) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) + labels := make([]*issues_model.Label, len(test.labelIDs)) for i, labelID := range test.labelIDs { - labels[i] = unittest.AssertExistsAndLoadBean(t, &models.Label{ID: labelID}).(*models.Label) + labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label) } doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) assert.NoError(t, AddLabels(issue, doer, labels)) for _, labelID := range test.labelIDs { - unittest.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: test.issueID, LabelID: labelID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: labelID}) } } } @@ -53,10 +53,10 @@ func TestIssue_AddLabel(t *testing.T) { } for _, test := range tests { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: test.issueID}).(*models.Issue) - label := unittest.AssertExistsAndLoadBean(t, &models.Label{ID: test.labelID}).(*models.Label) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue) + label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: test.labelID}).(*issues_model.Label) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User) assert.NoError(t, AddLabel(issue, doer, label)) - unittest.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: test.issueID, LabelID: test.labelID}) + unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: test.labelID}) } } diff --git a/services/issue/milestone.go b/services/issue/milestone.go index 287f8ae285..af337c3f14 100644 --- a/services/issue/milestone.go +++ b/services/issue/milestone.go @@ -8,15 +8,14 @@ import ( "context" "fmt" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" ) -func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *models.Issue, oldMilestoneID int64) error { - if err := models.UpdateIssueCols(ctx, issue, "milestone_id"); err != nil { +func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) error { + if err := issues_model.UpdateIssueCols(ctx, issue, "milestone_id"); err != nil { return err } @@ -37,15 +36,15 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *mo return err } - opts := &models.CreateCommentOptions{ - Type: models.CommentTypeMilestone, + opts := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeMilestone, Doer: doer, Repo: issue.Repo, Issue: issue, OldMilestoneID: oldMilestoneID, MilestoneID: issue.MilestoneID, } - if _, err := models.CreateCommentCtx(ctx, opts); err != nil { + if _, err := issues_model.CreateCommentCtx(ctx, opts); err != nil { return err } } @@ -54,7 +53,7 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *mo } // ChangeMilestoneAssign changes assignment of milestone for issue. -func ChangeMilestoneAssign(issue *models.Issue, doer *user_model.User, oldMilestoneID int64) (err error) { +func ChangeMilestoneAssign(issue *issues_model.Issue, doer *user_model.User, oldMilestoneID int64) (err error) { ctx, committer, err := db.TxContext() if err != nil { return err diff --git a/services/issue/milestone_test.go b/services/issue/milestone_test.go index 80e37a8acd..d08b1ae8c7 100644 --- a/services/issue/milestone_test.go +++ b/services/issue/milestone_test.go @@ -7,7 +7,6 @@ package issue import ( "testing" - "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -17,7 +16,7 @@ import ( func TestChangeMilestoneAssign(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{RepoID: 1}).(*models.Issue) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: 1}).(*issues_model.Issue) doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) assert.NotNil(t, issue) assert.NotNil(t, doer) @@ -25,11 +24,11 @@ func TestChangeMilestoneAssign(t *testing.T) { oldMilestoneID := issue.MilestoneID issue.MilestoneID = 2 assert.NoError(t, ChangeMilestoneAssign(issue, doer, oldMilestoneID)) - unittest.AssertExistsAndLoadBean(t, &models.Comment{ + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issue.ID, - Type: models.CommentTypeMilestone, + Type: issues_model.CommentTypeMilestone, MilestoneID: issue.MilestoneID, OldMilestoneID: oldMilestoneID, }) - unittest.CheckConsistencyFor(t, &issues_model.Milestone{}, &models.Issue{}) + unittest.CheckConsistencyFor(t, &issues_model.Milestone{}, &issues_model.Issue{}) } diff --git a/services/issue/status.go b/services/issue/status.go index d2b4fc303e..0da5c88762 100644 --- a/services/issue/status.go +++ b/services/issue/status.go @@ -7,25 +7,25 @@ package issue import ( "context" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" ) // ChangeStatus changes issue status to open or closed. -func ChangeStatus(issue *models.Issue, doer *user_model.User, closed bool) error { +func ChangeStatus(issue *issues_model.Issue, doer *user_model.User, closed bool) error { return changeStatusCtx(db.DefaultContext, issue, doer, closed) } // changeStatusCtx changes issue status to open or closed. // TODO: if context is not db.DefaultContext we get a deadlock!!! -func changeStatusCtx(ctx context.Context, issue *models.Issue, doer *user_model.User, closed bool) error { - comment, err := models.ChangeIssueStatus(ctx, issue, doer, closed) +func changeStatusCtx(ctx context.Context, issue *issues_model.Issue, doer *user_model.User, closed bool) error { + comment, err := issues_model.ChangeIssueStatus(ctx, issue, doer, closed) if err != nil { - if models.IsErrDependenciesLeft(err) && closed { - if err := models.FinishIssueStopwatchIfPossible(ctx, doer, issue); err != nil { + if issues_model.IsErrDependenciesLeft(err) && closed { + if err := issues_model.FinishIssueStopwatchIfPossible(ctx, doer, issue); err != nil { log.Error("Unable to stop stopwatch for issue[%d]#%d: %v", issue.ID, issue.Index, err) } } @@ -33,7 +33,7 @@ func changeStatusCtx(ctx context.Context, issue *models.Issue, doer *user_model. } if closed { - if err := models.FinishIssueStopwatchIfPossible(ctx, doer, issue); err != nil { + if err := issues_model.FinishIssueStopwatchIfPossible(ctx, doer, issue); err != nil { return err } } diff --git a/services/mailer/mail.go b/services/mailer/mail.go index bdd7e25cab..81cfb2e31a 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -19,6 +19,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -220,10 +221,10 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient prefix string // Fall back subject for bad templates, make sure subject is never empty fallback string - reviewComments []*models.Comment + reviewComments []*issues_model.Comment ) - commentType := models.CommentTypeComment + commentType := issues_model.CommentTypeComment if ctx.Comment != nil { commentType = ctx.Comment.Type link = ctx.Issue.HTMLURL() + "#" + ctx.Comment.HashTag() @@ -231,7 +232,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient link = ctx.Issue.HTMLURL() } - reviewType := models.ReviewTypeComment + reviewType := issues_model.ReviewTypeComment if ctx.Comment != nil && ctx.Comment.Review != nil { reviewType = ctx.Comment.Review.Type } @@ -254,7 +255,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient fallback = prefix + fallbackMailSubject(ctx.Issue) if ctx.Comment != nil && ctx.Comment.Review != nil { - reviewComments = make([]*models.Comment, 0, 10) + reviewComments = make([]*issues_model.Comment, 0, 10) for _, lines := range ctx.Comment.Review.CodeComments { for _, comments := range lines { reviewComments = append(reviewComments, comments...) @@ -328,7 +329,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient return msgs, nil } -func createReference(issue *models.Issue, comment *models.Comment, actionType models.ActionType) string { +func createReference(issue *issues_model.Issue, comment *issues_model.Comment, actionType models.ActionType) string { var path string if issue.IsPull { path = "pulls" @@ -400,7 +401,7 @@ func sanitizeSubject(subject string) string { } // SendIssueAssignedMail composes and sends issue assigned email -func SendIssueAssignedMail(issue *models.Issue, doer *user_model.User, content string, comment *models.Comment, recipients []*user_model.User) error { +func SendIssueAssignedMail(issue *issues_model.Issue, doer *user_model.User, content string, comment *issues_model.Comment, recipients []*user_model.User) error { if setting.MailService == nil { // No mail service configured return nil @@ -439,8 +440,8 @@ func SendIssueAssignedMail(issue *models.Issue, doer *user_model.User, content s // actionToTemplate returns the type and name of the action facing the user // (slightly different from models.ActionType) and the name of the template to use (based on availability) -func actionToTemplate(issue *models.Issue, actionType models.ActionType, - commentType models.CommentType, reviewType models.ReviewType, +func actionToTemplate(issue *issues_model.Issue, actionType models.ActionType, + commentType issues_model.CommentType, reviewType issues_model.ReviewType, ) (typeName, name, template string) { if issue.IsPull { typeName = "pull" @@ -464,20 +465,20 @@ func actionToTemplate(issue *models.Issue, actionType models.ActionType, name = "ready_for_review" default: switch commentType { - case models.CommentTypeReview: + case issues_model.CommentTypeReview: switch reviewType { - case models.ReviewTypeApprove: + case issues_model.ReviewTypeApprove: name = "approve" - case models.ReviewTypeReject: + case issues_model.ReviewTypeReject: name = "reject" default: name = "review" } - case models.CommentTypeCode: + case issues_model.CommentTypeCode: name = "code" - case models.CommentTypeAssignees: + case issues_model.CommentTypeAssignees: name = "assigned" - case models.CommentTypePullRequestPush: + case issues_model.CommentTypePullRequestPush: name = "push" default: name = "default" diff --git a/services/mailer/mail_comment.go b/services/mailer/mail_comment.go index baecd2a101..95d11ae8a1 100644 --- a/services/mailer/mail_comment.go +++ b/services/mailer/mail_comment.go @@ -8,20 +8,21 @@ import ( "context" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) // MailParticipantsComment sends new comment emails to repository watchers and mentioned people. -func MailParticipantsComment(ctx context.Context, c *models.Comment, opType models.ActionType, issue *models.Issue, mentions []*user_model.User) error { +func MailParticipantsComment(ctx context.Context, c *issues_model.Comment, opType models.ActionType, issue *issues_model.Issue, mentions []*user_model.User) error { if setting.MailService == nil { // No mail service configured return nil } content := c.Content - if c.Type == models.CommentTypePullRequestPush { + if c.Type == issues_model.CommentTypePullRequestPush { content = "" } if err := mailIssueCommentToParticipants( @@ -39,7 +40,7 @@ func MailParticipantsComment(ctx context.Context, c *models.Comment, opType mode } // MailMentionsComment sends email to users mentioned in a code comment -func MailMentionsComment(ctx context.Context, pr *models.PullRequest, c *models.Comment, mentions []*user_model.User) (err error) { +func MailMentionsComment(ctx context.Context, pr *issues_model.PullRequest, c *issues_model.Comment, mentions []*user_model.User) (err error) { if setting.MailService == nil { // No mail service configured return nil diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go index d479dd0d44..5c330f6e00 100644 --- a/services/mailer/mail_issue.go +++ b/services/mailer/mail_issue.go @@ -9,6 +9,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -16,17 +17,17 @@ import ( "code.gitea.io/gitea/modules/setting" ) -func fallbackMailSubject(issue *models.Issue) string { +func fallbackMailSubject(issue *issues_model.Issue) string { return fmt.Sprintf("[%s] %s (#%d)", issue.Repo.FullName(), issue.Title, issue.Index) } type mailCommentContext struct { context.Context - Issue *models.Issue + Issue *issues_model.Issue Doer *user_model.User ActionType models.ActionType Content string - Comment *models.Comment + Comment *issues_model.Comment } const ( @@ -57,21 +58,21 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo unfiltered[0] = ctx.Issue.PosterID // =========== Assignees =========== - ids, err := models.GetAssigneeIDsByIssue(ctx.Issue.ID) + ids, err := issues_model.GetAssigneeIDsByIssue(ctx.Issue.ID) if err != nil { return fmt.Errorf("GetAssigneeIDsByIssue(%d): %v", ctx.Issue.ID, err) } unfiltered = append(unfiltered, ids...) // =========== Participants (i.e. commenters, reviewers) =========== - ids, err = models.GetParticipantsIDsByIssueID(ctx.Issue.ID) + ids, err = issues_model.GetParticipantsIDsByIssueID(ctx.Issue.ID) if err != nil { return fmt.Errorf("GetParticipantsIDsByIssueID(%d): %v", ctx.Issue.ID, err) } unfiltered = append(unfiltered, ids...) // =========== Issue watchers =========== - ids, err = models.GetIssueWatchersIDs(ctx, ctx.Issue.ID, true) + ids, err = issues_model.GetIssueWatchersIDs(ctx, ctx.Issue.ID, true) if err != nil { return fmt.Errorf("GetIssueWatchersIDs(%d): %v", ctx.Issue.ID, err) } @@ -98,7 +99,7 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo } // Avoid mailing explicit unwatched - ids, err = models.GetIssueWatchersIDs(ctx, ctx.Issue.ID, false) + ids, err = issues_model.GetIssueWatchersIDs(ctx, ctx.Issue.ID, false) if err != nil { return fmt.Errorf("GetIssueWatchersIDs(%d): %v", ctx.Issue.ID, err) } @@ -171,7 +172,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi // MailParticipants sends new issue thread created emails to repository watchers // and mentioned people. -func MailParticipants(issue *models.Issue, doer *user_model.User, opType models.ActionType, mentions []*user_model.User) error { +func MailParticipants(issue *issues_model.Issue, doer *user_model.User, opType models.ActionType, mentions []*user_model.User) error { if setting.MailService == nil { // No mail service configured return nil diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go index baf426146a..83955a5896 100644 --- a/services/mailer/mail_test.go +++ b/services/mailer/mail_test.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -46,7 +47,7 @@ const bodyTpl = ` ` -func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Repository, issue *models.Issue, comment *models.Comment) { +func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, comment *issues_model.Comment) { assert.NoError(t, unittest.PrepareTestDatabase()) mailService := setting.Mailer{ From: "test@gitea.com", @@ -57,9 +58,9 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer}).(*repo_model.Repository) - issue = unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue) + issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1, Repo: repo, Poster: doer}).(*issues_model.Issue) assert.NoError(t, issue.LoadRepo(db.DefaultContext)) - comment = unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment) + comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2, Issue: issue}).(*issues_model.Comment) return } @@ -162,8 +163,8 @@ func TestTemplateSelection(t *testing.T) { }, recipients, false, "TestTemplateSelection") expect(t, msg, "issue/default/subject", "issue/default/body") - pull := unittest.AssertExistsAndLoadBean(t, &models.Issue{ID: 2, Repo: repo, Poster: doer}).(*models.Issue) - comment = unittest.AssertExistsAndLoadBean(t, &models.Comment{ID: 4, Issue: pull}).(*models.Comment) + pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer}).(*issues_model.Issue) + comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull}).(*issues_model.Comment) msg = testComposeIssueCommentMessage(t, &mailCommentContext{ Context: context.TODO(), // TODO: use a correct context Issue: pull, Doer: doer, ActionType: models.ActionCommentPull, @@ -183,7 +184,7 @@ func TestTemplateServices(t *testing.T) { doer, _, issue, comment := prepareMailerTest(t) assert.NoError(t, issue.LoadRepo(db.DefaultContext)) - expect := func(t *testing.T, issue *models.Issue, comment *models.Comment, doer *user_model.User, + expect := func(t *testing.T, issue *issues_model.Issue, comment *issues_model.Comment, doer *user_model.User, actionType models.ActionType, fromMention bool, tplSubject, tplBody, expSubject, expBody string, ) { stpl := texttmpl.Must(texttmpl.New("issue/default").Parse(tplSubject)) @@ -268,8 +269,8 @@ func Test_createReference(t *testing.T) { pullIssue.IsPull = true type args struct { - issue *models.Issue - comment *models.Comment + issue *issues_model.Issue + comment *issues_model.Comment actionType models.ActionType } tests := []struct { diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index 408704adef..e71b2ca17a 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -45,14 +45,14 @@ type GiteaLocalUploader struct { repoOwner string repoName string repo *repo_model.Repository - labels map[string]*models.Label + labels map[string]*issues_model.Label milestones map[string]int64 - issues map[int64]*models.Issue + issues map[int64]*issues_model.Issue gitRepo *git.Repository prHeadCache map[string]struct{} sameApp bool userMap map[int64]int64 // external user id mapping to user id - prCache map[int64]*models.PullRequest + prCache map[int64]*issues_model.PullRequest gitServiceType structs.GitServiceType } @@ -63,12 +63,12 @@ func NewGiteaLocalUploader(ctx context.Context, doer *user_model.User, repoOwner doer: doer, repoOwner: repoOwner, repoName: repoName, - labels: make(map[string]*models.Label), + labels: make(map[string]*issues_model.Label), milestones: make(map[string]int64), - issues: make(map[int64]*models.Issue), + issues: make(map[int64]*issues_model.Issue), prHeadCache: make(map[string]struct{}), userMap: make(map[int64]int64), - prCache: make(map[int64]*models.PullRequest), + prCache: make(map[int64]*issues_model.PullRequest), } } @@ -76,17 +76,17 @@ func NewGiteaLocalUploader(ctx context.Context, doer *user_model.User, repoOwner func (g *GiteaLocalUploader) MaxBatchInsertSize(tp string) int { switch tp { case "issue": - return db.MaxBatchInsertSize(new(models.Issue)) + return db.MaxBatchInsertSize(new(issues_model.Issue)) case "comment": - return db.MaxBatchInsertSize(new(models.Comment)) + return db.MaxBatchInsertSize(new(issues_model.Comment)) case "milestone": return db.MaxBatchInsertSize(new(issues_model.Milestone)) case "label": - return db.MaxBatchInsertSize(new(models.Label)) + return db.MaxBatchInsertSize(new(issues_model.Label)) case "release": return db.MaxBatchInsertSize(new(models.Release)) case "pullrequest": - return db.MaxBatchInsertSize(new(models.PullRequest)) + return db.MaxBatchInsertSize(new(issues_model.PullRequest)) } return 10 } @@ -216,9 +216,9 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err // CreateLabels creates labels func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { - lbs := make([]*models.Label, 0, len(labels)) + lbs := make([]*issues_model.Label, 0, len(labels)) for _, label := range labels { - lbs = append(lbs, &models.Label{ + lbs = append(lbs, &issues_model.Label{ RepoID: g.repo.ID, Name: label.Name, Description: label.Description, @@ -226,7 +226,7 @@ func (g *GiteaLocalUploader) CreateLabels(labels ...*base.Label) error { }) } - err := models.NewLabels(lbs...) + err := issues_model.NewLabels(lbs...) if err != nil { return err } @@ -339,9 +339,9 @@ func (g *GiteaLocalUploader) SyncTags() error { // CreateIssues creates issues func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { - iss := make([]*models.Issue, 0, len(issues)) + iss := make([]*issues_model.Issue, 0, len(issues)) for _, issue := range issues { - var labels []*models.Label + var labels []*issues_model.Label for _, label := range issue.Labels { lb, ok := g.labels[label.Name] if ok { @@ -366,7 +366,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { } } - is := models.Issue{ + is := issues_model.Issue{ RepoID: g.repo.ID, Repo: g.repo, Index: issue.Number, @@ -423,9 +423,9 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { // CreateComments creates comments of issues func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { - cms := make([]*models.Comment, 0, len(comments)) + cms := make([]*issues_model.Comment, 0, len(comments)) for _, comment := range comments { - var issue *models.Issue + var issue *issues_model.Issue issue, ok := g.issues[comment.IssueIndex] if !ok { return fmt.Errorf("comment references non existent IssueIndex %d", comment.IssueIndex) @@ -438,9 +438,9 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { comment.Updated = comment.Created } - cm := models.Comment{ + cm := issues_model.Comment{ IssueID: issue.ID, - Type: models.CommentTypeComment, + Type: issues_model.CommentTypeComment, Content: comment.Content, CreatedUnix: timeutil.TimeStamp(comment.Created.Unix()), UpdatedUnix: timeutil.TimeStamp(comment.Updated.Unix()), @@ -473,7 +473,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { // CreatePullRequests creates pull requests func (g *GiteaLocalUploader) CreatePullRequests(prs ...*base.PullRequest) error { - gprs := make([]*models.PullRequest, 0, len(prs)) + gprs := make([]*issues_model.PullRequest, 0, len(prs)) for _, pr := range prs { gpr, err := g.newPullRequest(pr) if err != nil { @@ -600,8 +600,8 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(pr *base.PullRequest) (head return head, nil } -func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullRequest, error) { - var labels []*models.Label +func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model.PullRequest, error) { + var labels []*issues_model.Label for _, label := range pr.Labels { lb, ok := g.labels[label.Name] if ok { @@ -629,7 +629,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR pr.Updated = pr.Created } - issue := models.Issue{ + issue := issues_model.Issue{ RepoID: g.repo.ID, Repo: g.repo, Title: pr.Title, @@ -660,7 +660,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR issue.Reactions = append(issue.Reactions, &res) } - pullRequest := models.PullRequest{ + pullRequest := issues_model.PullRequest{ HeadRepoID: g.repo.ID, HeadBranch: head, BaseRepoID: g.repo.ID, @@ -686,28 +686,28 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR return &pullRequest, nil } -func convertReviewState(state string) models.ReviewType { +func convertReviewState(state string) issues_model.ReviewType { switch state { case base.ReviewStatePending: - return models.ReviewTypePending + return issues_model.ReviewTypePending case base.ReviewStateApproved: - return models.ReviewTypeApprove + return issues_model.ReviewTypeApprove case base.ReviewStateChangesRequested: - return models.ReviewTypeReject + return issues_model.ReviewTypeReject case base.ReviewStateCommented: - return models.ReviewTypeComment + return issues_model.ReviewTypeComment case base.ReviewStateRequestReview: - return models.ReviewTypeRequest + return issues_model.ReviewTypeRequest default: - return models.ReviewTypePending + return issues_model.ReviewTypePending } } // CreateReviews create pull request reviews of currently migrated issues func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { - cms := make([]*models.Review, 0, len(reviews)) + cms := make([]*issues_model.Review, 0, len(reviews)) for _, review := range reviews { - var issue *models.Issue + var issue *issues_model.Issue issue, ok := g.issues[review.IssueIndex] if !ok { return fmt.Errorf("review references non existent IssueIndex %d", review.IssueIndex) @@ -716,7 +716,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { review.CreatedAt = time.Unix(int64(issue.CreatedUnix), 0) } - cm := models.Review{ + cm := issues_model.Review{ Type: convertReviewState(review.State), IssueID: issue.ID, Content: review.Content, @@ -733,7 +733,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { pr, ok := g.prCache[issue.ID] if !ok { var err error - pr, err = models.GetPullRequestByIssueIDWithNoAttributes(issue.ID) + pr, err = issues_model.GetPullRequestByIssueIDWithNoAttributes(issue.ID) if err != nil { return err } @@ -767,7 +767,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { _ = writer.Close() }(comment) - patch, _ = git.CutDiffAroundLine(reader, int64((&models.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) + patch, _ = git.CutDiffAroundLine(reader, int64((&issues_model.Comment{Line: int64(line + comment.Position - 1)}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) if comment.CreatedAt.IsZero() { comment.CreatedAt = review.CreatedAt @@ -776,8 +776,8 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { comment.UpdatedAt = comment.CreatedAt } - c := models.Comment{ - Type: models.CommentTypeCode, + c := issues_model.Comment{ + Type: issues_model.CommentTypeCode, IssueID: issue.ID, Content: comment.Content, Line: int64(line + comment.Position - 1), @@ -798,7 +798,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { cms = append(cms, &cm) } - return models.InsertReviews(cms) + return issues_model.InsertReviews(cms) } // Rollback when migrating failed, this will rollback all the changes. @@ -819,7 +819,7 @@ func (g *GiteaLocalUploader) Finish() error { } // update issue_index - if err := models.RecalculateIssueIndexForRepo(g.repo.ID); err != nil { + if err := issues_model.RecalculateIssueIndexForRepo(g.repo.ID); err != nil { return err } diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index bd7c6e0657..6ea1c20592 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -81,7 +81,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Empty(t, milestones) - labels, err := models.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) + labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{}) assert.NoError(t, err) assert.Len(t, labels, 12) @@ -105,7 +105,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, err) assert.Len(t, releases, 1) - issues, err := models.Issues(&models.IssuesOptions{ + issues, err := issues_model.Issues(&issues_model.IssuesOptions{ RepoID: repo.ID, IsPull: util.OptionalBoolFalse, SortType: "oldest", @@ -115,7 +115,7 @@ func TestGiteaUploadRepo(t *testing.T) { assert.NoError(t, issues[0].LoadDiscussComments()) assert.Empty(t, issues[0].Comments) - pulls, _, err := models.PullRequests(repo.ID, &models.PullRequestsOptions{ + pulls, _, err := issues_model.PullRequests(repo.ID, &issues_model.PullRequestsOptions{ SortType: "oldest", }) assert.NoError(t, err) diff --git a/services/pull/check.go b/services/pull/check.go index 94e7ca7161..6621a281fa 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -44,9 +45,9 @@ var ( ) // AddToTaskQueue adds itself to pull request test task queue. -func AddToTaskQueue(pr *models.PullRequest) { +func AddToTaskQueue(pr *issues_model.PullRequest) { err := prPatchCheckerQueue.PushFunc(strconv.FormatInt(pr.ID, 10), func() error { - pr.Status = models.PullRequestStatusChecking + pr.Status = issues_model.PullRequestStatusChecking err := pr.UpdateColsIfNotMerged("status") if err != nil { log.Error("AddToTaskQueue.UpdateCols[%d].(add to queue): %v", pr.ID, err) @@ -61,7 +62,7 @@ func AddToTaskQueue(pr *models.PullRequest) { } // CheckPullMergable check if the pull mergable based on all conditions (branch protection, merge options, ...) -func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *models.PullRequest, manuallMerge, force bool) error { +func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *issues_model.PullRequest, manuallMerge, force bool) error { return db.WithTx(func(ctx context.Context) error { if pr.HasMerged { return ErrHasMerged @@ -114,7 +115,7 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce return err } - if noDeps, err := models.IssueNoDependenciesLeft(ctx, pr.Issue); err != nil { + if noDeps, err := issues_model.IssueNoDependenciesLeft(ctx, pr.Issue); err != nil { return err } else if !noDeps { return ErrDependenciesLeft @@ -125,7 +126,7 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *acce } // isSignedIfRequired check if merge will be signed if required -func isSignedIfRequired(ctx context.Context, pr *models.PullRequest, doer *user_model.User) (bool, error) { +func isSignedIfRequired(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User) (bool, error) { if err := pr.LoadProtectedBranchCtx(ctx); err != nil { return false, err } @@ -141,10 +142,10 @@ func isSignedIfRequired(ctx context.Context, pr *models.PullRequest, doer *user_ // checkAndUpdateStatus checks if pull request is possible to leaving checking status, // and set to be either conflict or mergeable. -func checkAndUpdateStatus(pr *models.PullRequest) { +func checkAndUpdateStatus(pr *issues_model.PullRequest) { // Status is not changed to conflict means mergeable. - if pr.Status == models.PullRequestStatusChecking { - pr.Status = models.PullRequestStatusMergeable + if pr.Status == issues_model.PullRequestStatusChecking { + pr.Status = issues_model.PullRequestStatusMergeable } // Make sure there is no waiting test to process before leaving the checking status. @@ -162,7 +163,7 @@ func checkAndUpdateStatus(pr *models.PullRequest) { // getMergeCommit checks if a pull request got merged // Returns the git.Commit of the pull request if merged -func getMergeCommit(ctx context.Context, pr *models.PullRequest) (*git.Commit, error) { +func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Commit, error) { if pr.BaseRepo == nil { var err error pr.BaseRepo, err = repo_model.GetRepositoryByID(pr.BaseRepoID) @@ -230,7 +231,7 @@ func getMergeCommit(ctx context.Context, pr *models.PullRequest) (*git.Commit, e // manuallyMerged checks if a pull request got manually merged // When a pull request got manually merged mark the pull request as merged -func manuallyMerged(ctx context.Context, pr *models.PullRequest) bool { +func manuallyMerged(ctx context.Context, pr *issues_model.PullRequest) bool { if err := pr.LoadBaseRepoCtx(ctx); err != nil { log.Error("PullRequest[%d].LoadBaseRepo: %v", pr.ID, err) return false @@ -254,7 +255,7 @@ func manuallyMerged(ctx context.Context, pr *models.PullRequest) bool { if commit != nil { pr.MergedCommitID = commit.ID.String() pr.MergedUnix = timeutil.TimeStamp(commit.Author.When.Unix()) - pr.Status = models.PullRequestStatusManuallyMerged + pr.Status = issues_model.PullRequestStatusManuallyMerged merger, _ := user_model.GetUserByEmail(commit.Author.Email) // When the commit author is unknown set the BaseRepo owner as merger @@ -287,7 +288,7 @@ func manuallyMerged(ctx context.Context, pr *models.PullRequest) bool { // InitializePullRequests checks and tests untested patches of pull requests. func InitializePullRequests(ctx context.Context) { - prs, err := models.GetPullRequestIDsByCheckStatus(models.PullRequestStatusChecking) + prs, err := issues_model.GetPullRequestIDsByCheckStatus(issues_model.PullRequestStatusChecking) if err != nil { log.Error("Find Checking PRs: %v", err) return @@ -323,7 +324,7 @@ func testPR(id int64) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("Test PR[%d] from patch checking queue", id)) defer finished() - pr, err := models.GetPullRequestByID(ctx, id) + pr, err := issues_model.GetPullRequestByID(ctx, id) if err != nil { log.Error("GetPullRequestByID[%d]: %v", id, err) return @@ -339,7 +340,7 @@ func testPR(id int64) { if err := TestPatch(pr); err != nil { log.Error("testPatch[%d]: %v", pr.ID, err) - pr.Status = models.PullRequestStatusError + pr.Status = issues_model.PullRequestStatusError if err := pr.UpdateCols("status"); err != nil { log.Error("update pr [%d] status to PullRequestStatusError failed: %v", pr.ID, err) } @@ -350,7 +351,7 @@ func testPR(id int64) { // CheckPrsForBaseBranch check all pulls with bseBrannch func CheckPrsForBaseBranch(baseRepo *repo_model.Repository, baseBranchName string) error { - prs, err := models.GetUnmergedPullRequestsByBaseInfo(baseRepo.ID, baseBranchName) + prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(baseRepo.ID, baseBranchName) if err != nil { return err } diff --git a/services/pull/check_test.go b/services/pull/check_test.go index bc4c45ffad..21fe675bbc 100644 --- a/services/pull/check_test.go +++ b/services/pull/check_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/queue" @@ -43,12 +43,12 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) { prPatchCheckerQueue = q.(queue.UniqueQueue) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) AddToTaskQueue(pr) assert.Eventually(t, func() bool { - pr = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) - return pr.Status == models.PullRequestStatusChecking + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + return pr.Status == issues_model.PullRequestStatusChecking }, 1*time.Second, 100*time.Millisecond) has, err := prPatchCheckerQueue.Has(strconv.FormatInt(pr.ID, 10)) @@ -72,8 +72,8 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) { assert.False(t, has) assert.NoError(t, err) - pr = unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) - assert.Equal(t, models.PullRequestStatusChecking, pr.Status) + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) + assert.Equal(t, issues_model.PullRequestStatusChecking, pr.Status) for _, callback := range queueShutdown { callback() diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go index c0894c6c98..5d846129f6 100644 --- a/services/pull/commit_status.go +++ b/services/pull/commit_status.go @@ -8,9 +8,9 @@ package pull import ( "context" - "code.gitea.io/gitea/models" "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/structs" @@ -83,7 +83,7 @@ func IsCommitStatusContextSuccess(commitStatuses []*git_model.CommitStatus, requ } // IsPullCommitStatusPass returns if all required status checks PASS -func IsPullCommitStatusPass(ctx context.Context, pr *models.PullRequest) (bool, error) { +func IsPullCommitStatusPass(ctx context.Context, pr *issues_model.PullRequest) (bool, error) { if err := pr.LoadProtectedBranchCtx(ctx); err != nil { return false, errors.Wrap(err, "GetLatestCommitStatus") } @@ -99,7 +99,7 @@ func IsPullCommitStatusPass(ctx context.Context, pr *models.PullRequest) (bool, } // GetPullRequestCommitStatusState returns pull request merged commit status state -func GetPullRequestCommitStatusState(ctx context.Context, pr *models.PullRequest) (structs.CommitStatusState, error) { +func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullRequest) (structs.CommitStatusState, error) { // Ensure HeadRepo is loaded if err := pr.LoadHeadRepoCtx(ctx); err != nil { return "", errors.Wrap(err, "LoadHeadRepo") @@ -112,15 +112,15 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *models.PullRequest } defer closer.Close() - if pr.Flow == models.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) { + if pr.Flow == issues_model.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) { return "", errors.New("Head branch does not exist, can not merge") } - if pr.Flow == models.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) { + if pr.Flow == issues_model.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) { return "", errors.New("Head branch does not exist, can not merge") } var sha string - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { sha, err = headGitRepo.GetBranchCommitID(pr.HeadBranch) } else { sha, err = headGitRepo.GetRefCommitID(pr.GetGitRefName()) diff --git a/services/pull/edits.go b/services/pull/edits.go index 11932d9ab8..2938f2b108 100644 --- a/services/pull/edits.go +++ b/services/pull/edits.go @@ -9,7 +9,7 @@ import ( "context" "errors" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -18,7 +18,7 @@ import ( var ErrUserHasNoPermissionForAction = errors.New("user not allowed to do this action") // SetAllowEdits allow edits from maintainers to PRs -func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *models.PullRequest, allow bool) error { +func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, allow bool) error { if doer == nil || !pr.Issue.IsPoster(doer.ID) { return ErrUserHasNoPermissionForAction } @@ -37,5 +37,5 @@ func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *models.PullRe } pr.AllowMaintainerEdit = allow - return models.UpdateAllowEdits(ctx, pr) + return issues_model.UpdateAllowEdits(ctx, pr) } diff --git a/services/pull/lfs.go b/services/pull/lfs.go index 490a904584..8cca0a91b7 100644 --- a/services/pull/lfs.go +++ b/services/pull/lfs.go @@ -12,15 +12,15 @@ import ( "strconv" "sync" - "code.gitea.io/gitea/models" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/git/pipeline" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" ) // LFSPush pushes lfs objects referred to in new commits in the head repository from the base repository -func LFSPush(ctx context.Context, tmpBasePath, mergeHeadSHA, mergeBaseSHA string, pr *models.PullRequest) error { +func LFSPush(ctx context.Context, tmpBasePath, mergeHeadSHA, mergeBaseSHA string, pr *issues_model.PullRequest) error { // Now we have to implement git lfs push // git rev-list --objects --filter=blob:limit=1k HEAD --not base // pass blob shas in to git cat-file --batch-check (possibly unnecessary) @@ -68,7 +68,7 @@ func LFSPush(ctx context.Context, tmpBasePath, mergeHeadSHA, mergeBaseSHA string return nil } -func createLFSMetaObjectsFromCatFileBatch(catFileBatchReader *io.PipeReader, wg *sync.WaitGroup, pr *models.PullRequest) { +func createLFSMetaObjectsFromCatFileBatch(catFileBatchReader *io.PipeReader, wg *sync.WaitGroup, pr *issues_model.PullRequest) { defer wg.Done() defer catFileBatchReader.Close() diff --git a/services/pull/merge.go b/services/pull/merge.go index eef1d17b64..aff800a1b6 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" pull_model "code.gitea.io/gitea/models/pull" repo_model "code.gitea.io/gitea/models/repo" @@ -38,7 +39,7 @@ import ( ) // GetDefaultMergeMessage returns default message used when merging pull request -func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *models.PullRequest, mergeStyle repo_model.MergeStyle) (string, error) { +func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle) (string, error) { if err := pr.LoadHeadRepo(); err != nil { return "", err } @@ -131,7 +132,7 @@ func GetDefaultMergeMessage(baseGitRepo *git.Repository, pr *models.PullRequest, // Merge merges pull request to base repository. // Caller should check PR is ready to be merged (review and status checks) -func Merge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) error { +func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) error { if err := pr.LoadHeadRepo(); err != nil { log.Error("LoadHeadRepo: %v", err) return fmt.Errorf("LoadHeadRepo: %v", err) @@ -213,7 +214,7 @@ func Merge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, b if close != ref.Issue.IsClosed { if err = issue_service.ChangeStatus(ref.Issue, doer, close); err != nil { // Allow ErrDependenciesLeft - if !models.IsErrDependenciesLeft(err) { + if !issues_model.IsErrDependenciesLeft(err) { return err } } @@ -223,7 +224,7 @@ func Merge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, b } // rawMerge perform the merge operation without changing any pull information in database -func rawMerge(ctx context.Context, pr *models.PullRequest, doer *user_model.User, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) (string, error) { +func rawMerge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, mergeStyle repo_model.MergeStyle, expectedHeadCommitID, message string) (string, error) { // Clone base repo. tmpBasePath, err := createTemporaryRepo(ctx, pr) if err != nil { @@ -635,7 +636,7 @@ func rawMerge(ctx context.Context, pr *models.PullRequest, doer *user_model.User return mergeCommitID, nil } -func commitAndSignNoAuthor(ctx context.Context, pr *models.PullRequest, message, signArg, tmpBasePath string, env []string) error { +func commitAndSignNoAuthor(ctx context.Context, pr *issues_model.PullRequest, message, signArg, tmpBasePath string, env []string) error { var outbuf, errbuf strings.Builder if signArg == "" { if err := git.NewCommand(ctx, "commit", "-m", message). @@ -663,7 +664,7 @@ func commitAndSignNoAuthor(ctx context.Context, pr *models.PullRequest, message, return nil } -func runMergeCommand(pr *models.PullRequest, mergeStyle repo_model.MergeStyle, cmd *git.Command, tmpBasePath string) error { +func runMergeCommand(pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle, cmd *git.Command, tmpBasePath string) error { var outbuf, errbuf strings.Builder if err := cmd.Run(&git.RunOpts{ Dir: tmpBasePath, @@ -747,7 +748,7 @@ func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string) ( } // IsUserAllowedToMerge check if user is allowed to merge PR with given permissions and branch protections -func IsUserAllowedToMerge(ctx context.Context, pr *models.PullRequest, p access_model.Permission, user *user_model.User) (bool, error) { +func IsUserAllowedToMerge(ctx context.Context, pr *issues_model.PullRequest, p access_model.Permission, user *user_model.User) (bool, error) { if user == nil { return false, nil } @@ -765,7 +766,7 @@ func IsUserAllowedToMerge(ctx context.Context, pr *models.PullRequest, p access_ } // CheckPullBranchProtections checks whether the PR is ready to be merged (reviews and status checks) -func CheckPullBranchProtections(ctx context.Context, pr *models.PullRequest, skipProtectedFilesCheck bool) (err error) { +func CheckPullBranchProtections(ctx context.Context, pr *issues_model.PullRequest, skipProtectedFilesCheck bool) (err error) { if err = pr.LoadBaseRepoCtx(ctx); err != nil { return fmt.Errorf("LoadBaseRepo: %v", err) } @@ -787,23 +788,23 @@ func CheckPullBranchProtections(ctx context.Context, pr *models.PullRequest, ski } } - if !models.HasEnoughApprovals(ctx, pr.ProtectedBranch, pr) { + if !issues_model.HasEnoughApprovals(ctx, pr.ProtectedBranch, pr) { return models.ErrDisallowedToMerge{ Reason: "Does not have enough approvals", } } - if models.MergeBlockedByRejectedReview(ctx, pr.ProtectedBranch, pr) { + if issues_model.MergeBlockedByRejectedReview(ctx, pr.ProtectedBranch, pr) { return models.ErrDisallowedToMerge{ Reason: "There are requested changes", } } - if models.MergeBlockedByOfficialReviewRequests(ctx, pr.ProtectedBranch, pr) { + if issues_model.MergeBlockedByOfficialReviewRequests(ctx, pr.ProtectedBranch, pr) { return models.ErrDisallowedToMerge{ Reason: "There are official review requests", } } - if models.MergeBlockedByOutdatedBranch(pr.ProtectedBranch, pr) { + if issues_model.MergeBlockedByOutdatedBranch(pr.ProtectedBranch, pr) { return models.ErrDisallowedToMerge{ Reason: "The head branch is behind the base branch", } @@ -823,7 +824,7 @@ func CheckPullBranchProtections(ctx context.Context, pr *models.PullRequest, ski } // MergedManually mark pr as merged manually -func MergedManually(pr *models.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, commitID string) error { +func MergedManually(pr *issues_model.PullRequest, doer *user_model.User, baseGitRepo *git.Repository, commitID string) error { pullWorkingPool.CheckIn(fmt.Sprint(pr.ID)) defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID)) @@ -862,7 +863,7 @@ func MergedManually(pr *models.PullRequest, doer *user_model.User, baseGitRepo * pr.MergedCommitID = commitID pr.MergedUnix = timeutil.TimeStamp(commit.Author.When.Unix()) - pr.Status = models.PullRequestStatusManuallyMerged + pr.Status = issues_model.PullRequestStatusManuallyMerged pr.Merger = doer pr.MergerID = doer.ID diff --git a/services/pull/patch.go b/services/pull/patch.go index 6e2889b060..c7a69501c3 100644 --- a/services/pull/patch.go +++ b/services/pull/patch.go @@ -15,6 +15,7 @@ import ( "strings" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/graceful" @@ -27,7 +28,7 @@ import ( ) // DownloadDiffOrPatch will write the patch for the pr to the writer -func DownloadDiffOrPatch(ctx context.Context, pr *models.PullRequest, w io.Writer, patch, binary bool) error { +func DownloadDiffOrPatch(ctx context.Context, pr *issues_model.PullRequest, w io.Writer, patch, binary bool) error { if err := pr.LoadBaseRepoCtx(ctx); err != nil { log.Error("Unable to load base repository ID %d for pr #%d [%d]", pr.BaseRepoID, pr.Index, pr.ID) return err @@ -54,7 +55,7 @@ var patchErrorSuffices = []string{ } // TestPatch will test whether a simple patch will apply -func TestPatch(pr *models.PullRequest) error { +func TestPatch(pr *issues_model.PullRequest) error { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("TestPatch: Repo[%d]#%d", pr.BaseRepoID, pr.Index)) defer finished() @@ -88,7 +89,7 @@ func TestPatch(pr *models.PullRequest) error { pr.MergeBase = strings.TrimSpace(pr.MergeBase) // 2. Check for conflicts - if conflicts, err := checkConflicts(ctx, pr, gitRepo, tmpBasePath); err != nil || conflicts || pr.Status == models.PullRequestStatusEmpty { + if conflicts, err := checkConflicts(ctx, pr, gitRepo, tmpBasePath); err != nil || conflicts || pr.Status == issues_model.PullRequestStatusEmpty { return err } @@ -101,7 +102,7 @@ func TestPatch(pr *models.PullRequest) error { log.Trace("Found %d protected files changed", len(pr.ChangedProtectedFiles)) } - pr.Status = models.PullRequestStatusMergeable + pr.Status = issues_model.PullRequestStatusMergeable return nil } @@ -270,7 +271,7 @@ func AttemptThreeWayMerge(ctx context.Context, gitPath string, gitRepo *git.Repo return conflict, conflictedFiles, nil } -func checkConflicts(ctx context.Context, pr *models.PullRequest, gitRepo *git.Repository, tmpBasePath string) (bool, error) { +func checkConflicts(ctx context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository, tmpBasePath string) (bool, error) { // 1. checkConflicts resets the conflict status - therefore - reset the conflict status pr.ConflictedFiles = nil @@ -295,7 +296,7 @@ func checkConflicts(ctx context.Context, pr *models.PullRequest, gitRepo *git.Re } if treeHash == baseTree.ID.String() { log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID) - pr.Status = models.PullRequestStatusEmpty + pr.Status = issues_model.PullRequestStatusEmpty } return false, nil @@ -329,7 +330,7 @@ func checkConflicts(ctx context.Context, pr *models.PullRequest, gitRepo *git.Re // 3b. if the size of that patch is 0 - there can be no conflicts! if stat.Size() == 0 { log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID) - pr.Status = models.PullRequestStatusEmpty + pr.Status = issues_model.PullRequestStatusEmpty return false, nil } @@ -449,7 +450,7 @@ func checkConflicts(ctx context.Context, pr *models.PullRequest, gitRepo *git.Re // Note: `"err" could be non-nil` is due that if enable 3-way merge, it doesn't return any error on found conflicts. if len(pr.ConflictedFiles) > 0 { if conflict { - pr.Status = models.PullRequestStatusConflict + pr.Status = issues_model.PullRequestStatusConflict log.Trace("Found %d files conflicted: %v", len(pr.ConflictedFiles), pr.ConflictedFiles) return true, nil @@ -516,8 +517,8 @@ func CheckUnprotectedFiles(repo *git.Repository, oldCommitID, newCommitID string } // checkPullFilesProtection check if pr changed protected files and save results -func checkPullFilesProtection(pr *models.PullRequest, gitRepo *git.Repository) error { - if pr.Status == models.PullRequestStatusEmpty { +func checkPullFilesProtection(pr *issues_model.PullRequest, gitRepo *git.Repository) error { + if pr.Status == issues_model.PullRequestStatusEmpty { pr.ChangedProtectedFiles = nil return nil } diff --git a/services/pull/pull.go b/services/pull/pull.go index 736520fda2..103fdc340d 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -35,7 +36,7 @@ import ( var pullWorkingPool = sync.NewExclusivePool() // NewPullRequest creates new pull request with labels for repository. -func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *models.Issue, labelIDs []int64, uuids []string, pr *models.PullRequest, assigneeIDs []int64) error { +func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *issues_model.Issue, labelIDs []int64, uuids []string, pr *issues_model.PullRequest, assigneeIDs []int64) error { if err := TestPatch(pr); err != nil { return err } @@ -47,7 +48,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode pr.CommitsAhead = divergence.Ahead pr.CommitsBehind = divergence.Behind - if err := models.NewPullRequest(ctx, repo, pull, labelIDs, uuids, pr); err != nil { + if err := issues_model.NewPullRequest(ctx, repo, pull, labelIDs, uuids, pr); err != nil { return err } @@ -66,7 +67,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode prCtx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("NewPullRequest: %s:%d", repo.FullName(), pr.Index)) defer finished() - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { err = PushToBaseRepo(prCtx, pr) } else { err = UpdateRef(prCtx, pr) @@ -75,7 +76,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode return err } - mentions, err := models.FindAndUpdateIssueMentions(ctx, pull, pull.Poster, pull.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, pull, pull.Poster, pull.Content) if err != nil { return err } @@ -102,7 +103,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode } if len(compareInfo.Commits) > 0 { - data := models.PushActionContent{IsForcePush: false} + data := issues_model.PushActionContent{IsForcePush: false} data.CommitIDs = make([]string, 0, len(compareInfo.Commits)) for i := len(compareInfo.Commits) - 1; i >= 0; i-- { data.CommitIDs = append(data.CommitIDs, compareInfo.Commits[i].ID.String()) @@ -113,8 +114,8 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode return err } - ops := &models.CreateCommentOptions{ - Type: models.CommentTypePullRequestPush, + ops := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypePullRequestPush, Doer: pull.Poster, Repo: repo, Issue: pr.Issue, @@ -122,14 +123,14 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *mode Content: string(dataJSON), } - _, _ = models.CreateComment(ops) + _, _ = issues_model.CreateComment(ops) } return nil } // ChangeTargetBranch changes the target branch of this pull request, as the given user. -func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_model.User, targetBranch string) (err error) { +func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, targetBranch string) (err error) { pullWorkingPool.CheckIn(fmt.Sprint(pr.ID)) defer pullWorkingPool.CheckOut(fmt.Sprint(pr.ID)) @@ -139,7 +140,7 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ } if pr.Issue.IsClosed { - return models.ErrIssueIsClosed{ + return issues_model.ErrIssueIsClosed{ ID: pr.Issue.ID, RepoID: pr.Issue.RepoID, Index: pr.Issue.Index, @@ -170,9 +171,9 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ } // Check if pull request for the new target branch already exists - existingPr, err := models.GetUnmergedPullRequest(pr.HeadRepoID, pr.BaseRepoID, pr.HeadBranch, targetBranch, models.PullRequestFlowGithub) + existingPr, err := issues_model.GetUnmergedPullRequest(pr.HeadRepoID, pr.BaseRepoID, pr.HeadBranch, targetBranch, issues_model.PullRequestFlowGithub) if existingPr != nil { - return models.ErrPullRequestAlreadyExists{ + return issues_model.ErrPullRequestAlreadyExists{ ID: existingPr.ID, IssueID: existingPr.Index, HeadRepoID: existingPr.HeadRepoID, @@ -181,7 +182,7 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ BaseBranch: existingPr.BaseBranch, } } - if err != nil && !models.IsErrPullRequestNotExist(err) { + if err != nil && !issues_model.IsErrPullRequestNotExist(err) { return err } @@ -196,8 +197,8 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ // Update target branch, PR diff and status // This is the same as checkAndUpdateStatus in check service, but also updates base_branch - if pr.Status == models.PullRequestStatusChecking { - pr.Status = models.PullRequestStatusMergeable + if pr.Status == issues_model.PullRequestStatusChecking { + pr.Status = issues_model.PullRequestStatusMergeable } // Update Commit Divergence @@ -213,22 +214,22 @@ func ChangeTargetBranch(ctx context.Context, pr *models.PullRequest, doer *user_ } // Create comment - options := &models.CreateCommentOptions{ - Type: models.CommentTypeChangeTargetBranch, + options := &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeChangeTargetBranch, Doer: doer, Repo: pr.Issue.Repo, Issue: pr.Issue, OldRef: oldBranch, NewRef: targetBranch, } - if _, err = models.CreateComment(options); err != nil { + if _, err = issues_model.CreateComment(options); err != nil { return fmt.Errorf("CreateChangeTargetBranchComment: %v", err) } return nil } -func checkForInvalidation(ctx context.Context, requests models.PullRequestList, repoID int64, doer *user_model.User, branch string) error { +func checkForInvalidation(ctx context.Context, requests issues_model.PullRequestList, repoID int64, doer *user_model.User, branch string) error { repo, err := repo_model.GetRepositoryByID(repoID) if err != nil { return fmt.Errorf("GetRepositoryByID: %v", err) @@ -257,14 +258,14 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, // If you don't let it run all the way then you will lose data // TODO: graceful: AddTestPullRequestTask needs to become a queue! - prs, err := models.GetUnmergedPullRequestsByHeadInfo(repoID, branch) + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(repoID, branch) if err != nil { log.Error("Find pull requests [head_repo_id: %d, head_branch: %s]: %v", repoID, branch, err) return } if isSync { - requests := models.PullRequestList(prs) + requests := issues_model.PullRequestList(prs) if err = requests.LoadAttributes(); err != nil { log.Error("PullRequestList.LoadAttributes: %v", err) } @@ -280,11 +281,11 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, } if changed { // Mark old reviews as stale if diff to mergebase has changed - if err := models.MarkReviewsAsStale(pr.IssueID); err != nil { + if err := issues_model.MarkReviewsAsStale(pr.IssueID); err != nil { log.Error("MarkReviewsAsStale: %v", err) } } - if err := models.MarkReviewsAsNotStale(pr.IssueID, newCommitID); err != nil { + if err := issues_model.MarkReviewsAsNotStale(pr.IssueID, newCommitID); err != nil { log.Error("MarkReviewsAsNotStale: %v", err) } divergence, err := GetDiverging(ctx, pr) @@ -306,7 +307,7 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, for _, pr := range prs { log.Trace("Updating PR[%d]: composing new test task", pr.ID) - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { if err := PushToBaseRepo(ctx, pr); err != nil { log.Error("PushToBaseRepo: %v", err) continue @@ -316,14 +317,14 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, } AddToTaskQueue(pr) - comment, err := models.CreatePushPullComment(ctx, doer, pr, oldCommitID, newCommitID) + comment, err := issues_model.CreatePushPullComment(ctx, doer, pr, oldCommitID, newCommitID) if err == nil && comment != nil { notification.NotifyPullRequestPushCommits(doer, pr, comment) } } log.Trace("AddTestPullRequestTask [base_repo_id: %d, base_branch: %s]: finding pull requests", repoID, branch) - prs, err = models.GetUnmergedPullRequestsByBaseInfo(repoID, branch) + prs, err = issues_model.GetUnmergedPullRequestsByBaseInfo(repoID, branch) if err != nil { log.Error("Find pull requests [base_repo_id: %d, base_branch: %s]: %v", repoID, branch, err) return @@ -349,7 +350,7 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, // checkIfPRContentChanged checks if diff to target branch has changed by push // A commit can be considered to leave the PR untouched if the patch/diff with its merge base is unchanged -func checkIfPRContentChanged(ctx context.Context, pr *models.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) { +func checkIfPRContentChanged(ctx context.Context, pr *issues_model.PullRequest, oldCommitID, newCommitID string) (hasChanged bool, err error) { if err = pr.LoadHeadRepoCtx(ctx); err != nil { return false, fmt.Errorf("LoadHeadRepo: %v", err) } else if pr.HeadRepo == nil { @@ -421,11 +422,11 @@ func checkIfPRContentChanged(ctx context.Context, pr *models.PullRequest, oldCom // PushToBaseRepo pushes commits from branches of head repository to // corresponding branches of base repository. // FIXME: Only push branches that are actually updates? -func PushToBaseRepo(ctx context.Context, pr *models.PullRequest) (err error) { +func PushToBaseRepo(ctx context.Context, pr *issues_model.PullRequest) (err error) { return pushToBaseRepoHelper(ctx, pr, "") } -func pushToBaseRepoHelper(ctx context.Context, pr *models.PullRequest, prefixHeadBranch string) (err error) { +func pushToBaseRepoHelper(ctx context.Context, pr *issues_model.PullRequest, prefixHeadBranch string) (err error) { log.Trace("PushToBaseRepo[%d]: pushing commits to base repo '%s'", pr.BaseRepoID, pr.GetGitRefName()) if err := pr.LoadHeadRepoCtx(ctx); err != nil { @@ -481,7 +482,7 @@ func pushToBaseRepoHelper(ctx context.Context, pr *models.PullRequest, prefixHea } // UpdateRef update refs/pull/id/head directly for agit flow pull request -func UpdateRef(ctx context.Context, pr *models.PullRequest) (err error) { +func UpdateRef(ctx context.Context, pr *issues_model.PullRequest) (err error) { log.Trace("UpdateRef[%d]: upgate pull request ref in base repo '%s'", pr.ID, pr.GetGitRefName()) if err := pr.LoadBaseRepoCtx(ctx); err != nil { log.Error("Unable to load base repository for PR[%d] Error: %v", pr.ID, err) @@ -514,24 +515,24 @@ func (errs errlist) Error() string { // CloseBranchPulls close all the pull requests who's head branch is the branch func CloseBranchPulls(doer *user_model.User, repoID int64, branch string) error { - prs, err := models.GetUnmergedPullRequestsByHeadInfo(repoID, branch) + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(repoID, branch) if err != nil { return err } - prs2, err := models.GetUnmergedPullRequestsByBaseInfo(repoID, branch) + prs2, err := issues_model.GetUnmergedPullRequestsByBaseInfo(repoID, branch) if err != nil { return err } prs = append(prs, prs2...) - if err := models.PullRequestList(prs).LoadAttributes(); err != nil { + if err := issues_model.PullRequestList(prs).LoadAttributes(); err != nil { return err } var errs errlist for _, pr := range prs { - if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !models.IsErrPullWasClosed(err) && !models.IsErrDependenciesLeft(err) { + if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !issues_model.IsErrPullWasClosed(err) && !issues_model.IsErrDependenciesLeft(err) { errs = append(errs, err) } } @@ -550,12 +551,12 @@ func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *re var errs errlist for _, branch := range branches { - prs, err := models.GetUnmergedPullRequestsByHeadInfo(repo.ID, branch.Name) + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(repo.ID, branch.Name) if err != nil { return err } - if err = models.PullRequestList(prs).LoadAttributes(); err != nil { + if err = issues_model.PullRequestList(prs).LoadAttributes(); err != nil { return err } @@ -565,7 +566,7 @@ func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *re if pr.BaseRepoID == repo.ID { continue } - if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !models.IsErrPullWasClosed(err) { + if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !issues_model.IsErrPullWasClosed(err) { errs = append(errs, err) } } @@ -580,7 +581,7 @@ func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *re var commitMessageTrailersPattern = regexp.MustCompile(`(?:^|\n\n)(?:[\w-]+[ \t]*:[^\n]+\n*(?:[ \t]+[^\n]+\n*)*)+$`) // GetSquashMergeCommitMessages returns the commit messages between head and merge base (if there is one) -func GetSquashMergeCommitMessages(ctx context.Context, pr *models.PullRequest) string { +func GetSquashMergeCommitMessages(ctx context.Context, pr *issues_model.PullRequest) string { if err := pr.LoadIssue(); err != nil { log.Error("Cannot load issue %d for PR id %d: Error: %v", pr.IssueID, pr.ID, err) return "" @@ -608,7 +609,7 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *models.PullRequest) s defer closer.Close() var headCommit *git.Commit - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { headCommit, err = gitRepo.GetBranchCommit(pr.HeadBranch) } else { pr.HeadCommitID, err = gitRepo.GetRefCommitID(pr.GetGitRefName()) @@ -736,13 +737,13 @@ func GetSquashMergeCommitMessages(ctx context.Context, pr *models.PullRequest) s } // GetIssuesLastCommitStatus returns a map of issue ID to the most recent commit's latest status -func GetIssuesLastCommitStatus(ctx context.Context, issues models.IssueList) (map[int64]*git_model.CommitStatus, error) { +func GetIssuesLastCommitStatus(ctx context.Context, issues issues_model.IssueList) (map[int64]*git_model.CommitStatus, error) { _, lastStatus, err := GetIssuesAllCommitStatus(ctx, issues) return lastStatus, err } // GetIssuesAllCommitStatus returns a map of issue ID to a list of all statuses for the most recent commit as well as a map of issue ID to only the commit's latest status -func GetIssuesAllCommitStatus(ctx context.Context, issues models.IssueList) (map[int64][]*git_model.CommitStatus, map[int64]*git_model.CommitStatus, error) { +func GetIssuesAllCommitStatus(ctx context.Context, issues issues_model.IssueList) (map[int64][]*git_model.CommitStatus, map[int64]*git_model.CommitStatus, error) { if err := issues.LoadPullRequests(); err != nil { return nil, nil, err } @@ -788,7 +789,7 @@ func GetIssuesAllCommitStatus(ctx context.Context, issues models.IssueList) (map } // getAllCommitStatus get pr's commit statuses. -func getAllCommitStatus(gitRepo *git.Repository, pr *models.PullRequest) (statuses []*git_model.CommitStatus, lastStatus *git_model.CommitStatus, err error) { +func getAllCommitStatus(gitRepo *git.Repository, pr *issues_model.PullRequest) (statuses []*git_model.CommitStatus, lastStatus *git_model.CommitStatus, err error) { sha, shaErr := gitRepo.GetRefCommitID(pr.GetGitRefName()) if shaErr != nil { return nil, nil, shaErr @@ -800,7 +801,7 @@ func getAllCommitStatus(gitRepo *git.Repository, pr *models.PullRequest) (status } // IsHeadEqualWithBranch returns if the commits of branchName are available in pull request head -func IsHeadEqualWithBranch(ctx context.Context, pr *models.PullRequest, branchName string) (bool, error) { +func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, branchName string) (bool, error) { var err error if err = pr.LoadBaseRepoCtx(ctx); err != nil { return false, err @@ -833,7 +834,7 @@ func IsHeadEqualWithBranch(ctx context.Context, pr *models.PullRequest, branchNa } var headCommit *git.Commit - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { headCommit, err = headGitRepo.GetBranchCommit(pr.HeadBranch) if err != nil { return false, err diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go index 09bae97780..9160c43460 100644 --- a/services/pull/pull_test.go +++ b/services/pull/pull_test.go @@ -8,7 +8,7 @@ package pull import ( "testing" - "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" @@ -38,7 +38,7 @@ func TestPullRequest_CommitMessageTrailersPattern(t *testing.T) { func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2}).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadBaseRepo()) gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) @@ -68,7 +68,7 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) baseRepo.Units = []*repo_model.RepoUnit{&externalTracker} - pr := unittest.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 2, BaseRepo: baseRepo}).(*models.PullRequest) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo}).(*issues_model.PullRequest) assert.NoError(t, pr.LoadBaseRepo()) gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath()) diff --git a/services/pull/review.go b/services/pull/review.go index eac7279f9b..9cb58fa3a1 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -12,8 +12,8 @@ import ( "regexp" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -23,7 +23,7 @@ import ( ) // CreateCodeComment creates a comment on the code line -func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *models.Issue, line int64, content, treePath string, isReview bool, replyReviewID int64, latestCommitID string) (*models.Comment, error) { +func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, line int64, content, treePath string, isReview bool, replyReviewID int64, latestCommitID string) (*issues_model.Comment, error) { var ( existsReview bool err error @@ -37,7 +37,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. if !isReview && replyReviewID != 0 { // It's not part of a review; maybe a reply to a review comment or a single comment. // Check if there are reviews for that line already; if there are, this is a reply - if existsReview, err = models.ReviewExists(issue, treePath, line); err != nil { + if existsReview, err = issues_model.ReviewExists(issue, treePath, line); err != nil { return nil, err } } @@ -61,7 +61,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. return nil, err } - mentions, err := models.FindAndUpdateIssueMentions(ctx, issue, doer, comment.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comment.Content) if err != nil { return nil, err } @@ -71,14 +71,14 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. return comment, nil } - review, err := models.GetCurrentReview(ctx, doer, issue) + review, err := issues_model.GetCurrentReview(ctx, doer, issue) if err != nil { - if !models.IsErrReviewNotExist(err) { + if !issues_model.IsErrReviewNotExist(err) { return nil, err } - if review, err = models.CreateReview(ctx, models.CreateReviewOptions{ - Type: models.ReviewTypePending, + if review, err = issues_model.CreateReview(ctx, issues_model.CreateReviewOptions{ + Type: issues_model.ReviewTypePending, Reviewer: doer, Issue: issue, Official: false, @@ -103,7 +103,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. if !isReview && !existsReview { // Submit the review we've just created so the comment shows up in the issue view - if _, _, err = SubmitReview(ctx, doer, gitRepo, issue, models.ReviewTypeComment, "", latestCommitID, nil); err != nil { + if _, _, err = SubmitReview(ctx, doer, gitRepo, issue, issues_model.ReviewTypeComment, "", latestCommitID, nil); err != nil { return nil, err } } @@ -116,7 +116,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git. var notEnoughLines = regexp.MustCompile(`exit status 128 - fatal: file .* has only \d+ lines?`) // createCodeComment creates a plain code comment at the specified line / path -func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *models.Issue, content, treePath string, line, reviewID int64) (*models.Comment, error) { +func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, treePath string, line, reviewID int64) (*issues_model.Comment, error) { var commitID, patch string if err := issue.LoadPullRequest(); err != nil { return nil, fmt.Errorf("GetPullRequestByIssueID: %v", err) @@ -135,11 +135,11 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo head := pr.GetGitRefName() if line > 0 { if reviewID != 0 { - first, err := models.FindComments(ctx, &models.FindCommentsOptions{ + first, err := issues_model.FindComments(ctx, &issues_model.FindCommentsOptions{ ReviewID: reviewID, Line: line, TreePath: treePath, - Type: models.CommentTypeCode, + Type: issues_model.CommentTypeCode, ListOptions: db.ListOptions{ PageSize: 1, Page: 1, @@ -149,13 +149,13 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo commitID = first[0].CommitSHA invalidated = first[0].Invalidated patch = first[0].Patch - } else if err != nil && !models.IsErrCommentNotExist(err) { + } else if err != nil && !issues_model.IsErrCommentNotExist(err) { return nil, fmt.Errorf("Find first comment for %d line %d path %s. Error: %v", reviewID, line, treePath, err) } else { - review, err := models.GetReviewByID(ctx, reviewID) + review, err := issues_model.GetReviewByID(ctx, reviewID) if err == nil && len(review.CommitID) > 0 { head = review.CommitID - } else if err != nil && !models.IsErrReviewNotExist(err) { + } else if err != nil && !issues_model.IsErrReviewNotExist(err) { return nil, fmt.Errorf("GetReviewByID %d. Error: %v", reviewID, err) } } @@ -196,14 +196,14 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo _ = writer.Close() }() - patch, err = git.CutDiffAroundLine(reader, int64((&models.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) + patch, err = git.CutDiffAroundLine(reader, int64((&issues_model.Comment{Line: line}).UnsignedLine()), line < 0, setting.UI.CodeCommentLines) if err != nil { log.Error("Error whilst generating patch: %v", err) return nil, err } } - return models.CreateComment(&models.CreateCommentOptions{ - Type: models.CommentTypeCode, + return issues_model.CreateComment(&issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeCode, Doer: doer, Repo: repo, Issue: issue, @@ -218,14 +218,14 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo } // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist -func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *models.Issue, reviewType models.ReviewType, content, commitID string, attachmentUUIDs []string) (*models.Review, *models.Comment, error) { +func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, reviewType issues_model.ReviewType, content, commitID string, attachmentUUIDs []string) (*issues_model.Review, *issues_model.Comment, error) { pr, err := issue.GetPullRequest() if err != nil { return nil, nil, err } var stale bool - if reviewType != models.ReviewTypeApprove && reviewType != models.ReviewTypeReject { + if reviewType != issues_model.ReviewTypeApprove && reviewType != issues_model.ReviewTypeReject { stale = false } else { headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName()) @@ -243,12 +243,12 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos } } - review, comm, err := models.SubmitReview(doer, issue, reviewType, content, commitID, stale, attachmentUUIDs) + review, comm, err := issues_model.SubmitReview(doer, issue, reviewType, content, commitID, stale, attachmentUUIDs) if err != nil { return nil, nil, err } - mentions, err := models.FindAndUpdateIssueMentions(ctx, issue, doer, comm.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comm.Content) if err != nil { return nil, nil, err } @@ -258,7 +258,7 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos for _, lines := range review.CodeComments { for _, comments := range lines { for _, codeComment := range comments { - mentions, err := models.FindAndUpdateIssueMentions(ctx, issue, doer, codeComment.Content) + mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, codeComment.Content) if err != nil { return nil, nil, err } @@ -271,17 +271,17 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos } // DismissReview dismissing stale review by repo admin -func DismissReview(ctx context.Context, reviewID int64, message string, doer *user_model.User, isDismiss bool) (comment *models.Comment, err error) { - review, err := models.GetReviewByID(ctx, reviewID) +func DismissReview(ctx context.Context, reviewID int64, message string, doer *user_model.User, isDismiss bool) (comment *issues_model.Comment, err error) { + review, err := issues_model.GetReviewByID(ctx, reviewID) if err != nil { return } - if review.Type != models.ReviewTypeApprove && review.Type != models.ReviewTypeReject { + if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject { return nil, fmt.Errorf("not need to dismiss this review because it's type is not Approve or change request") } - if err = models.DismissReview(review, isDismiss); err != nil { + if err = issues_model.DismissReview(review, isDismiss); err != nil { return } @@ -296,14 +296,14 @@ func DismissReview(ctx context.Context, reviewID int64, message string, doer *us if err = review.Issue.LoadPullRequest(); err != nil { return } - if err = review.Issue.LoadAttributes(); err != nil { + if err = review.Issue.LoadAttributes(ctx); err != nil { return } - comment, err = models.CreateComment(&models.CreateCommentOptions{ + comment, err = issues_model.CreateComment(&issues_model.CreateCommentOptions{ Doer: doer, Content: message, - Type: models.CommentTypeDismissReview, + Type: issues_model.CommentTypeDismissReview, ReviewID: review.ID, Issue: review.Issue, Repo: review.Issue.Repo, diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go index 6b01809d49..c1456ef0a9 100644 --- a/services/pull/temp_repo.go +++ b/services/pull/temp_repo.go @@ -13,6 +13,7 @@ import ( "strings" "code.gitea.io/gitea/models" + 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/log" @@ -21,7 +22,7 @@ import ( // createTemporaryRepo creates a temporary repo with "base" for pr.BaseBranch and "tracking" for pr.HeadBranch // it also create a second base branch called "original_base" -func createTemporaryRepo(ctx context.Context, pr *models.PullRequest) (string, error) { +func createTemporaryRepo(ctx context.Context, pr *issues_model.PullRequest) (string, error) { if err := pr.LoadHeadRepoCtx(ctx); err != nil { log.Error("LoadHeadRepo: %v", err) return "", fmt.Errorf("LoadHeadRepo: %v", err) @@ -164,7 +165,7 @@ func createTemporaryRepo(ctx context.Context, pr *models.PullRequest) (string, e trackingBranch := "tracking" // Fetch head branch var headBranch string - if pr.Flow == models.PullRequestFlowGithub { + if pr.Flow == issues_model.PullRequestFlowGithub { headBranch = git.BranchPrefix + pr.HeadBranch } else if len(pr.HeadCommitID) == 40 { // for not created pull request headBranch = pr.HeadCommitID diff --git a/services/pull/update.go b/services/pull/update.go index 0ab8ffcd7d..e5e26462e5 100644 --- a/services/pull/update.go +++ b/services/pull/update.go @@ -9,6 +9,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + issues_model "code.gitea.io/gitea/models/issues" access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" @@ -19,9 +20,9 @@ import ( ) // Update updates pull request with base branch. -func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User, message string, rebase bool) error { +func Update(ctx context.Context, pull *issues_model.PullRequest, doer *user_model.User, message string, rebase bool) error { var ( - pr *models.PullRequest + pr *issues_model.PullRequest style repo_model.MergeStyle ) @@ -33,7 +34,7 @@ func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User style = repo_model.MergeStyleRebaseUpdate } else { // use merge functions but switch repo's and branch's - pr = &models.PullRequest{ + pr = &issues_model.PullRequest{ HeadRepoID: pull.BaseRepoID, BaseRepoID: pull.HeadRepoID, HeadBranch: pull.BaseBranch, @@ -42,7 +43,7 @@ func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User style = repo_model.MergeStyleMerge } - if pull.Flow == models.PullRequestFlowAGit { + if pull.Flow == issues_model.PullRequestFlowAGit { // TODO: Not support update agit flow pull request's head branch return fmt.Errorf("Not support update agit flow pull request's head branch") } @@ -76,8 +77,8 @@ func Update(ctx context.Context, pull *models.PullRequest, doer *user_model.User } // IsUserAllowedToUpdate check if user is allowed to update PR with given permissions and branch protections -func IsUserAllowedToUpdate(ctx context.Context, pull *models.PullRequest, user *user_model.User) (mergeAllowed, rebaseAllowed bool, err error) { - if pull.Flow == models.PullRequestFlowAGit { +func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest, user *user_model.User) (mergeAllowed, rebaseAllowed bool, err error) { + if pull.Flow == issues_model.PullRequestFlowAGit { return false, false, nil } @@ -89,7 +90,7 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *models.PullRequest, user * return false, false, err } - pr := &models.PullRequest{ + pr := &issues_model.PullRequest{ HeadRepoID: pull.BaseRepoID, BaseRepoID: pull.HeadRepoID, HeadBranch: pull.BaseBranch, @@ -139,7 +140,7 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *models.PullRequest, user * } // GetDiverging determines how many commits a PR is ahead or behind the PR base branch -func GetDiverging(ctx context.Context, pr *models.PullRequest) (*git.DivergeObject, error) { +func GetDiverging(ctx context.Context, pr *issues_model.PullRequest) (*git.DivergeObject, error) { log.Trace("GetDiverging[%d]: compare commits", pr.ID) if err := pr.LoadBaseRepoCtx(ctx); err != nil { return nil, err diff --git a/services/repository/repository.go b/services/repository/repository.go index 6848eda101..4bde6879a6 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models" admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" @@ -105,7 +106,7 @@ func UpdateRepository(repo *repo_model.Repository, visibilityChanged bool) (err // LinkedRepository returns the linked repo if any func LinkedRepository(a *repo_model.Attachment) (*repo_model.Repository, unit.Type, error) { if a.IssueID != 0 { - iss, err := models.GetIssueByID(a.IssueID) + iss, err := issues_model.GetIssueByID(db.DefaultContext, a.IssueID) if err != nil { return nil, unit.TypeIssues, err } diff --git a/services/repository/template.go b/services/repository/template.go index 6a1bfaff5b..d7e8145811 100644 --- a/services/repository/template.go +++ b/services/repository/template.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -18,14 +19,14 @@ import ( // GenerateIssueLabels generates issue labels from a template repository func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error { - templateLabels, err := models.GetLabelsByRepoID(ctx, templateRepo.ID, "", db.ListOptions{}) + templateLabels, err := issues_model.GetLabelsByRepoID(ctx, templateRepo.ID, "", db.ListOptions{}) if err != nil { return err } - newLabels := make([]*models.Label, 0, len(templateLabels)) + newLabels := make([]*issues_model.Label, 0, len(templateLabels)) for _, templateLabel := range templateLabels { - newLabels = append(newLabels, &models.Label{ + newLabels = append(newLabels, &issues_model.Label{ RepoID: generateRepo.ID, Name: templateLabel.Name, Description: templateLabel.Description, From 3c6c1507403b659a9ed790df19311a9f83175364 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 13 Jun 2022 20:55:08 +0800 Subject: [PATCH 4/7] Add deprecated log when using MySQL with utf8 charset (#19952) --- modules/setting/database.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/setting/database.go b/modules/setting/database.go index 5be2d8deea..a90ace5b4b 100644 --- a/modules/setting/database.go +++ b/modules/setting/database.go @@ -13,6 +13,8 @@ import ( "path/filepath" "strings" "time" + + "code.gitea.io/gitea/modules/log" ) var ( @@ -83,6 +85,10 @@ func InitDBConfig() { Database.Schema = sec.Key("SCHEMA").String() Database.SSLMode = sec.Key("SSL_MODE").MustString("disable") Database.Charset = sec.Key("CHARSET").In(defaultCharset, []string{"utf8", "utf8mb4"}) + if Database.UseMySQL && defaultCharset != "utf8mb4" { + log.Error("Deprecated database mysql charset utf8 support, please use utf8mb4 or convert utf8 to utf8mb4.") + } + Database.Path = sec.Key("PATH").MustString(filepath.Join(AppDataPath, "gitea.db")) Database.Timeout = sec.Key("SQLITE_TIMEOUT").MustInt(500) Database.MaxIdleConns = sec.Key("MAX_IDLE_CONNS").MustInt(2) From ff82a1831521bb2a9d91884eb2bc426a6403b0ed Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 14 Jun 2022 00:12:59 +0800 Subject: [PATCH 5/7] Fix mirror template bug (#19959) * Fix mirror template bug Co-authored-by: wxiaoguang Co-authored-by: delvh --- modules/context/repo.go | 20 ++++++-------------- templates/repo/header.tmpl | 7 ++++--- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/modules/context/repo.go b/modules/context/repo.go index c2b8306b9d..8e75ad07d5 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -380,24 +380,16 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) { ctx.Data["Permission"] = &ctx.Repo.Permission if repo.IsMirror { - - // Check if the mirror has finsihed migrationg, only then we can - // lookup the mirror informtation the database. - finishedMigrating, err := models.HasFinishedMigratingTask(repo.ID) - if err != nil { - ctx.ServerError("HasFinishedMigratingTask", err) - return - } - if finishedMigrating { - ctx.Repo.Mirror, err = repo_model.GetMirrorByRepoID(ctx, repo.ID) - if err != nil { - ctx.ServerError("GetMirrorByRepoID", err) - return - } + ctx.Repo.Mirror, err = repo_model.GetMirrorByRepoID(ctx, repo.ID) + if err == nil { ctx.Repo.Mirror.Repo = repo + ctx.Data["IsPullMirror"] = true ctx.Data["MirrorEnablePrune"] = ctx.Repo.Mirror.EnablePrune ctx.Data["MirrorInterval"] = ctx.Repo.Mirror.Interval ctx.Data["Mirror"] = ctx.Repo.Mirror + } else if err != repo_model.ErrMirrorNotExist { + ctx.ServerError("GetMirrorByRepoID", err) + return } } diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index cfac37cd11..029e9a186f 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -37,9 +37,10 @@ {{end}} - {{if .IsMirror}} - {{$address := MirrorRemoteAddress $.Context . $.Mirror.GetRemoteName}} -
{{$.i18n.Tr "repo.mirror_from"}} {{$address.Address}}
{{end}} + {{if $.IsPullMirror}} + {{$address := MirrorRemoteAddress $.Context . $.Mirror.GetRemoteName}} +
{{$.i18n.Tr "repo.mirror_from"}} {{$address.Address}}
+ {{end}} {{if .IsFork}}
{{$.i18n.Tr "repo.forked_from"}} {{.BaseRepo.FullName}}
{{end}} {{if .IsGenerated}}
{{$.i18n.Tr "repo.generated_from"}} {{.TemplateRepo.FullName}}
{{end}} From 0d7eda511f57a5327706129f9fc25a3fa5c1a898 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 14 Jun 2022 02:46:39 +0800 Subject: [PATCH 6/7] Fix aria for logo (#19955) Co-authored-by: 6543 <6543@obermui.de> --- templates/base/head_navbar.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 37a579142c..fab1d2d0b1 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -1,7 +1,7 @@