Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct ProposalLinkExtractor: MarkupWalker, ValueExtractor {
if let headerField = source["Proposal"] {
visit(headerField)
} else {
errors.append(.missingProposalIDLink)
errors.append(.missingProposalField)
}
if let proposalLink {

Expand Down
177 changes: 115 additions & 62 deletions Sources/EvolutionMetadataExtraction/Utilities/ValidationIssues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,148 +12,201 @@ import EvolutionMetadataModel
// VALIDATION ENHANCEMENTS: After validation enhancements, consider moving the full list of known issues to EvolutionMetadataModel as an extension to Proposal.Issue. Possibly then add ValidationIssue as a typealias.

extension Proposal.Issue {
// MARK: - Parse Errors

// MARK: - Document-Level Errors
// VALIDATION ENHANCEMENTS: Consider making a stronger 'unable to fetch or read proposal' statement
static let proposalContainsNoContent = Proposal.Issue(
kind: .error,
code: 1,
message: "Proposal contains no content."
)

static let emptyMarkdownFile = Proposal.Issue(
kind: .error,
code: 2,
message: "Proposal Markdown file is empty."
)

static let missingMetadataFields = Proposal.Issue(
kind: .error,
code: 3,
message: "Missing list of metadata fields."
)

// MARK: - Heading Errors

// MARK: - Title
// TODO: title missing = 10
// TODO: title wrong heading level = 11

static let missingOrInvalidStatus = Proposal.Issue(
// MARK: - Summary of changes
// TODO: summary missing = 20
// TODO: summary wrong heading level = 21
// TODO: summary too long = 22
// TODO: summary multiple paragraphs = 23

// MARK: - Header Field Errors

// MARK: - Proposal
static let missingProposalField = Proposal.Issue(
kind: .error,
message: "Missing or invalid proposal status."
code: 30,
message: "Missing proposal field."
)
// How different from missingStatus?

static let missingProposalIDLink = Proposal.Issue(
kind: .error,
code: 31,
message: "Missing proposal ID link (SE-NNNN)[NNNN-filename.md]."
)

static let proposalIDWrongDigitCount = Proposal.Issue(
kind: .error,
code: 32,
message: "Proposal ID must include four decimal digits."
)

static let missingAuthors = Proposal.Issue(
kind: .error,
message: "Missing author(s)."
static let proposalIDHasExtraMarkup = Proposal.Issue(
kind: .warning,
code: 33,
message: "Proposal ID contains extra markup; expected a link with plaintext contents."
)

static let authorsHaveExtraMarkup = Proposal.Issue(
kind: .error,
message: "Author name contains extra markup; expected a link with plaintext contents."
)

static let upcomingFeatureFlagExtractionFailure = Proposal.Issue(
kind: .error,
message: "Failed to extract upcoming feature flag."
)

static let previousProposalIDsExtractionFailure = Proposal.Issue(
static let invalidProposalIDLink = Proposal.Issue(
kind: .error,
message: "Failed to extract previous proposal IDs."
code: 34,
message: "Proposal ID link must be a relative link (SE-NNNN)[NNNN-filename.md]."
)

static let missingReviewField = Proposal.Issue(
static let reservedProposalID = Proposal.Issue(
kind: .error,
message: "Missing Review field."
code: 34,
message: "Missing valid proposal ID; SE-0000 is reserved."
)

static let discussionExtractionFailure = Proposal.Issue(
// MARK: - Author
static let missingAuthors = Proposal.Issue(
kind: .error,
message: "Failed to extract discussions from Review field."
)

// MARK: - Parse Warnings

// VALIDATION ENHANCEMENT: Why is this only a warning?
static let missingStatus = Proposal.Issue(
kind: .warning,
message: "Status not found in the proposal's details list."
code: 40,
message: "Missing author(s)."
)

static let missingImplementedVersion = Proposal.Issue(
kind: .warning,
message: "Missing Swift version number for an implemented proposal."
static let authorsHaveExtraMarkup = Proposal.Issue(
kind: .error,
code: 41,
message: "Author name contains extra markup; expected a link with plaintext contents."
)

static let missingOrInvalidReviewDates = Proposal.Issue(
static let authorMissingProfileLink = Proposal.Issue(
kind: .warning,
message: "Missing or invalid dates for a review period."
code: 42,
message: "Author missing link."
)

static let proposalIDHasExtraMarkup = Proposal.Issue(
static let invalidAuthorLink = Proposal.Issue(
kind: .warning,
message: "Proposal ID contains extra markup; expected a link with plaintext contents."
code: 43,
message: "Author's link doesn't refer to a GitHub profile. Link removed."
)

// MARK: - Review Manager
static let missingReviewManagers = Proposal.Issue(
kind: .warning,
code: 50,
message: "Missing review manager(s)."
)

static let multipleReviewManagers = Proposal.Issue(
kind: .warning,
code: 51,
message: "Multiple review managers listed without profile links."
)

static let reviewManagerMissingProfileLink = Proposal.Issue(
kind: .warning,
code: 52,
message: "Review manager missing profile link."
)

static let authorMissingProfileLink = Proposal.Issue(
static let invalidReviewManagerLink = Proposal.Issue(
kind: .warning,
message: "Author missing link."
)

// MARK: - Validation Errors

static let invalidProposalIDLink = Proposal.Issue(
kind: .error,
message: "Proposal ID link must be a relative link (SE-NNNN)[NNNN-filename.md]."
code: 53,
message: "Review manager's link doesn't refer to a GitHub profile. Link removed."
)

static let reservedProposalID = Proposal.Issue(
kind: .error,
message: "Missing valid proposal ID; SE-0000 is reserved."
// MARK: - Status
// VALIDATION ENHANCEMENT: Why is this only a warning?
static let missingStatus = Proposal.Issue(
kind: .warning,
code: 60,
message: "Status not found in the proposal's details list."
)

static let malformedUpcomingFeatureFlag = Proposal.Issue(
// How different from missingStatus?
static let missingOrInvalidStatus = Proposal.Issue(
kind: .error,
message: "Upcoming feature flag should not contain whitespace."
code: 61,
message: "Missing or invalid proposal status."
)

// MARK: - Validation Warnings

static let invalidAuthorLink = Proposal.Issue(
static let missingImplementedVersion = Proposal.Issue(
kind: .warning,
message: "Author's link doesn't refer to a GitHub profile. Link removed."
code: 62,
message: "Missing Swift version number for an implemented proposal."
)

static let invalidReviewManagerLink = Proposal.Issue(
static let missingOrInvalidReviewDates = Proposal.Issue(
kind: .warning,
message: "Review manager's link doesn't refer to a GitHub profile. Link removed."
code: 63,
message: "Missing or invalid dates for a review period."
)

// MARK: - Bugs
// TODO: malformed bug = 70

// MARK: - Implementation
static let invalidImplementationLink = Proposal.Issue(
kind: .warning,
code: 80,
message: "Implementation links to a non-Swift repository."
)


// MARK: - Upcoming Feature Flag
static let upcomingFeatureFlagExtractionFailure = Proposal.Issue(
kind: .error,
code: 90,
message: "Failed to extract upcoming feature flag."
)

static let malformedUpcomingFeatureFlag = Proposal.Issue(
kind: .error,
code: 91,
message: "Upcoming feature flag should not contain whitespace."
)

// MARK: - Previous Proposal
static let previousProposalIDsExtractionFailure = Proposal.Issue(
kind: .error,
code: 100,
message: "Failed to extract previous proposal IDs."
)

// MARK: - Review
static let missingReviewField = Proposal.Issue(
kind: .error,
code: 110,
message: "Missing Review field."
)

static let discussionExtractionFailure = Proposal.Issue(
kind: .error,
code: 111,
message: "Failed to extract discussions from Review field."
)

static let invalidDiscussionLink = Proposal.Issue(
kind: .warning,
code: 112,
message: "Discussion link doesn't refer to a Swift forum thread. Discussion removed."
)

Expand Down
Loading