diff --git a/Sources/App/Commands/Ingest.swift b/Sources/App/Commands/Ingest.swift index 311915592..7bf64744f 100644 --- a/Sources/App/Commands/Ingest.swift +++ b/Sources/App/Commands/Ingest.swift @@ -193,6 +193,7 @@ func updateRepository(on database: Database, repository.defaultBranch = repoMetadata.defaultBranch repository.forks = repoMetadata.forkCount repository.fundingLinks = repoMetadata.fundingLinks?.compactMap(FundingLink.init(from:)) ?? [] + repository.hasSPIBadge = readmeInfo?.containsSPIBadge() repository.homepageUrl = repoMetadata.homepageUrl?.trimmed repository.isArchived = repoMetadata.isArchived repository.isInOrganization = repoMetadata.isInOrganization diff --git a/Sources/App/Core/Github.swift b/Sources/App/Core/Github.swift index ef91bcabe..8bccce4f2 100644 --- a/Sources/App/Core/Github.swift +++ b/Sources/App/Core/Github.swift @@ -248,6 +248,10 @@ extension Github { var originalUrl: String var s3Key: S3Store.Key } + + func containsSPIBadge() -> Bool { + html.contains("https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com") + } } struct Metadata: Decodable, Equatable { diff --git a/Sources/App/Migrations/082/UpdateRepositoryAddHasSPIBadge.swift b/Sources/App/Migrations/082/UpdateRepositoryAddHasSPIBadge.swift new file mode 100644 index 000000000..1925f227a --- /dev/null +++ b/Sources/App/Migrations/082/UpdateRepositoryAddHasSPIBadge.swift @@ -0,0 +1,29 @@ +// Copyright Dave Verwer, Sven A. Schmidt, and other contributors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Fluent + +struct UpdateRepositoryAddHasSPIBadge: AsyncMigration { + func prepare(on database: Database) async throws { + try await database.schema("repositories") + .field("has_spi_badge", .bool) + .update() + } + + func revert(on database: Database) async throws { + try await database.schema("repositories") + .deleteField("has_spi_badge") + .update() + } +} diff --git a/Sources/App/Models/Repository.swift b/Sources/App/Models/Repository.swift index 1b252f83b..cee66ba7c 100644 --- a/Sources/App/Models/Repository.swift +++ b/Sources/App/Models/Repository.swift @@ -69,6 +69,9 @@ final class Repository: @unchecked Sendable, Model, Content { @Field(key: "is_in_organization") var isInOrganization: Bool + @Field(key: "has_spi_badge") + var hasSPIBadge: Bool? + @Field(key: "keywords") var keywords: [String] diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift index 98e15cd3d..173f3d935 100644 --- a/Sources/App/configure.swift +++ b/Sources/App/configure.swift @@ -344,6 +344,9 @@ public func configure(_ app: Application) async throws -> String { app.migrations.add(CreateCustomCollection()) app.migrations.add(CreateCustomCollectionPackage()) } + do { // Migration 082 - Add `has_spi_badge` to `repositories` + app.migrations.add(UpdateRepositoryAddHasSPIBadge()) + } app.asyncCommands.use(Analyze.Command(), as: "analyze") app.asyncCommands.use(CreateRestfileCommand(), as: "create-restfile") diff --git a/Tests/AppTests/GithubTests.swift b/Tests/AppTests/GithubTests.swift index 24cd24cee..f8613d740 100644 --- a/Tests/AppTests/GithubTests.swift +++ b/Tests/AppTests/GithubTests.swift @@ -459,4 +459,21 @@ class GithubTests: AppTestCase { XCTAssertEqual(originalReadme, readme) XCTAssertEqual(images, []) } + + func test_Readme_containsSPIBadge() throws { + do { + let html = """ +

+

+

🏷 SemanticVersion

+ """ + let readme = Github.Readme(html: html, htmlUrl: "url", imagesToCache: []) + XCTAssertTrue(readme.containsSPIBadge()) + } + do { + let readme = Github.Readme(html: "some html", htmlUrl: "url", imagesToCache: []) + XCTAssertFalse(readme.containsSPIBadge()) + } + } + } diff --git a/Tests/AppTests/IngestorTests.swift b/Tests/AppTests/IngestorTests.swift index 16acd3044..ff8f89e59 100644 --- a/Tests/AppTests/IngestorTests.swift +++ b/Tests/AppTests/IngestorTests.swift @@ -158,7 +158,7 @@ class IngestorTests: AppTestCase { metadata: md, licenseInfo: .init(htmlUrl: "license url"), readmeInfo: .init(etag: "etag", - html: "readme html", + html: "readme html https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com", htmlUrl: "readme html url", imagesToCache: []), s3Readme: .cached(s3ObjectUrl: "url", githubEtag: "etag"), @@ -177,6 +177,7 @@ class IngestorTests: AppTestCase { .init(platform: .customUrl, url: "https://example.com/username1"), .init(platform: .customUrl, url: "https://example.com/username2") ]) + XCTAssertEqual(repo.hasSPIBadge, true) XCTAssertEqual(repo.homepageUrl, "https://swiftpackageindex.com/Alamofire/Alamofire") XCTAssertEqual(repo.isInOrganization, true) XCTAssertEqual(repo.keywords, ["bar", "baz", "foo"])