forked from
tangled.org/core
Monorepo for Tangled
1package validator
2
3import (
4 "database/sql"
5 "fmt"
6 "strings"
7
8 "tangled.org/core/appview/db"
9 "tangled.org/core/appview/models"
10 "tangled.org/core/orm"
11 "tangled.org/core/patchutil"
12)
13
14func (v *Validator) ValidatePull(pull *models.Pull) error {
15 if len(pull.Submissions) == 0 {
16 return fmt.Errorf("pull must have at least one submission")
17 }
18
19 latestSubmission := pull.LatestSubmission()
20 if latestSubmission == nil {
21 return fmt.Errorf("pull must have a valid latest submission")
22 }
23
24 isFormatPatch := patchutil.IsFormatPatch(latestSubmission.Patch)
25
26 // title and body can only be empty if the patch is a format-patch
27 if !isFormatPatch {
28 if pull.Title == "" {
29 return fmt.Errorf("pull title is empty (required for non-format-patch pulls)")
30 }
31
32 if pull.Body == "" {
33 return fmt.Errorf("pull body is empty (required for non-format-patch pulls)")
34 }
35
36 if st := strings.TrimSpace(v.sanitizer.SanitizeDescription(pull.Title)); st == "" {
37 return fmt.Errorf("title is empty after HTML sanitization")
38 }
39
40 if sb := strings.TrimSpace(v.sanitizer.SanitizeDefault(pull.Body)); sb == "" {
41 return fmt.Errorf("body is empty after HTML sanitization")
42 }
43 }
44
45 // the dependent_on should not form a DAG, aka, two PRs should not have the same dependent
46 if pull.DependentOn != nil {
47 dependentPull, err := db.GetPull(
48 v.db,
49 orm.FilterEq("dependent_on", pull.DependentOn.String()),
50 )
51
52 if err == sql.ErrNoRows {
53 return nil
54 }
55
56 if err != nil {
57 return fmt.Errorf("failed to fetch pulls with same dependency: %w", err)
58 }
59
60 if dependentPull.AtUri() == pull.AtUri() {
61 return nil
62 }
63
64 return fmt.Errorf("another pull already depends on %s, which would form a DAG, this is presently disallowed", pull.DependentOn.String())
65 }
66
67 return nil
68}