From c55572e192960171e425dcc06b89c6053a7b841d Mon Sep 17 00:00:00 2001 From: Antoine van der Lee Date: Thu, 5 May 2022 11:14:00 +0200 Subject: [PATCH 1/7] Filter emojis out of changelog --- Sources/GitBuddyCore/Commands/ReleaseCommand.swift | 5 +++++ Sources/GitBuddyCore/Models/ChangelogItem.swift | 10 ++++++++++ .../GitBuddyTests/GitHub/PullRequestFetcherTests.swift | 2 +- Tests/GitBuddyTests/Models/ChangelogItemTests.swift | 4 ++-- Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift | 2 +- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Sources/GitBuddyCore/Commands/ReleaseCommand.swift b/Sources/GitBuddyCore/Commands/ReleaseCommand.swift index fe84bd5..0af2ea8 100644 --- a/Sources/GitBuddyCore/Commands/ReleaseCommand.swift +++ b/Sources/GitBuddyCore/Commands/ReleaseCommand.swift @@ -21,21 +21,26 @@ struct ReleaseCommand: ParsableCommand { @Flag(name: [.customLong("use-pre-release"), .customShort("p")], help: "Create the release as a pre-release.") var isPrerelease: Bool = false + // Main @Option(name: .shortAndLong, help: "Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA. Unused if the Git tag already exists. Default: the repository's default branch (usually main).") var targetCommitish: String? + // 1.3.1b1072 @Option(name: [.long, .customShort("n")], help: "The name of the tag. If set, `changelogToTag` is required too. Default: takes the last created tag to publish as a GitHub release.") var tagName: String? + // // 1.3.1b1072 - App Store Release @Option(name: .shortAndLong, help: "The title of the release. Default: uses the tag name.") var releaseTitle: String? + // 1.3.0b1039 @Option(name: .shortAndLong, help: "The last release tag to use as a base for the changelog creation. Default: previous tag.") var lastReleaseTag: String? @Option(name: .customLong("changelogToTag"), help: "If set, the date of this tag will be used as the limit for the changelog creation. This variable should be passed when `tagName` is set. Default: latest tag.") var changelogToTag: String? + // Develop @Option(name: .shortAndLong, help: "The base branch to compare with for generating the changelog. Defaults to master.") var baseBranch: String? diff --git a/Sources/GitBuddyCore/Models/ChangelogItem.swift b/Sources/GitBuddyCore/Models/ChangelogItem.swift index 55b24fb..aef1efc 100644 --- a/Sources/GitBuddyCore/Models/ChangelogItem.swift +++ b/Sources/GitBuddyCore/Models/ChangelogItem.swift @@ -34,6 +34,8 @@ struct ChangelogItem { var title: String? { guard var title = input.title else { return nil } title = title.prefix(1).uppercased() + title.dropFirst() + title = title.removingEmojis().trimmingCharacters(in: .whitespaces) + if let htmlURL = input.htmlURL { title += " ([#\(input.number)](\(htmlURL)))" } @@ -43,3 +45,11 @@ struct ChangelogItem { return title } } + +private extension String { + func removingEmojis() -> String { + String(unicodeScalars.filter { + !$0.properties.isEmojiPresentation + }) + } +} diff --git a/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift b/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift index b30112a..d7b4ed9 100644 --- a/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift +++ b/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift @@ -36,7 +36,7 @@ final class PullRequestFetcherTests: XCTestCase { let fetcher = PullRequestFetcher(octoKit: octoKit, baseBranch: "master", project: project) let pullRequests = try fetcher.fetchAllBetween(release.created, and: Date(), using: urlSession) XCTAssertEqual(pullRequests.count, 2) - XCTAssertEqual(pullRequests[0].title, "Add charset utf-8 to html head") + XCTAssertEqual(pullRequests[0].title, "Add charset utf-8 to html head 🫥") XCTAssertEqual(pullRequests[1].title, "Fix warning occurring in pod library because of importing style.css #trivial") } diff --git a/Tests/GitBuddyTests/Models/ChangelogItemTests.swift b/Tests/GitBuddyTests/Models/ChangelogItemTests.swift index 0b0e419..bb7eb5b 100644 --- a/Tests/GitBuddyTests/Models/ChangelogItemTests.swift +++ b/Tests/GitBuddyTests/Models/ChangelogItemTests.swift @@ -42,7 +42,7 @@ final class ChangelogItemTests: XCTestCase { let input = PullRequestsJSON.data(using: .utf8)!.mapJSON(to: [PullRequest].self).first! input.htmlURL = nil let item = ChangelogItem(input: input, closedBy: input) - XCTAssertEqual(item.title, "\(input.title!) via [@AvdLee](https://github.com/AvdLee)") + XCTAssertEqual(item.title, "Add charset utf-8 to html head via [@AvdLee](https://github.com/AvdLee)") } /// It should fallback to the assignee if the user is nil for Pull Requests. @@ -53,7 +53,7 @@ final class ChangelogItemTests: XCTestCase { let item = ChangelogItem(input: input, closedBy: input) XCTAssertEqual( item.title, - "\(input.title!) via [@kairadiagne](https://github.com/kairadiagne)" + "Add charset utf-8 to html head via [@kairadiagne](https://github.com/kairadiagne)" ) } diff --git a/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift b/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift index e25491b..53d6aec 100644 --- a/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift @@ -21,7 +21,7 @@ let PullRequestsJSON = """ "number": 50, "state": "closed", "locked": false, - "title": "Add charset utf-8 to html head", + "title": "Add charset utf-8 to html head 🫥", "user": { "login": "AvdLee", "id": 793147, From fd0598865716187ec8fdc8ecf11f9d2231dc883d Mon Sep 17 00:00:00 2001 From: Antoine van der Lee Date: Thu, 5 May 2022 11:29:00 +0200 Subject: [PATCH 2/7] Update CI --- Submodules/WeTransfer-iOS-CI | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Submodules/WeTransfer-iOS-CI b/Submodules/WeTransfer-iOS-CI index 9d07bc5..86c9e6e 160000 --- a/Submodules/WeTransfer-iOS-CI +++ b/Submodules/WeTransfer-iOS-CI @@ -1 +1 @@ -Subproject commit 9d07bc5e7c23c7ccfe40840d5b369c2257734d72 +Subproject commit 86c9e6e0d723288ead32a0af9eb0367f5388f3b1 From b07f38613032b78156be87802d3895c6cb8d29ce Mon Sep 17 00:00:00 2001 From: Antoine van der Lee Date: Thu, 5 May 2022 11:43:20 +0200 Subject: [PATCH 3/7] Also add an emoji to the issue example --- Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift b/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift index 91f4592..374c271 100644 --- a/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift @@ -777,7 +777,7 @@ let IssuesJSON = #""" "id": 545013288, "node_id": "MDExOlB1bGxSZXF1ZXN0MzU5MDA1MjAz", "number": 50, - "title": "Add charset utf-8 to html head", + "title": "Add charset utf-8 to html head 🫥", "user": { "login": "intitni", "id": 793147, From 31c851b8561278f65184ae111b108d6fc677d6d1 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee Date: Thu, 5 May 2022 12:04:39 +0200 Subject: [PATCH 4/7] use a different emoji --- Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift | 2 +- Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift | 2 +- Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift b/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift index d7b4ed9..9c05e6a 100644 --- a/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift +++ b/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift @@ -36,7 +36,7 @@ final class PullRequestFetcherTests: XCTestCase { let fetcher = PullRequestFetcher(octoKit: octoKit, baseBranch: "master", project: project) let pullRequests = try fetcher.fetchAllBetween(release.created, and: Date(), using: urlSession) XCTAssertEqual(pullRequests.count, 2) - XCTAssertEqual(pullRequests[0].title, "Add charset utf-8 to html head 🫥") + XCTAssertEqual(pullRequests[0].title, "Add charset utf-8 to html head 😃") XCTAssertEqual(pullRequests[1].title, "Fix warning occurring in pod library because of importing style.css #trivial") } diff --git a/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift b/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift index 374c271..63723b2 100644 --- a/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift @@ -777,7 +777,7 @@ let IssuesJSON = #""" "id": 545013288, "node_id": "MDExOlB1bGxSZXF1ZXN0MzU5MDA1MjAz", "number": 50, - "title": "Add charset utf-8 to html head 🫥", + "title": "Add charset utf-8 to html head 😃", "user": { "login": "intitni", "id": 793147, diff --git a/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift b/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift index 53d6aec..75a865a 100644 --- a/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift @@ -21,7 +21,7 @@ let PullRequestsJSON = """ "number": 50, "state": "closed", "locked": false, - "title": "Add charset utf-8 to html head 🫥", + "title": "Add charset utf-8 to html head 😃", "user": { "login": "AvdLee", "id": 793147, From fc1cd1f8e31160926d85bad518040056bdbbe3dc Mon Sep 17 00:00:00 2001 From: Antoine van der Lee Date: Thu, 5 May 2022 12:22:42 +0200 Subject: [PATCH 5/7] Fix SwiftLint issues --- Sources/GitBuddyCore/Models/Changelog.swift | 2 +- .../GitBuddyCore/Models/ChangelogItem.swift | 2 +- .../GitHub/IssueResolverTests.swift | 20 +++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Sources/GitBuddyCore/Models/Changelog.swift b/Sources/GitBuddyCore/Models/Changelog.swift index d380362..ff9a733 100644 --- a/Sources/GitBuddyCore/Models/Changelog.swift +++ b/Sources/GitBuddyCore/Models/Changelog.swift @@ -50,7 +50,7 @@ struct SectionedChangelog: Changelog { let description: String let itemIdentifiers: [PullRequestID: [IssueID]] - + init(issues: [Issue], pullRequests: [PullRequest]) { description = """ diff --git a/Sources/GitBuddyCore/Models/ChangelogItem.swift b/Sources/GitBuddyCore/Models/ChangelogItem.swift index aef1efc..3a63f2e 100644 --- a/Sources/GitBuddyCore/Models/ChangelogItem.swift +++ b/Sources/GitBuddyCore/Models/ChangelogItem.swift @@ -35,7 +35,7 @@ struct ChangelogItem { guard var title = input.title else { return nil } title = title.prefix(1).uppercased() + title.dropFirst() title = title.removingEmojis().trimmingCharacters(in: .whitespaces) - + if let htmlURL = input.htmlURL { title += " ([#\(input.number)](\(htmlURL)))" } diff --git a/Tests/GitBuddyTests/GitHub/IssueResolverTests.swift b/Tests/GitBuddyTests/GitHub/IssueResolverTests.swift index db6e335..637ba64 100644 --- a/Tests/GitBuddyTests/GitHub/IssueResolverTests.swift +++ b/Tests/GitBuddyTests/GitHub/IssueResolverTests.swift @@ -62,7 +62,7 @@ final class IssueResolverTests: XCTestCase { "Resolves", "resolved" ] - + let issueNumber = 4343 issueClosingKeywords.forEach { (closingKeyword) in @@ -70,13 +70,13 @@ final class IssueResolverTests: XCTestCase { XCTAssertEqual(description.resolvingIssues(), [issueNumber]) } } - + /// It should not extract anything if no issue number is found. func testResolvingNoReferencedIssue() { let description = examplePullRequestDescriptionUsing(closingKeyword: "fixes", issueNumber: nil) XCTAssertTrue(description.resolvingIssues().isEmpty) } - + /// It should not extract anything if no closing keyword is found. func testResolvingNoClosingKeyword() { let issueNumber = 4343 @@ -84,7 +84,7 @@ final class IssueResolverTests: XCTestCase { let description = examplePullRequestDescriptionUsing(closingKeyword: "", issueNumber: issueNumber) XCTAssertTrue(description.resolvingIssues().isEmpty) } - + /// It should extract mulitple issues. func testResolvingMultipleIssues() { let description = "This is a beautiful PR that close #123 for real. It also fixes #1 and fixes #2" @@ -92,31 +92,31 @@ final class IssueResolverTests: XCTestCase { XCTAssertEqual(resolvedIssues.count, 3) XCTAssertEqual(Set(description.resolvingIssues()), Set([123, 1, 2])) } - + /// It should deduplicate if the same issue is closed multiple times. func testResolvingMultipleIssuesDedup() { let description = "This is a beautiful PR that close #123 for real. It also fixes #123" XCTAssertEqual(description.resolvingIssues(), [123]) } - + /// It should not extract anything if there is no number after the #. func testResolvingNoNumber() { let description = "This is a beautiful PR that close # for real." XCTAssertTrue(description.resolvingIssues().isEmpty) } - + /// It should not extract anything if there is no number after the #, and it's at the end. func testResolvingNoNumberLast() { let description = "This is a beautiful PR that close #" XCTAssertTrue(description.resolvingIssues().isEmpty) } - + /// It should extract the issue if it's first. func testResolvingIssueFirst() { let description = "Resolves #123. Yay!" XCTAssertEqual(description.resolvingIssues(), [123]) } - + /// It should extract the issue if it's the only thing present. func testResolvingIssueOnly() { let description = "Resolved #123" @@ -127,7 +127,7 @@ final class IssueResolverTests: XCTestCase { extension IssueResolverTests { func examplePullRequestDescriptionUsing(closingKeyword: String, issueNumber: Int?) -> String { let issueNumberString = issueNumber?.description ?? "" - + return """ This PR does a lot of awesome stuff. It even closes some issues! From 470ca34114817cd4b35730fd2cef98153c3f7c62 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee Date: Thu, 5 May 2022 13:41:45 +0200 Subject: [PATCH 6/7] Fix SwiftFormat issue --- Package.swift | 2 +- .../Changelog/ChangelogItemsFactory.swift | 2 +- .../Changelog/ChangelogProducer.swift | 3 +-- .../Commands/ChangelogCommand.swift | 3 +-- Sources/GitBuddyCore/Commands/GitBuddy.swift | 4 ++-- .../Commands/ReleaseCommand.swift | 3 +-- .../Commands/TagDeletionsCommand.swift | 3 +-- .../GitBuddyCore/GitHub/IssuesFetcher.swift | 4 +--- .../GitBuddyCore/GitHub/IssuesResolver.swift | 5 ++--- .../GitHub/OctoKit+Authentication.swift | 1 - .../GitHub/PullRequestFetcher.swift | 4 +--- .../GitBuddyCore/Helpers/DateFormatters.swift | 2 +- .../Helpers/DependencyInjectors.swift | 2 +- Sources/GitBuddyCore/Helpers/Shell.swift | 6 ++--- Sources/GitBuddyCore/Models/Changelog.swift | 6 ++--- .../GitBuddyCore/Models/ChangelogItem.swift | 5 +++-- Sources/GitBuddyCore/Models/Tag.swift | 1 - Sources/GitBuddyCore/Models/Token.swift | 1 - .../Release/ReleaseProducer.swift | 5 ++--- .../Tag Deletions/TagsDeleter.swift | 7 +++--- .../Changelog/ChangelogCommandTests.swift | 12 +++++----- .../ChangelogItemsFactoryTests.swift | 8 +++---- .../GitBuddyTests/GitBuddyCommandTests.swift | 3 +-- .../GitBuddyTests/GitHub/CommenterTests.swift | 3 +-- .../GitHub/IssueResolverTests.swift | 22 +++++++++---------- .../GitHub/PullRequestFetcherTests.swift | 10 ++++----- .../Models/ChangelogItemTests.swift | 4 +--- .../Models/SingleSectionChangelogTests.swift | 3 +-- .../Release/ReleaseProducerTests.swift | 3 +-- .../Tag Deletions/TagsDeleterTests.swift | 5 ++--- .../TestHelpers/ListReleasesJSON.swift | 2 +- Tests/GitBuddyTests/TestHelpers/Mocks.swift | 7 +++--- .../TestHelpers/XCTestExtensions.swift | 5 ++--- Tests/GitBuddyTests/XCTestManifests.swift | 9 -------- 34 files changed, 63 insertions(+), 102 deletions(-) delete mode 100644 Tests/GitBuddyTests/XCTestManifests.swift diff --git a/Package.swift b/Package.swift index 8833c0e..44647ab 100644 --- a/Package.swift +++ b/Package.swift @@ -6,7 +6,7 @@ let package = Package( name: "GitBuddy", platforms: [ .macOS(.v10_15) - ], + ], products: [ .executable(name: "GitBuddy", targets: ["GitBuddy"]) ], diff --git a/Sources/GitBuddyCore/Changelog/ChangelogItemsFactory.swift b/Sources/GitBuddyCore/Changelog/ChangelogItemsFactory.swift index 01fa2aa..4e8c9a4 100644 --- a/Sources/GitBuddyCore/Changelog/ChangelogItemsFactory.swift +++ b/Sources/GitBuddyCore/Changelog/ChangelogItemsFactory.swift @@ -21,7 +21,7 @@ struct ChangelogItemsFactory { return [ChangelogItem(input: pullRequest, closedBy: pullRequest)] } return resolvedIssues.map { issue -> ChangelogItem in - return ChangelogItem(input: issue, closedBy: pullRequest) + ChangelogItem(input: issue, closedBy: pullRequest) } } } diff --git a/Sources/GitBuddyCore/Changelog/ChangelogProducer.swift b/Sources/GitBuddyCore/Changelog/ChangelogProducer.swift index 5b77fed..6b2daee 100644 --- a/Sources/GitBuddyCore/Changelog/ChangelogProducer.swift +++ b/Sources/GitBuddyCore/Changelog/ChangelogProducer.swift @@ -11,7 +11,6 @@ import OctoKit /// Capable of producing a changelog based on input parameters. final class ChangelogProducer: URLSessionInjectable { - enum Since { case date(date: Date) case tag(tag: String) @@ -32,7 +31,7 @@ final class ChangelogProducer: URLSessionInjectable { } } - private lazy var octoKit: Octokit = Octokit() + private lazy var octoKit: Octokit = .init() let baseBranch: Branch let since: Since let from: Date diff --git a/Sources/GitBuddyCore/Commands/ChangelogCommand.swift b/Sources/GitBuddyCore/Commands/ChangelogCommand.swift index 3b10165..62b4893 100644 --- a/Sources/GitBuddyCore/Commands/ChangelogCommand.swift +++ b/Sources/GitBuddyCore/Commands/ChangelogCommand.swift @@ -5,11 +5,10 @@ // Created by Antoine van der Lee on 09/04/2020. // -import Foundation import ArgumentParser +import Foundation struct ChangelogCommand: ParsableCommand { - public static let configuration = CommandConfiguration(commandName: "changelog", abstract: "Create a changelog for GitHub repositories") @Option(name: .shortAndLong, help: "The tag to use as a base. Defaults to the latest tag.") diff --git a/Sources/GitBuddyCore/Commands/GitBuddy.swift b/Sources/GitBuddyCore/Commands/GitBuddy.swift index e61ce6b..b8dc2ac 100644 --- a/Sources/GitBuddyCore/Commands/GitBuddy.swift +++ b/Sources/GitBuddyCore/Commands/GitBuddy.swift @@ -6,8 +6,8 @@ // Copyright © 2020 WeTransfer. All rights reserved. // -import Foundation import ArgumentParser +import Foundation /// Entry class of GitBuddy that registers commands and handles execution. public struct GitBuddy: ParsableCommand { @@ -20,5 +20,5 @@ public struct GitBuddy: ParsableCommand { subcommands: [ChangelogCommand.self, ReleaseCommand.self, TagDeletionsCommand.self] ) - public init() { } + public init() {} } diff --git a/Sources/GitBuddyCore/Commands/ReleaseCommand.swift b/Sources/GitBuddyCore/Commands/ReleaseCommand.swift index 0af2ea8..438ab26 100644 --- a/Sources/GitBuddyCore/Commands/ReleaseCommand.swift +++ b/Sources/GitBuddyCore/Commands/ReleaseCommand.swift @@ -5,11 +5,10 @@ // Created by Antoine van der Lee on 09/04/2020. // -import Foundation import ArgumentParser +import Foundation struct ReleaseCommand: ParsableCommand { - public static let configuration = CommandConfiguration(commandName: "release", abstract: "Create a new release including a changelog and publish comments on related issues.") @Option(name: .shortAndLong, help: "The path to the Changelog to update it with the latest changes.") diff --git a/Sources/GitBuddyCore/Commands/TagDeletionsCommand.swift b/Sources/GitBuddyCore/Commands/TagDeletionsCommand.swift index 40659cc..04a4ab7 100644 --- a/Sources/GitBuddyCore/Commands/TagDeletionsCommand.swift +++ b/Sources/GitBuddyCore/Commands/TagDeletionsCommand.swift @@ -1,8 +1,7 @@ -import Foundation import ArgumentParser +import Foundation struct TagDeletionsCommand: ParsableCommand { - public static let configuration = CommandConfiguration(commandName: "tagDeletion", abstract: "Delete a batch of tags based on given predicates.") @Option(name: .shortAndLong, help: "The date of this tag will be used as a limit. Defaults to the latest tag.") diff --git a/Sources/GitBuddyCore/GitHub/IssuesFetcher.swift b/Sources/GitBuddyCore/GitHub/IssuesFetcher.swift index f06c334..e09fb9b 100644 --- a/Sources/GitBuddyCore/GitHub/IssuesFetcher.swift +++ b/Sources/GitBuddyCore/GitHub/IssuesFetcher.swift @@ -9,7 +9,6 @@ import Foundation import OctoKit struct IssuesFetcher { - let octoKit: Octokit let project: GITProject @@ -20,7 +19,7 @@ struct IssuesFetcher { var result: Result<[Issue], Swift.Error>! - octoKit.issues(session, owner: project.organisation, repository: project.repository, state: .closed) { (response) in + octoKit.issues(session, owner: project.organisation, repository: project.repository, state: .closed) { response in switch response { case .success(let issues): result = .success(issues) @@ -42,5 +41,4 @@ struct IssuesFetcher { return closedAt > fromDate && closedAt < toDate } } - } diff --git a/Sources/GitBuddyCore/GitHub/IssuesResolver.swift b/Sources/GitBuddyCore/GitHub/IssuesResolver.swift index cd1091b..6f0991a 100644 --- a/Sources/GitBuddyCore/GitHub/IssuesResolver.swift +++ b/Sources/GitBuddyCore/GitHub/IssuesResolver.swift @@ -42,7 +42,6 @@ struct IssuesResolver { } extension String { - /// Extracts the resolved issues from a Pull Request body. func resolvingIssues() -> [Int] { var resolvedIssues = Set() @@ -69,8 +68,8 @@ extension String { guard index + 1 <= splits.count - 1 else { break } let nextSplit = splits[index + 1] - let numberPrefixString = nextSplit.prefix { (character) -> Bool in - return character.isNumber + let numberPrefixString = nextSplit.prefix { character -> Bool in + character.isNumber } if !numberPrefixString.isEmpty, let numberPrefix = Int(numberPrefixString.description) { diff --git a/Sources/GitBuddyCore/GitHub/OctoKit+Authentication.swift b/Sources/GitBuddyCore/GitHub/OctoKit+Authentication.swift index 35ed542..255018d 100644 --- a/Sources/GitBuddyCore/GitHub/OctoKit+Authentication.swift +++ b/Sources/GitBuddyCore/GitHub/OctoKit+Authentication.swift @@ -9,7 +9,6 @@ import Foundation import OctoKit extension Octokit { - static var protocolClasses: [AnyClass]? static var environment: [String: String] = ProcessInfo.processInfo.environment diff --git a/Sources/GitBuddyCore/GitHub/PullRequestFetcher.swift b/Sources/GitBuddyCore/GitHub/PullRequestFetcher.swift index 84139a4..73c7416 100644 --- a/Sources/GitBuddyCore/GitHub/PullRequestFetcher.swift +++ b/Sources/GitBuddyCore/GitHub/PullRequestFetcher.swift @@ -12,7 +12,6 @@ import OctoKit typealias Branch = String struct PullRequestFetcher { - let octoKit: Octokit let baseBranch: Branch let project: GITProject @@ -23,7 +22,7 @@ struct PullRequestFetcher { var result: Result<[PullRequest], Swift.Error>! - octoKit.pullRequests(session, owner: project.organisation, repository: project.repository, base: baseBranch, state: .closed, sort: .updated, direction: .desc) { (response) in + octoKit.pullRequests(session, owner: project.organisation, repository: project.repository, base: baseBranch, state: .closed, sort: .updated, direction: .desc) { response in switch response { case .success(let pullRequests): result = .success(pullRequests) @@ -39,5 +38,4 @@ struct PullRequestFetcher { return mergedAt > fromDate && mergedAt < toDate } } - } diff --git a/Sources/GitBuddyCore/Helpers/DateFormatters.swift b/Sources/GitBuddyCore/Helpers/DateFormatters.swift index c33fcfa..b93efd1 100644 --- a/Sources/GitBuddyCore/Helpers/DateFormatters.swift +++ b/Sources/GitBuddyCore/Helpers/DateFormatters.swift @@ -1,6 +1,6 @@ // // DateFormatters.swift -// +// // // Created by Antoine van der Lee on 25/01/2022. // Copyright © 2020 WeTransfer. All rights reserved. diff --git a/Sources/GitBuddyCore/Helpers/DependencyInjectors.swift b/Sources/GitBuddyCore/Helpers/DependencyInjectors.swift index c065750..8270b18 100644 --- a/Sources/GitBuddyCore/Helpers/DependencyInjectors.swift +++ b/Sources/GitBuddyCore/Helpers/DependencyInjectors.swift @@ -9,7 +9,7 @@ import Foundation /// Adds a `urlSession` property which defaults to `URLSession.shared`. -protocol URLSessionInjectable { } +protocol URLSessionInjectable {} extension URLSessionInjectable { var urlSession: URLSession { return URLSessionInjector.urlSession } diff --git a/Sources/GitBuddyCore/Helpers/Shell.swift b/Sources/GitBuddyCore/Helpers/Shell.swift index 249e586..ff87892 100644 --- a/Sources/GitBuddyCore/Helpers/Shell.swift +++ b/Sources/GitBuddyCore/Helpers/Shell.swift @@ -47,8 +47,8 @@ extension Process { guard let outputData = String(data: data, encoding: String.Encoding.utf8) else { return "" } return outputData - .reduce("") { (result, value) in - return result + String(value) + .reduce("") { result, value in + result + String(value) } .trimmingCharacters(in: .whitespacesAndNewlines) } @@ -65,7 +65,7 @@ private enum Shell: ShellExecuting { } /// Adds a `shell` property which defaults to `Shell.self`. -protocol ShellInjectable { } +protocol ShellInjectable {} extension ShellInjectable { static var shell: ShellExecuting.Type { ShellInjector.shell } diff --git a/Sources/GitBuddyCore/Models/Changelog.swift b/Sources/GitBuddyCore/Models/Changelog.swift index ff9a733..e82ab03 100644 --- a/Sources/GitBuddyCore/Models/Changelog.swift +++ b/Sources/GitBuddyCore/Models/Changelog.swift @@ -28,7 +28,7 @@ struct SingleSectionChangelog: Changelog { init(items: [ChangelogItem]) { description = ChangelogBuilder(items: items).build() - self.itemIdentifiers = items.reduce(into: [:], { (result, item) in + itemIdentifiers = items.reduce(into: [:]) { result, item in let pullRequestID: PullRequestID = item.closedBy.number if var pullRequestIssues = result[pullRequestID] { @@ -40,7 +40,7 @@ struct SingleSectionChangelog: Changelog { } else { result[pullRequestID] = [] } - }) + } } } @@ -63,7 +63,7 @@ struct SectionedChangelog: Changelog { \(ChangelogBuilder(items: pullRequests.map { ChangelogItem(input: $0, closedBy: $0) }).build()) """ - itemIdentifiers = pullRequests.reduce(into: [:]) { (result, item) in + itemIdentifiers = pullRequests.reduce(into: [:]) { result, item in result[item.number] = item.body?.resolvingIssues() } } diff --git a/Sources/GitBuddyCore/Models/ChangelogItem.swift b/Sources/GitBuddyCore/Models/ChangelogItem.swift index 3a63f2e..cc04d51 100644 --- a/Sources/GitBuddyCore/Models/ChangelogItem.swift +++ b/Sources/GitBuddyCore/Models/ChangelogItem.swift @@ -16,8 +16,9 @@ protocol ChangelogInput { var htmlURL: Foundation.URL? { get } var username: String? { get } } -protocol ChangelogIssue: ChangelogInput { } -protocol ChangelogPullRequest: ChangelogInput { } + +protocol ChangelogIssue: ChangelogInput {} +protocol ChangelogPullRequest: ChangelogInput {} extension PullRequest: ChangelogPullRequest { var username: String? { user?.login ?? assignee?.login } diff --git a/Sources/GitBuddyCore/Models/Tag.swift b/Sources/GitBuddyCore/Models/Tag.swift index 6230dda..df7e3fd 100644 --- a/Sources/GitBuddyCore/Models/Tag.swift +++ b/Sources/GitBuddyCore/Models/Tag.swift @@ -21,7 +21,6 @@ struct Tag: ShellInjectable, Encodable { return "There's no tags available" } } - } let name: String diff --git a/Sources/GitBuddyCore/Models/Token.swift b/Sources/GitBuddyCore/Models/Token.swift index 9e36d0d..8ce8302 100644 --- a/Sources/GitBuddyCore/Models/Token.swift +++ b/Sources/GitBuddyCore/Models/Token.swift @@ -47,5 +47,4 @@ struct Token: CustomStringConvertible { self.username = String(username) self.accessToken = String(accessToken) } - } diff --git a/Sources/GitBuddyCore/Release/ReleaseProducer.swift b/Sources/GitBuddyCore/Release/ReleaseProducer.swift index e524d6d..4094fe1 100644 --- a/Sources/GitBuddyCore/Release/ReleaseProducer.swift +++ b/Sources/GitBuddyCore/Release/ReleaseProducer.swift @@ -11,7 +11,6 @@ import OctoKit /// Capable of producing a release, adjusting a Changelog file, and posting comments to released issues/PRs. final class ReleaseProducer: URLSessionInjectable, ShellInjectable { - enum Error: Swift.Error, CustomStringConvertible { case changelogTargetDateMissing @@ -23,7 +22,7 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { } } - private lazy var octoKit: Octokit = Octokit() + private lazy var octoKit: Octokit = .init() let changelogURL: Foundation.URL? let skipComments: Bool let isPrerelease: Bool @@ -171,7 +170,7 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { """) var result: Result! - octoKit.postRelease(urlSession, owner: project.organisation, repository: project.repository, tagName: tagName, targetCommitish: targetCommitish, name: releaseTitle, body: body, prerelease: isPrerelease, draft: false) { (response) in + octoKit.postRelease(urlSession, owner: project.organisation, repository: project.repository, tagName: tagName, targetCommitish: targetCommitish, name: releaseTitle, body: body, prerelease: isPrerelease, draft: false) { response in switch response { case .success(let release): result = .success(release.htmlURL) diff --git a/Sources/GitBuddyCore/Tag Deletions/TagsDeleter.swift b/Sources/GitBuddyCore/Tag Deletions/TagsDeleter.swift index b8bad80..ac5fe8f 100644 --- a/Sources/GitBuddyCore/Tag Deletions/TagsDeleter.swift +++ b/Sources/GitBuddyCore/Tag Deletions/TagsDeleter.swift @@ -2,8 +2,7 @@ import Foundation import OctoKit final class TagsDeleter: URLSessionInjectable, ShellInjectable { - - private lazy var octoKit: Octokit = Octokit() + private lazy var octoKit: Octokit = .init() let upUntilTagName: String? let limit: Int let prereleaseOnly: Bool @@ -49,12 +48,12 @@ final class TagsDeleter: URLSessionInjectable, ShellInjectable { Log.debug("Fetched releases: \(releases.map { $0.tagName }.joined(separator: ", "))") return releases - .filter({ release in + .filter { release in guard !prereleaseOnly || release.prerelease else { return false } return release.createdAt < upUntil - }) + } .suffix(limit) } diff --git a/Tests/GitBuddyTests/Changelog/ChangelogCommandTests.swift b/Tests/GitBuddyTests/Changelog/ChangelogCommandTests.swift index ad52ea3..c426746 100644 --- a/Tests/GitBuddyTests/Changelog/ChangelogCommandTests.swift +++ b/Tests/GitBuddyTests/Changelog/ChangelogCommandTests.swift @@ -5,13 +5,12 @@ // Created by Antoine van der Lee on 09/04/2020. // -import XCTest -import Mocker @testable import GitBuddyCore +import Mocker import OctoKit +import XCTest final class ChangelogCommandTests: XCTestCase { - override func setUp() { super.setUp() Octokit.protocolClasses = [MockingURLProtocol.self] @@ -99,7 +98,7 @@ final class ChangelogCommandTests: XCTestCase { /// It should use the latest tag by default for the latest release adding 60 seconds to its creation date. func testLatestReleaseUsingLatestTag() throws { let tag = "2.1.3" - let date = Date().addingTimeInterval(TimeInterval.random(in: 0..<100)) + let date = Date().addingTimeInterval(TimeInterval.random(in: 0 ..< 100)) MockedShell.mockRelease(tag: tag, date: date) let producer = try ChangelogProducer(baseBranch: nil) @@ -109,11 +108,11 @@ final class ChangelogCommandTests: XCTestCase { /// It should use a tag passed as argument over the latest tag adding 60 seconds to its creation date.. func testReleaseUsingTagArgument() throws { let expectedTag = "3.0.2" - let date = Date().addingTimeInterval(TimeInterval.random(in: 0..<100)) + let date = Date().addingTimeInterval(TimeInterval.random(in: 0 ..< 100)) MockedShell.mockRelease(tag: expectedTag, date: date) let producer = try ChangelogProducer(since: .tag(tag: expectedTag), baseBranch: nil) - guard case let ChangelogProducer.Since.tag(tag) = producer.since else { + guard case ChangelogProducer.Since.tag(let tag) = producer.since else { XCTFail("Wrong since used") return } @@ -131,5 +130,4 @@ final class ChangelogCommandTests: XCTestCase { XCTAssertEqual(producer.project.organisation, organisation) XCTAssertEqual(producer.project.repository, repository) } - } diff --git a/Tests/GitBuddyTests/Changelog/ChangelogItemsFactoryTests.swift b/Tests/GitBuddyTests/Changelog/ChangelogItemsFactoryTests.swift index daa0b76..59d0bc6 100644 --- a/Tests/GitBuddyTests/Changelog/ChangelogItemsFactoryTests.swift +++ b/Tests/GitBuddyTests/Changelog/ChangelogItemsFactoryTests.swift @@ -6,14 +6,13 @@ // Copyright © 2020 WeTransfer. All rights reserved. // -import XCTest @testable import GitBuddyCore -@testable import OctoKit import Mocker +@testable import OctoKit +import XCTest final class ChangelogItemsFactoryTests: XCTestCase { - - private let octoKit: Octokit = Octokit() + private let octoKit: Octokit = .init() private var urlSession: URLSession! private let project = GITProject(organisation: "WeTransfer", repository: "Diagnostics") @@ -51,5 +50,4 @@ final class ChangelogItemsFactoryTests: XCTestCase { XCTAssertEqual(items.first?.input.title, issue.title) XCTAssertEqual(items.first?.closedBy.title, pullRequest.title) } - } diff --git a/Tests/GitBuddyTests/GitBuddyCommandTests.swift b/Tests/GitBuddyTests/GitBuddyCommandTests.swift index b086da3..3396975 100644 --- a/Tests/GitBuddyTests/GitBuddyCommandTests.swift +++ b/Tests/GitBuddyTests/GitBuddyCommandTests.swift @@ -6,11 +6,10 @@ // Copyright © 2020 WeTransfer. All rights reserved. // -import XCTest @testable import GitBuddyCore +import XCTest final class GitBuddyCommandTests: XCTestCase { - /// It should throw an error if the GitHub access token was not set. func testMissingAccessToken() { do { diff --git a/Tests/GitBuddyTests/GitHub/CommenterTests.swift b/Tests/GitBuddyTests/GitHub/CommenterTests.swift index da9a503..3a44cb3 100644 --- a/Tests/GitBuddyTests/GitHub/CommenterTests.swift +++ b/Tests/GitBuddyTests/GitHub/CommenterTests.swift @@ -5,12 +5,11 @@ // Created by Antoine van der Lee on 09/04/2020. // -import XCTest @testable import GitBuddyCore import Mocker +import XCTest final class CommenterTests: XCTestCase { - override func setUp() { super.setUp() let configuration = URLSessionConfiguration.default diff --git a/Tests/GitBuddyTests/GitHub/IssueResolverTests.swift b/Tests/GitBuddyTests/GitHub/IssueResolverTests.swift index 637ba64..32c5d03 100644 --- a/Tests/GitBuddyTests/GitHub/IssueResolverTests.swift +++ b/Tests/GitBuddyTests/GitHub/IssueResolverTests.swift @@ -6,14 +6,13 @@ // Copyright © 2020 WeTransfer. All rights reserved. // -import XCTest -import OctoKit -import Mocker @testable import GitBuddyCore +import Mocker +import OctoKit +import XCTest final class IssueResolverTests: XCTestCase { - - private let octoKit: Octokit = Octokit() + private let octoKit: Octokit = .init() private var urlSession: URLSession! override func setUp() { @@ -65,7 +64,7 @@ final class IssueResolverTests: XCTestCase { let issueNumber = 4343 - issueClosingKeywords.forEach { (closingKeyword) in + issueClosingKeywords.forEach { closingKeyword in let description = examplePullRequestDescriptionUsing(closingKeyword: closingKeyword, issueNumber: issueNumber) XCTAssertEqual(description.resolvingIssues(), [issueNumber]) } @@ -129,12 +128,11 @@ extension IssueResolverTests { let issueNumberString = issueNumber?.description ?? "" return """ - This PR does a lot of awesome stuff. - It even closes some issues! - Not #3737 though. This one is too hard. - - \(closingKeyword) #\(issueNumberString) - """ + This PR does a lot of awesome stuff. + It even closes some issues! + Not #3737 though. This one is too hard. + \(closingKeyword) #\(issueNumberString) + """ } } diff --git a/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift b/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift index 9c05e6a..1e9e5ad 100644 --- a/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift +++ b/Tests/GitBuddyTests/GitHub/PullRequestFetcherTests.swift @@ -6,14 +6,13 @@ // Copyright © 2020 WeTransfer. All rights reserved. // -import XCTest -import OctoKit -import Mocker @testable import GitBuddyCore +import Mocker +import OctoKit +import XCTest final class PullRequestFetcherTests: XCTestCase { - - private let octoKit: Octokit = Octokit() + private let octoKit: Octokit = .init() private var urlSession: URLSession! override func setUp() { @@ -39,5 +38,4 @@ final class PullRequestFetcherTests: XCTestCase { XCTAssertEqual(pullRequests[0].title, "Add charset utf-8 to html head 😃") XCTAssertEqual(pullRequests[1].title, "Fix warning occurring in pod library because of importing style.css #trivial") } - } diff --git a/Tests/GitBuddyTests/Models/ChangelogItemTests.swift b/Tests/GitBuddyTests/Models/ChangelogItemTests.swift index bb7eb5b..fa47ae0 100644 --- a/Tests/GitBuddyTests/Models/ChangelogItemTests.swift +++ b/Tests/GitBuddyTests/Models/ChangelogItemTests.swift @@ -6,12 +6,11 @@ // Copyright © 2020 WeTransfer. All rights reserved. // -import XCTest @testable import GitBuddyCore import OctoKit +import XCTest final class ChangelogItemTests: XCTestCase { - /// It should return `nil` if there's no title. func testNilTitle() { let item = ChangelogItem(input: MockChangelogInput(), closedBy: MockedPullRequest()) @@ -67,5 +66,4 @@ final class ChangelogItemTests: XCTestCase { "\(input.title!) ([#1](https://www.fakeurl.com)) via [@Henk](https://github.com/Henk)" ) } - } diff --git a/Tests/GitBuddyTests/Models/SingleSectionChangelogTests.swift b/Tests/GitBuddyTests/Models/SingleSectionChangelogTests.swift index 29fd3c3..2e65ba2 100644 --- a/Tests/GitBuddyTests/Models/SingleSectionChangelogTests.swift +++ b/Tests/GitBuddyTests/Models/SingleSectionChangelogTests.swift @@ -7,11 +7,10 @@ // import Foundation -import XCTest @testable import GitBuddyCore +import XCTest final class SingleSectionChangelogTests: XCTestCase { - /// It should report a single issue from a pull request correctly. func testPullRequestSingleIssue() { let pullRequest = MockedPullRequest(number: 0) diff --git a/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift b/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift index 1f9dc9f..7d5edbe 100644 --- a/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift +++ b/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift @@ -6,13 +6,12 @@ // Copyright © 2020 WeTransfer. All rights reserved. // -import XCTest @testable import GitBuddyCore import Mocker import OctoKit +import XCTest final class ReleaseProducerTests: XCTestCase { - override func setUp() { super.setUp() Octokit.protocolClasses = [MockingURLProtocol.self] diff --git a/Tests/GitBuddyTests/Tag Deletions/TagsDeleterTests.swift b/Tests/GitBuddyTests/Tag Deletions/TagsDeleterTests.swift index 564f534..8a04706 100644 --- a/Tests/GitBuddyTests/Tag Deletions/TagsDeleterTests.swift +++ b/Tests/GitBuddyTests/Tag Deletions/TagsDeleterTests.swift @@ -1,17 +1,16 @@ // // TagsDeleterTests.swift -// +// // // Created by Antoine van der Lee on 25/01/2022. // -import XCTest @testable import GitBuddyCore import Mocker import OctoKit +import XCTest final class TagsDeleterTests: XCTestCase { - override func setUp() { super.setUp() Octokit.protocolClasses = [MockingURLProtocol.self] diff --git a/Tests/GitBuddyTests/TestHelpers/ListReleasesJSON.swift b/Tests/GitBuddyTests/TestHelpers/ListReleasesJSON.swift index 282efb9..da28c82 100644 --- a/Tests/GitBuddyTests/TestHelpers/ListReleasesJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/ListReleasesJSON.swift @@ -1,6 +1,6 @@ // // ListReleasesJSON.swift -// +// // // Created by Antoine van der Lee on 25/01/2022. // diff --git a/Tests/GitBuddyTests/TestHelpers/Mocks.swift b/Tests/GitBuddyTests/TestHelpers/Mocks.swift index d5221cc..32a44b8 100644 --- a/Tests/GitBuddyTests/TestHelpers/Mocks.swift +++ b/Tests/GitBuddyTests/TestHelpers/Mocks.swift @@ -8,13 +8,12 @@ // swiftlint:disable final_class import Foundation +@testable import GitBuddyCore import Mocker import OctoKit -@testable import GitBuddyCore import XCTest struct MockedShell: ShellExecuting { - static var commandMocks: [String: String] = [:] @discardableResult static func execute(_ command: ShellCommand) -> String { @@ -59,8 +58,8 @@ class MockChangelogInput: ChangelogInput { } } -final class MockedPullRequest: MockChangelogInput, ChangelogPullRequest { } -final class MockedIssue: MockChangelogInput, ChangelogIssue { } +final class MockedPullRequest: MockChangelogInput, ChangelogPullRequest {} +final class MockedIssue: MockChangelogInput, ChangelogIssue {} extension Mocker { static func mockPullRequests(baseBranch: String = "master") { diff --git a/Tests/GitBuddyTests/TestHelpers/XCTestExtensions.swift b/Tests/GitBuddyTests/TestHelpers/XCTestExtensions.swift index 1ff14cb..bde8e0d 100644 --- a/Tests/GitBuddyTests/TestHelpers/XCTestExtensions.swift +++ b/Tests/GitBuddyTests/TestHelpers/XCTestExtensions.swift @@ -6,11 +6,10 @@ // import Foundation -import XCTest @testable import GitBuddyCore +import XCTest extension XCTest { - func AssertEqualStringsIgnoringTrailingWhitespace(_ string1: String, _ string2: String, file: StaticString = #file, line: UInt = #line) { let lines1 = string1.split(separator: "\n", omittingEmptySubsequences: false) let lines2 = string2.split(separator: "\n", omittingEmptySubsequences: false) @@ -51,7 +50,7 @@ extension XCTest { extension Substring { func trimmed() -> Substring { - guard let i = lastIndex(where: { $0 != " "}) else { + guard let i = lastIndex(where: { $0 != " " }) else { return "" } return self[...i] diff --git a/Tests/GitBuddyTests/XCTestManifests.swift b/Tests/GitBuddyTests/XCTestManifests.swift deleted file mode 100644 index a098d7f..0000000 --- a/Tests/GitBuddyTests/XCTestManifests.swift +++ /dev/null @@ -1,9 +0,0 @@ -import XCTest - -#if !canImport(ObjectiveC) -public func allTests() -> [XCTestCaseEntry] { - return [ - // testCase(GitBuddyTests.allTests), - ] -} -#endif From 6e59042c90d0beb296f946dbab671efbab5fa7b6 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee Date: Thu, 5 May 2022 13:59:37 +0200 Subject: [PATCH 7/7] Fix SwiftLint and SwiftFormat warnings --- .../Changelog/ChangelogProducer.swift | 3 +- .../Commands/ReleaseCommand.swift | 34 +++++++++++++-- .../Commands/TagDeletionsCommand.swift | 5 ++- Sources/GitBuddyCore/GitHub/Commenter.swift | 25 ++++++----- .../GitHub/PullRequestFetcher.swift | 10 ++++- Sources/GitBuddyCore/Models/Tag.swift | 3 +- .../Release/ReleaseProducer.swift | 42 ++++++++++++++++--- .../Tag Deletions/TagsDeleter.swift | 7 +++- .../Changelog/ChangelogCommandTests.swift | 5 ++- .../GitBuddyTests/GitHub/CommenterTests.swift | 14 ++++++- .../Release/ReleaseProducerTests.swift | 6 ++- .../GitBuddyTests/TestHelpers/IssueJSON.swift | 1 + .../TestHelpers/IssuesJSON.swift | 2 + Tests/GitBuddyTests/TestHelpers/Mocks.swift | 38 ++++++++++++++--- .../TestHelpers/PullRequestsJSON.swift | 1 + .../TestHelpers/ReleaseJSON.swift | 1 + .../TestHelpers/XCTestExtensions.swift | 7 +++- 17 files changed, 168 insertions(+), 36 deletions(-) diff --git a/Sources/GitBuddyCore/Changelog/ChangelogProducer.swift b/Sources/GitBuddyCore/Changelog/ChangelogProducer.swift index 6b2daee..a3d7833 100644 --- a/Sources/GitBuddyCore/Changelog/ChangelogProducer.swift +++ b/Sources/GitBuddyCore/Changelog/ChangelogProducer.swift @@ -17,7 +17,8 @@ final class ChangelogProducer: URLSessionInjectable { case latestTag /// Gets the date for the current Since property. - /// In the case of a tag, we add 60 seconds to make sure that the Changelog does not include the commit that is used for creating the tag. + /// In the case of a tag, we add 60 seconds to make sure that the Changelog does not include the commit that + /// is used for creating the tag. /// This is needed as the tag creation date equals the commit creation date. func get() throws -> Date { switch self { diff --git a/Sources/GitBuddyCore/Commands/ReleaseCommand.swift b/Sources/GitBuddyCore/Commands/ReleaseCommand.swift index 438ab26..d62ce21 100644 --- a/Sources/GitBuddyCore/Commands/ReleaseCommand.swift +++ b/Sources/GitBuddyCore/Commands/ReleaseCommand.swift @@ -9,7 +9,10 @@ import ArgumentParser import Foundation struct ReleaseCommand: ParsableCommand { - public static let configuration = CommandConfiguration(commandName: "release", abstract: "Create a new release including a changelog and publish comments on related issues.") + public static let configuration = CommandConfiguration( + commandName: "release", + abstract: "Create a new release including a changelog and publish comments on related issues." + ) @Option(name: .shortAndLong, help: "The path to the Changelog to update it with the latest changes.") var changelogPath: String? @@ -21,11 +24,26 @@ struct ReleaseCommand: ParsableCommand { var isPrerelease: Bool = false // Main - @Option(name: .shortAndLong, help: "Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA. Unused if the Git tag already exists. Default: the repository's default branch (usually main).") + @Option( + name: .shortAndLong, + help: """ + Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA. + Unused if the Git tag already exists. + + Default: the repository's default branch (usually main). + """ + ) var targetCommitish: String? // 1.3.1b1072 - @Option(name: [.long, .customShort("n")], help: "The name of the tag. If set, `changelogToTag` is required too. Default: takes the last created tag to publish as a GitHub release.") + @Option( + name: [.long, .customShort("n")], + help: """ + The name of the tag. If set, `changelogToTag` is required too. + + Default: takes the last created tag to publish as a GitHub release. + """ + ) var tagName: String? // // 1.3.1b1072 - App Store Release @@ -36,7 +54,15 @@ struct ReleaseCommand: ParsableCommand { @Option(name: .shortAndLong, help: "The last release tag to use as a base for the changelog creation. Default: previous tag.") var lastReleaseTag: String? - @Option(name: .customLong("changelogToTag"), help: "If set, the date of this tag will be used as the limit for the changelog creation. This variable should be passed when `tagName` is set. Default: latest tag.") + @Option( + name: .customLong("changelogToTag"), + help: """ + If set, the date of this tag will be used as the limit for the changelog creation. + This variable should be passed when `tagName` is set. + + Default: latest tag. + """ + ) var changelogToTag: String? // Develop diff --git a/Sources/GitBuddyCore/Commands/TagDeletionsCommand.swift b/Sources/GitBuddyCore/Commands/TagDeletionsCommand.swift index 04a4ab7..032ca61 100644 --- a/Sources/GitBuddyCore/Commands/TagDeletionsCommand.swift +++ b/Sources/GitBuddyCore/Commands/TagDeletionsCommand.swift @@ -2,7 +2,10 @@ import ArgumentParser import Foundation struct TagDeletionsCommand: ParsableCommand { - public static let configuration = CommandConfiguration(commandName: "tagDeletion", abstract: "Delete a batch of tags based on given predicates.") + public static let configuration = CommandConfiguration( + commandName: "tagDeletion", + abstract: "Delete a batch of tags based on given predicates." + ) @Option(name: .shortAndLong, help: "The date of this tag will be used as a limit. Defaults to the latest tag.") private var upUntilTag: String? diff --git a/Sources/GitBuddyCore/GitHub/Commenter.swift b/Sources/GitBuddyCore/GitHub/Commenter.swift index f6f5d08..7d153a1 100644 --- a/Sources/GitBuddyCore/GitHub/Commenter.swift +++ b/Sources/GitBuddyCore/GitHub/Commenter.swift @@ -18,8 +18,10 @@ enum Comment { case .releasedPR(let release): return "Congratulations! :tada: This was released as part of [Release \(release.title)](\(release.url)) :rocket:" case .releasedIssue(let release, let pullRequestID): - var body = "The pull request #\(pullRequestID) that closed this issue was merged and released as part of [Release \(release.title)](\(release.url)) :rocket:\n" - body += "Please let us know if the functionality works as expected as a reply here. If it does not, please open a new issue. Thanks!" + var body = "The pull request #\(pullRequestID) that closed this issue was merged and released " + body += "as part of [Release \(release.title)](\(release.url)) :rocket:\n" + body += "Please let us know if the functionality works as expected as a reply here. " + body += "If it does not, please open a new issue. Thanks!" return body } } @@ -43,14 +45,17 @@ enum Commenter { static func post(_ comment: Comment, on issueID: Int, at project: GITProject, completion: @escaping () -> Void) { var body = comment.body body += watermark - Octokit().commentIssue(urlSession, owner: project.organisation, repository: project.repository, number: issueID, body: body) { response in - switch response { - case .success(let comment): - Log.debug("Successfully posted comment at: \(comment.htmlURL)") - case .failure(let error): - Log.debug("Posting comment for issue #\(issueID) failed: \(error)") + Octokit() + .commentIssue(urlSession, owner: project.organisation, repository: project.repository, number: issueID, + body: body) + { response in + switch response { + case .success(let comment): + Log.debug("Successfully posted comment at: \(comment.htmlURL)") + case .failure(let error): + Log.debug("Posting comment for issue #\(issueID) failed: \(error)") + } + completion() } - completion() - } } } diff --git a/Sources/GitBuddyCore/GitHub/PullRequestFetcher.swift b/Sources/GitBuddyCore/GitHub/PullRequestFetcher.swift index 73c7416..2b017ba 100644 --- a/Sources/GitBuddyCore/GitHub/PullRequestFetcher.swift +++ b/Sources/GitBuddyCore/GitHub/PullRequestFetcher.swift @@ -22,7 +22,15 @@ struct PullRequestFetcher { var result: Result<[PullRequest], Swift.Error>! - octoKit.pullRequests(session, owner: project.organisation, repository: project.repository, base: baseBranch, state: .closed, sort: .updated, direction: .desc) { response in + octoKit.pullRequests( + session, + owner: project.organisation, + repository: project.repository, + base: baseBranch, + state: .closed, + sort: .updated, + direction: .desc + ) { response in switch response { case .success(let pullRequests): result = .success(pullRequests) diff --git a/Sources/GitBuddyCore/Models/Tag.swift b/Sources/GitBuddyCore/Models/Tag.swift index df7e3fd..a52c285 100644 --- a/Sources/GitBuddyCore/Models/Tag.swift +++ b/Sources/GitBuddyCore/Models/Tag.swift @@ -29,7 +29,8 @@ struct Tag: ShellInjectable, Encodable { /// Creates a new Tag instance. /// - Parameters: /// - name: The name to use for the tag. - /// - created: The creation date to use. If `nil`, the date is fetched using the `git` terminal command. See `fallbackDate` for setting a date if this operation fails due to a missing tag. + /// - created: The creation date to use. If `nil`, the date is fetched using the `git` terminal command. See `fallbackDate` + /// for setting a date if this operation fails due to a missing tag. /// - Throws: An error if the creation date could not be found. init(name: String, created: Date? = nil) throws { self.name = name diff --git a/Sources/GitBuddyCore/Release/ReleaseProducer.swift b/Sources/GitBuddyCore/Release/ReleaseProducer.swift index 4094fe1..e735060 100644 --- a/Sources/GitBuddyCore/Release/ReleaseProducer.swift +++ b/Sources/GitBuddyCore/Release/ReleaseProducer.swift @@ -33,7 +33,17 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { let changelogToTag: String? let baseBranch: String - init(changelogPath: String?, skipComments: Bool, isPrerelease: Bool, targetCommitish: String? = nil, tagName: String? = nil, releaseTitle: String? = nil, lastReleaseTag: String? = nil, baseBranch: String? = nil, changelogToTag: String? = nil) throws { + init( + changelogPath: String?, + skipComments: Bool, + isPrerelease: Bool, + targetCommitish: String? = nil, + tagName: String? = nil, + releaseTitle: String? = nil, + lastReleaseTag: String? = nil, + baseBranch: String? = nil, + changelogToTag: String? = nil + ) throws { try Octokit.authenticate() if let changelogPath = changelogPath { @@ -58,7 +68,11 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { let adjustedChangelogToDate = changelogToDate.addingTimeInterval(60) let changelogSinceTag = lastReleaseTag ?? Self.shell.execute(.previousTag) - let changelogProducer = try ChangelogProducer(since: .tag(tag: changelogSinceTag), to: adjustedChangelogToDate, baseBranch: baseBranch) + let changelogProducer = try ChangelogProducer( + since: .tag(tag: changelogSinceTag), + to: adjustedChangelogToDate, + baseBranch: baseBranch + ) let changelog = try changelogProducer.run(isSectioned: isSectioned) Log.debug("\(changelog)\n") @@ -68,7 +82,13 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { let repositoryName = Self.shell.execute(.repositoryName) let project = GITProject.current() Log.debug("Creating a release for tag \(tagName) at repository \(repositoryName)") - let release = try createRelease(using: project, tagName: tagName, targetCommitish: targetCommitish, title: releaseTitle, body: changelog.description) + let release = try createRelease( + using: project, + tagName: tagName, + targetCommitish: targetCommitish, + title: releaseTitle, + body: changelog.description + ) postComments(for: changelog, project: project, release: release) Log.debug("Result of creating the release:\n") @@ -151,7 +171,9 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { handle.closeFile() } - private func createRelease(using project: GITProject, tagName: String, targetCommitish: String?, title: String?, body: String) throws -> Release { + private func createRelease(using project: GITProject, tagName: String, targetCommitish: String?, title: String?, + body: String) throws -> Release + { let group = DispatchGroup() group.enter() @@ -170,7 +192,17 @@ final class ReleaseProducer: URLSessionInjectable, ShellInjectable { """) var result: Result! - octoKit.postRelease(urlSession, owner: project.organisation, repository: project.repository, tagName: tagName, targetCommitish: targetCommitish, name: releaseTitle, body: body, prerelease: isPrerelease, draft: false) { response in + octoKit.postRelease( + urlSession, + owner: project.organisation, + repository: project.repository, + tagName: tagName, + targetCommitish: targetCommitish, + name: releaseTitle, + body: body, + prerelease: isPrerelease, + draft: false + ) { response in switch response { case .success(let release): result = .success(release.htmlURL) diff --git a/Sources/GitBuddyCore/Tag Deletions/TagsDeleter.swift b/Sources/GitBuddyCore/Tag Deletions/TagsDeleter.swift index ac5fe8f..c0f96ff 100644 --- a/Sources/GitBuddyCore/Tag Deletions/TagsDeleter.swift +++ b/Sources/GitBuddyCore/Tag Deletions/TagsDeleter.swift @@ -102,7 +102,12 @@ final class TagsDeleter: URLSessionInjectable, ShellInjectable { return } - octoKit.deleteReference(urlSession, owner: project.organisation, repository: project.repository, ref: "tags/\(release.tagName)") { error in + octoKit.deleteReference( + urlSession, + owner: project.organisation, + repository: project.repository, + ref: "tags/\(release.tagName)" + ) { error in defer { group.leave() } guard let error = error else { Log.debug("Successfully deleted tag \(release.tagName)") diff --git a/Tests/GitBuddyTests/Changelog/ChangelogCommandTests.swift b/Tests/GitBuddyTests/Changelog/ChangelogCommandTests.swift index c426746..bfd7d7e 100644 --- a/Tests/GitBuddyTests/Changelog/ChangelogCommandTests.swift +++ b/Tests/GitBuddyTests/Changelog/ChangelogCommandTests.swift @@ -35,7 +35,10 @@ final class ChangelogCommandTests: XCTestCase { let token = "username:79B02BE4-38D1-4E3D-9B41-4E0739761512" mockGITAuthentication(token) try executeCommand("gitbuddy changelog") - XCTAssertEqual(URLSessionInjector.urlSession.configuration.httpAdditionalHeaders?["Authorization"] as? String, "Basic dXNlcm5hbWU6NzlCMDJCRTQtMzhEMS00RTNELTlCNDEtNEUwNzM5NzYxNTEy") + XCTAssertEqual( + URLSessionInjector.urlSession.configuration.httpAdditionalHeaders?["Authorization"] as? String, + "Basic dXNlcm5hbWU6NzlCMDJCRTQtMzhEMS00RTNELTlCNDEtNEUwNzM5NzYxNTEy" + ) } /// It should correctly output the changelog. diff --git a/Tests/GitBuddyTests/GitHub/CommenterTests.swift b/Tests/GitBuddyTests/GitHub/CommenterTests.swift index 3a44cb3..e03b28c 100644 --- a/Tests/GitBuddyTests/GitHub/CommenterTests.swift +++ b/Tests/GitBuddyTests/GitHub/CommenterTests.swift @@ -27,11 +27,21 @@ final class CommenterTests: XCTestCase { func testWatermark() throws { Mocker.mockPullRequests() let latestTag = try Tag.latest() - let release = Release(tagName: latestTag.name, url: URL(string: "https://www.fakegithub.com")!, title: "Release title", changelog: "") + let release = Release( + tagName: latestTag.name, + url: URL(string: "https://www.fakegithub.com")!, + title: "Release title", + changelog: "" + ) let project = GITProject(organisation: "WeTransfer", repository: "GitBuddy") let mockExpectation = expectation(description: "Mock should be called") - var mock = Mock(url: URL(string: "https://api.github.com/repos/WeTransfer/GitBuddy/issues/1/comments")!, dataType: .json, statusCode: 200, data: [.post: Data()]) + var mock = Mock( + url: URL(string: "https://api.github.com/repos/WeTransfer/GitBuddy/issues/1/comments")!, + dataType: .json, + statusCode: 200, + data: [.post: Data()] + ) mock.onRequest = { _, postBodyArguments in let body = postBodyArguments?["body"] as? String XCTAssertTrue(body?.contains(Commenter.watermark) == true) diff --git a/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift b/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift index 7d5edbe..6b03149 100644 --- a/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift +++ b/Tests/GitBuddyTests/Release/ReleaseProducerTests.swift @@ -37,7 +37,10 @@ final class ReleaseProducerTests: XCTestCase { let token = "username:79B02BE4-38D1-4E3D-9B41-4E0739761512" mockGITAuthentication(token) try executeCommand("gitbuddy release -s") - XCTAssertEqual(URLSessionInjector.urlSession.configuration.httpAdditionalHeaders?["Authorization"] as? String, "Basic dXNlcm5hbWU6NzlCMDJCRTQtMzhEMS00RTNELTlCNDEtNEUwNzM5NzYxNTEy") + XCTAssertEqual( + URLSessionInjector.urlSession.configuration.httpAdditionalHeaders?["Authorization"] as? String, + "Basic dXNlcm5hbWU6NzlCMDJCRTQtMzhEMS00RTNELTlCNDEtNEUwNzM5NzYxNTEy" + ) } /// It should correctly output the release URL. @@ -47,6 +50,7 @@ final class ReleaseProducerTests: XCTestCase { func testReleaseOutputJSON() throws { let output = try executeCommand("gitbuddy release -s --json") + // swiftlint:disable:next line_length XCTAssertTrue(output.contains("{\"title\":\"1.0.1\",\"tagName\":\"1.0.1\",\"url\":\"https:\\/\\/github.com\\/WeTransfer\\/ChangelogProducer\\/releases\\/tag\\/1.0.1\"")) } diff --git a/Tests/GitBuddyTests/TestHelpers/IssueJSON.swift b/Tests/GitBuddyTests/TestHelpers/IssueJSON.swift index 789563f..5cd9e93 100644 --- a/Tests/GitBuddyTests/TestHelpers/IssueJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/IssueJSON.swift @@ -6,6 +6,7 @@ // Copyright © 2020 WeTransfer. All rights reserved. // +// swiftlint:disable line_length let IssueJSON = """ { diff --git a/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift b/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift index 63723b2..5e2df34 100644 --- a/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/IssuesJSON.swift @@ -5,6 +5,8 @@ // Created by Max Desiatov on 28/03/2020. // +// swiftlint:disable line_length +// swiftlint:disable file_length let IssuesJSON = #""" [ { diff --git a/Tests/GitBuddyTests/TestHelpers/Mocks.swift b/Tests/GitBuddyTests/TestHelpers/Mocks.swift index 32a44b8..7517b3f 100644 --- a/Tests/GitBuddyTests/TestHelpers/Mocks.swift +++ b/Tests/GitBuddyTests/TestHelpers/Mocks.swift @@ -68,7 +68,10 @@ extension Mocker { let date = dateFormatter.date(from: "2020-01-03")! MockedShell.mockRelease(tag: "1.0.0", date: date) - var urlComponents = URLComponents(url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/pulls")!, resolvingAgainstBaseURL: false)! + var urlComponents = URLComponents( + url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/pulls")!, + resolvingAgainstBaseURL: false + )! urlComponents.queryItems = [ URLQueryItem(name: "base", value: baseBranch), URLQueryItem(name: "direction", value: "desc"), @@ -87,7 +90,10 @@ extension Mocker { let date = dateFormatter.date(from: "2020-01-03")! MockedShell.mockRelease(tag: "1.0.0", date: date) - var urlComponents = URLComponents(url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/issues")!, resolvingAgainstBaseURL: false)! + var urlComponents = URLComponents( + url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/issues")!, + resolvingAgainstBaseURL: false + )! urlComponents.queryItems = [ URLQueryItem(name: "page", value: "1"), URLQueryItem(name: "per_page", value: "100"), @@ -107,26 +113,46 @@ extension Mocker { @discardableResult static func mockRelease() -> Mock { let releaseJSONData = ReleaseJSON.data(using: .utf8)! - let mock = Mock(url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/releases")!, dataType: .json, statusCode: 201, data: [.post: releaseJSONData]) + let mock = Mock( + url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/releases")!, + dataType: .json, + statusCode: 201, + data: [.post: releaseJSONData] + ) mock.register() return mock } @discardableResult static func mockListReleases() -> Mock { let releaseJSONData = ListReleasesJSON.data(using: .utf8)! - let mock = Mock(url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/releases?per_page=100")!, dataType: .json, statusCode: 200, data: [.get: releaseJSONData]) + let mock = Mock( + url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/releases?per_page=100")!, + dataType: .json, + statusCode: 200, + data: [.get: releaseJSONData] + ) mock.register() return mock } @discardableResult static func mockDeletingRelease(id: Int) -> Mock { - let mock = Mock(url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/releases/\(id)")!, dataType: .json, statusCode: 204, data: [.delete: Data()]) + let mock = Mock( + url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/releases/\(id)")!, + dataType: .json, + statusCode: 204, + data: [.delete: Data()] + ) mock.register() return mock } @discardableResult static func mockDeletingReference(tagName: String) -> Mock { - let mock = Mock(url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/git/refs/tags/\(tagName)")!, dataType: .json, statusCode: 204, data: [.delete: Data()]) + let mock = Mock( + url: URL(string: "https://api.github.com/repos/WeTransfer/Diagnostics/git/refs/tags/\(tagName)")!, + dataType: .json, + statusCode: 204, + data: [.delete: Data()] + ) mock.register() return mock } diff --git a/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift b/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift index 75a865a..97f8eb5 100644 --- a/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/PullRequestsJSON.swift @@ -8,6 +8,7 @@ import Foundation +// swiftlint:disable line_length let PullRequestsJSON = """ [{ diff --git a/Tests/GitBuddyTests/TestHelpers/ReleaseJSON.swift b/Tests/GitBuddyTests/TestHelpers/ReleaseJSON.swift index 4321c3a..7b87a57 100644 --- a/Tests/GitBuddyTests/TestHelpers/ReleaseJSON.swift +++ b/Tests/GitBuddyTests/TestHelpers/ReleaseJSON.swift @@ -8,6 +8,7 @@ import Foundation +// swiftlint:disable line_length let ReleaseJSON = """ { diff --git a/Tests/GitBuddyTests/TestHelpers/XCTestExtensions.swift b/Tests/GitBuddyTests/TestHelpers/XCTestExtensions.swift index bde8e0d..43b564d 100644 --- a/Tests/GitBuddyTests/TestHelpers/XCTestExtensions.swift +++ b/Tests/GitBuddyTests/TestHelpers/XCTestExtensions.swift @@ -10,7 +10,9 @@ import Foundation import XCTest extension XCTest { - func AssertEqualStringsIgnoringTrailingWhitespace(_ string1: String, _ string2: String, file: StaticString = #file, line: UInt = #line) { + func AssertEqualStringsIgnoringTrailingWhitespace(_ string1: String, _ string2: String, file: StaticString = #file, + line: UInt = #line) + { let lines1 = string1.split(separator: "\n", omittingEmptySubsequences: false) let lines2 = string2.split(separator: "\n", omittingEmptySubsequences: false) @@ -22,7 +24,8 @@ extension XCTest { /// Executes the command and throws the execution error if any occur. /// - Parameters: - /// - command: The command to execute. This command can be exactly the same as you would use in the terminal. E.g. "gitbuddy changelog". + /// - command: The command to execute. This command can be exactly the same as you would use in the terminal. + /// E.g. "gitbuddy changelog". /// - expected: The expected outcome printed in the console. /// - Throws: The error occured while executing the command. func AssertExecuteCommand(_ command: String, expected: String, file: StaticString = #file, line: UInt = #line) throws {