Skip to content

Commit

Permalink
Separates healtcheck and metadata pages
Browse files Browse the repository at this point in the history
  • Loading branch information
richmahn committed Dec 17, 2024
1 parent a2fc75a commit 34390b0
Show file tree
Hide file tree
Showing 16 changed files with 842 additions and 582 deletions.
250 changes: 248 additions & 2 deletions models/repo/door43healthcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ package repo

import (
"context"
"fmt"
"strings"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/dcs"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"
Expand Down Expand Up @@ -158,8 +161,8 @@ var IssueSuggestionsFormatStrings = map[IssueCode]string{
IssueCodeNoMetadata: "Add a manifest.yaml file to the repository to describe the resource.",
IssueCodeMetadataInvalid: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and fix these errors:\n\n<pre>%s</pre>",
IssueCodeRelation: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and change **`%s`** to **`%s/%s`** in the **`relation`** field.",
IssueCodePublisher: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and change `unfoldingWord` to the correct publisher in the **`publisher`** field, e.g. %s.",
IssueCodeTitle: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and remove 'unfoldingWord ' from the beginning of **`title`**, **`%s`** => **`%s`**, or translate into your language.",
IssueCodePublisher: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and change `unfoldingWord` to the correct publisher in the **`publisher`** field, such as **`%s`**.",
IssueCodeTitle: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and remove 'unfoldingWord ' from the beginning of **`title`**, such as **`%s`** => **`%s`**, or translate into your language.",
IssueCodeIdentifier: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and change **`%s`** to the correct **`identifier`** for the subject **`%s`**, which is **`%s`**.",
IssueCodeLanguage: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and change **`en`** to the correct **`language code`** for your project's language, the **`title`** of the language, and the **`direction`**.",
IssueCodeIngredientTitle: "Edit the [manifest.yaml](%s/src/branch/%s/manifest.yaml) file and translate the **`title`** of the projects. For example, translate **'%s'** to the resource's language.",
Expand Down Expand Up @@ -236,3 +239,246 @@ func GetHealthcheckGroupedIssues(ctx context.Context, dmID int64) (*HealthcheckG
healthcheck := NewHealthcheckGroupedIssues(issues)
return healthcheck, nil
}

// PerformHealthcheck on Door43Metadata
func PerformHealthcheck(ctx context.Context, dm *Door43Metadata) (*HealthcheckGroupedIssues, error) {
dm.LoadRepo(ctx)
if dm.HealthcheckUnix > 0 {
oldIssues, err := GetDoor43HealthcheckIssuesByDoor43MetadataID(ctx, dm.ID)
if err != nil {
return nil, err
}
for _, issue := range oldIssues {
issue.Current = false
if _, err := db.GetEngine(ctx).ID(issue.ID).Cols("current").Update(issue); err != nil {
return nil, err
}
}
}
issues := []*Door43HealthcheckIssue{}

// Check if metadata is valid
if dm.ValidationError != nil {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeMetadataInvalid,
SeverityLevel: SeverityLevelError,
Details: IssueCodeMetadataInvalid.IssueDetailsFormatString(),
Suggestion: fmt.Sprintf(IssueCodeMetadataInvalid.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref, dcs.ConvertValidationErrorToString(dm.ValidationError)),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}

if dm.Repo.Owner.LowerName != "unfoldingword" && (dm.Publisher == "" || strings.HasPrefix(strings.TrimSpace(dm.Publisher), "unfoldingWord")) {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodePublisher,
SeverityLevel: SeverityLevelError,
Details: IssueCodePublisher.IssueDetailsFormatString(),
Suggestion: fmt.Sprintf(IssueCodePublisher.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref, dm.Repo.OwnerName),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}

if dm.Repo.Owner.LowerName != "unfoldingword" && (dm.Title == "" || strings.HasPrefix(strings.TrimSpace(dm.Title), "unfoldingWord")) {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeTitle,
SeverityLevel: SeverityLevelError,
Details: IssueCodeTitle.IssueDetailsFormatString(),
Suggestion: fmt.Sprintf(IssueCodeTitle.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref, dm.Title, strings.Join(strings.Fields(dm.Title)[1:], " ")),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}

if dm.Abbreviation == "" || dm.Subject != "Bible" && dm.Subject != "Aligned Bible" {
if subject, ok := dcs.ResourceToSubjectMap[dm.Abbreviation]; !ok || subject != dm.Subject {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeIdentifier,
SeverityLevel: SeverityLevelError,
Details: fmt.Sprintf(IssueCodeIdentifier.IssueDetailsFormatString(), dm.Abbreviation, dm.Subject),
Suggestion: fmt.Sprintf(IssueCodeIdentifier.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref, dm.Abbreviation, dm.Subject, dcs.SubjectToResourceMap[dm.Subject]),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}
}

if dm.Language == "en" && !strings.HasPrefix(dm.Repo.Name, "en_") {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeLanguage,
SeverityLevel: SeverityLevelWarning,
Details: IssueCodeLanguage.IssueDetailsFormatString(),
Suggestion: fmt.Sprintf(IssueCodeLanguage.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}

// Check for relations in other languages
for _, relation := range dm.Relations {
if relation.Language != dm.Language && relation.Language != "hbo" && relation.Language != "el-x-koine" {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeRelation,
SeverityLevel: SeverityLevelError,
Details: fmt.Sprintf(IssueCodeRelation.IssueDetailsFormatString(), relation.FullRelation, dm.Language),
Suggestion: fmt.Sprintf(IssueCodeRelation.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref, relation.FullRelation, dm.Language, relation.Identifier),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}
}

if dm.Ingredients != nil {
doneIngredientTitle := false
for _, ingredient := range dm.Ingredients {
// Acts, Numbers and Deuteronomy are only in English and not other languages, so using those
if !doneIngredientTitle && (ingredient.Title == "" || (dm.Language != "en" && (ingredient.Title == "Numbers" || ingredient.Title == "Deuteronomy" || ingredient.Title == "Acts"))) {
doneIngredientTitle = true
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeIngredientTitle,
SeverityLevel: SeverityLevelError,
Details: fmt.Sprintf(IssueCodeIngredientTitle.IssueDetailsFormatString(), ingredient.Identifier, ingredient.Title),
Suggestion: fmt.Sprintf(IssueCodeIngredientTitle.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref, ingredient.Title),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}

if !ingredient.Exists {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeIngredientMissing,
SeverityLevel: SeverityLevelError,
Details: fmt.Sprintf(IssueCodeIngredientMissing.IssueDetailsFormatString(), ingredient.Identifier, ingredient.Path),
Suggestion: fmt.Sprintf(IssueCodeIngredientMissing.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref, ingredient.Identifier, ingredient.Path),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}

if ingredient.Exists && ingredient.Size == 0 && !ingredient.IsDir {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeIngredientEmpty,
SeverityLevel: SeverityLevelError,
Details: fmt.Sprintf(IssueCodeIngredientEmpty.IssueDetailsFormatString(), ingredient.Identifier, ingredient.Path),
Suggestion: fmt.Sprintf(IssueCodeIngredientEmpty.IssueSuggestionFormatString(), dm.Repo.Link(), dm.Ref, ingredient.Identifier, ingredient.Path),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
issues = append(issues, item)
}
}
}

healthcheckGroupedIssues := NewHealthcheckGroupedIssues(issues)
fmt.Printf("dm.Ref: %v\n", dm.Ref)
fmt.Printf("dm.Repo.DefaultBranch: %v\n", dm.Repo.DefaultBranch)
fmt.Printf("healthcheckGroupedIssues.SeverityLevelCount[SeverityLevelError]: %v\n", healthcheckGroupedIssues.SeverityLevelCount[SeverityLevelError])
fmt.Printf("healthcheckGroupedIssues.SeverityLevelCount: %v\n", healthcheckGroupedIssues.SeverityLevelCount)
if dm.Ref == dm.Repo.DefaultBranch {
if healthcheckGroupedIssues.SeverityLevelCount[SeverityLevelError] > 0 {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeReleaseNeeded,
SeverityLevel: SeverityLevelError,
Details: IssueCodeReleaseNeeded.IssueDetailsFormatString(),
Suggestion: "Fix all the errors above. Then make a release with [gatewayAdmin](https://gateway-admin.netlify.app/).",
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
healthcheckGroupedIssues.AddIssue(item)
} else {
dm.LoadRepo(ctx)
err := dm.Repo.LoadLatestDMs(ctx)
if err != nil {
return nil, err
}
var releaseHealthcheckGroupedIssues *HealthcheckGroupedIssues
if dm.Repo.LatestProdDM != nil {
if dm.Repo.LatestProdDM.HealthcheckUnix == 0 {
var err error
if releaseHealthcheckGroupedIssues, err = PerformHealthcheck(ctx, dm.Repo.LatestProdDM); err != nil {
return nil, err
}
} else {
releaseHealthcheckGroupedIssues, err = GetHealthcheckGroupedIssues(ctx, dm.Repo.LatestProdDM.ID)
if err != nil {
return nil, err
}
}
}

if healthcheckGroupedIssues.SeverityLevelCount[SeverityLevelError] == 0 && releaseHealthcheckGroupedIssues != nil && releaseHealthcheckGroupedIssues.SeverityLevelCount[SeverityLevelError] > 0 {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeReleaseNeeded,
SeverityLevel: SeverityLevelError,
Details: IssueCodeReleaseNeeded.IssueDetailsFormatString(),
Suggestion: fmt.Sprintf(IssueCodeReleaseNeeded.IssueSuggestionFormatString(), "all", dm.Ref, SeverityLevelError.String()),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
healthcheckGroupedIssues.AddIssue(item)
} else if releaseHealthcheckGroupedIssues != nil && healthcheckGroupedIssues.SeverityLevelCount[SeverityLevelWarning] < releaseHealthcheckGroupedIssues.SeverityLevelCount[SeverityLevelWarning] {
item := &Door43HealthcheckIssue{
Door43MetadataID: dm.ID,
IssueCode: IssueCodeReleaseNeeded,
SeverityLevel: SeverityLevelInfo,
Details: IssueCodeReleaseNeeded.IssueDetailsFormatString(),
Suggestion: fmt.Sprintf(IssueCodeReleaseNeeded.IssueSuggestionFormatString(), "some or all", dm.Ref, SeverityLevelWarning.String()),
Current: true,
}
if _, err := db.GetEngine(ctx).Insert(item); err != nil {
return nil, err
}
healthcheckGroupedIssues.AddIssue(item)
}
}
}

dm.HealthcheckUnix = timeutil.TimeStampNow()
if _, err := db.GetEngine(ctx).ID(dm.ID).Cols("healthcheck_unix").Update(dm); err != nil {
return nil, err
}

return healthcheckGroupedIssues, nil
}
11 changes: 6 additions & 5 deletions models/repo/door43metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ type Door43Metadata struct {
IsRepoMetadata bool `xorm:"INDEX NOT NULL DEFAULT false"`
Metadata map[string]interface{} `xorm:"JSON MEDIUMTEXT"`
ValidationError *jsonschema.ValidationError `xorm:"JSON MEDIUMTEXT"`
HealthcheckIssues []*Door43HealthcheckIssue `xorm:"-"`
Healthcheck *HealthcheckGroupedIssues `xorm:"-"`
ReleaseDateUnix timeutil.TimeStamp `xorm:"NOT NULL"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created NOT NULL"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
HealthchckUnix timeutil.TimeStamp `xorm:"INDEX"`
HealthcheckUnix timeutil.TimeStamp `xorm:"INDEX"`
}

func init() {
Expand Down Expand Up @@ -121,13 +121,13 @@ func (dm *Door43Metadata) LoadRelease(ctx context.Context) error {
return nil
}

func (dm *Door43Metadata) LoadHealthcheckIssues(ctx context.Context) error {
if dm.HealthcheckIssues == nil && dm.HealthchckUnix > 0 {
func (dm *Door43Metadata) LoadHealthcheck(ctx context.Context) error {
if dm.HealthcheckUnix > 0 {
issues, err := GetDoor43HealthcheckIssuesByDoor43MetadataID(ctx, dm.ID)
if err != nil {
return err
}
dm.HealthcheckIssues = issues
dm.Healthcheck = NewHealthcheckGroupedIssues(issues)
}
return nil
}
Expand All @@ -143,6 +143,7 @@ func (dm *Door43Metadata) LoadAttributes(ctx context.Context) error {
return nil
}
}
dm.LoadHealthcheck(ctx)
return nil
}

Expand Down
5 changes: 5 additions & 0 deletions models/repo/repo_dcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ func (repo *Repository) LoadLatestDMs(ctx context.Context) error {
return err
}
if has && dm != nil {
dm.Repo = repo
dm.LoadAttributes(ctx)
repo.LatestProdDM = dm
}
}
Expand All @@ -45,6 +47,7 @@ func (repo *Repository) LoadLatestDMs(ctx context.Context) error {
return err
}
if has && dm != nil {
dm.Repo = repo
repo.LatestPreprodDM = dm
}
}
Expand All @@ -62,6 +65,7 @@ func (repo *Repository) LoadLatestDMs(ctx context.Context) error {
return err
}
if has && dm != nil {
dm.Repo = repo
repo.DefaultBranchDM = dm
}
}
Expand Down Expand Up @@ -89,6 +93,7 @@ func (repo *Repository) LoadLatestDMs(ctx context.Context) error {
langIsGL := dcs.LanguageIsGL(lang)
repo.RepoDM = &Door43Metadata{
RepoID: repo.ID,
Repo: repo,
MetadataType: metadataType,
MetadataVersion: metadataVersion,
Title: title,
Expand Down
26 changes: 13 additions & 13 deletions routers/web/dcs/catalog.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

/*** DCS Customizations - Router for Catalog page ***/
/*** DCS Customizations - Router for Healthcheck page ***/

package dcs

Expand All @@ -18,18 +18,18 @@ import (
)

const (
// tplCatalog catalog page template.
tplCatalog base.TplName = "catalog/catalog"
// tplHealthcheck healthcheck page template.
tplHealthcheck base.TplName = "catalog/catalog"
)

// CatalogSearchOptions when calling search catalog
type CatalogSearchOptions struct {
// HealthcheckOptions when calling healthcheck
type HealthcheckOptions struct {
PageSize int
TplName base.TplName
}

// RenderCatalogSearch render catalog search page
func RenderCatalogSearch(ctx *context.Context, opts *CatalogSearchOptions) {
// RenderHealthSearch render healthcheck search page
func RenderHealthcheckSearch(ctx *context.Context, opts *HealthcheckOptions) {
page := ctx.FormInt("page")
if page <= 0 {
page = 1
Expand Down Expand Up @@ -166,14 +166,14 @@ func RenderCatalogSearch(ctx *context.Context, opts *CatalogSearchOptions) {
ctx.HTML(200, opts.TplName)
}

// Catalog render catalog page
func Catalog(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("catalog")
ctx.Data["PageIsCatalog"] = true
// Healthcheck render healthcheck page
func Healthcheck(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("healthcheck")
ctx.Data["PageIsHealtcheck"] = true
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled

RenderCatalogSearch(ctx, &CatalogSearchOptions{
RenderHealthcheckSearch(ctx, &HealthcheckOptions{
PageSize: setting.UI.ExplorePagingNum,
TplName: tplCatalog,
TplName: tplHealthcheck,
})
}
Loading

0 comments on commit 34390b0

Please sign in to comment.