From 5b31cedf58611fd82d07c1f02cca35e5e2484dac Mon Sep 17 00:00:00 2001 From: "hummingbird-automation[bot]" <168462326+hummingbird-automation[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 07:33:06 +0000 Subject: [PATCH] Update from Hummingbird Project Template (#41) * Update from hummingbird-project-template 572d468b2cabeca286314c5a35196bd42445c8ef * run swift-format * Remove .swiftformat --------- Co-authored-by: adam-fowler Co-authored-by: Adam Fowler --- .github/workflows/validate.yml | 6 +- .swift-format | 63 +++++++++++++++ .swiftformat | 26 ------- CONTRIBUTING.md | 2 +- Package.swift | 13 ++-- Sources/Jobs/JobMetricsHelper.swift | 26 ++++--- Sources/Jobs/JobParameters.swift | 14 +++- Sources/Jobs/JobQueue.swift | 11 ++- Sources/Jobs/JobQueueHandler.swift | 77 ++++++++++++------- Sources/Jobs/JobRegistry.swift | 4 +- Sources/Jobs/MemoryJobQueue.swift | 2 +- Sources/Jobs/Scheduler/JobSchedule.swift | 15 ++-- Sources/Jobs/Scheduler/Schedule.swift | 21 ++--- .../DecodableWithUserInfoConfiguration.swift | 7 +- Tests/JobsTests/JobSchedulerTests.swift | 17 +++- Tests/JobsTests/MetricsTests.swift | 21 +++-- scripts/validate.sh | 25 +++--- 17 files changed, 212 insertions(+), 138 deletions(-) create mode 100644 .swift-format delete mode 100644 .swiftformat diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 7cddf30..434025a 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -8,16 +8,12 @@ concurrency: jobs: validate: - runs-on: macOS-latest + runs-on: ubuntu-latest timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 - - name: Install Dependencies - run: | - brew install mint - mint install NickLockwood/SwiftFormat@0.53.10 --no-link - name: run script run: ./scripts/validate.sh diff --git a/.swift-format b/.swift-format new file mode 100644 index 0000000..bb3dcff --- /dev/null +++ b/.swift-format @@ -0,0 +1,63 @@ +{ + "version" : 1, + "indentation" : { + "spaces" : 4 + }, + "tabWidth" : 4, + "fileScopedDeclarationPrivacy" : { + "accessLevel" : "private" + }, + "spacesAroundRangeFormationOperators" : false, + "indentConditionalCompilationBlocks" : false, + "indentSwitchCaseLabels" : false, + "lineBreakAroundMultilineExpressionChainComponents" : false, + "lineBreakBeforeControlFlowKeywords" : false, + "lineBreakBeforeEachArgument" : true, + "lineBreakBeforeEachGenericRequirement" : true, + "lineLength" : 150, + "maximumBlankLines" : 1, + "respectsExistingLineBreaks" : true, + "prioritizeKeepingFunctionOutputTogether" : true, + "multiElementCollectionTrailingCommas" : true, + "rules" : { + "AllPublicDeclarationsHaveDocumentation" : false, + "AlwaysUseLiteralForEmptyCollectionInit" : false, + "AlwaysUseLowerCamelCase" : false, + "AmbiguousTrailingClosureOverload" : true, + "BeginDocumentationCommentWithOneLineSummary" : false, + "DoNotUseSemicolons" : true, + "DontRepeatTypeInStaticProperties" : true, + "FileScopedDeclarationPrivacy" : true, + "FullyIndirectEnum" : true, + "GroupNumericLiterals" : true, + "IdentifiersMustBeASCII" : true, + "NeverForceUnwrap" : false, + "NeverUseForceTry" : false, + "NeverUseImplicitlyUnwrappedOptionals" : false, + "NoAccessLevelOnExtensionDeclaration" : true, + "NoAssignmentInExpressions" : true, + "NoBlockComments" : true, + "NoCasesWithOnlyFallthrough" : true, + "NoEmptyTrailingClosureParentheses" : true, + "NoLabelsInCasePatterns" : true, + "NoLeadingUnderscores" : false, + "NoParensAroundConditions" : true, + "NoVoidReturnOnFunctionSignature" : true, + "OmitExplicitReturns" : true, + "OneCasePerLine" : true, + "OneVariableDeclarationPerLine" : true, + "OnlyOneTrailingClosureArgument" : true, + "OrderedImports" : true, + "ReplaceForEachWithForLoop" : true, + "ReturnVoidInsteadOfEmptyTuple" : true, + "UseEarlyExits" : false, + "UseExplicitNilCheckInConditions" : false, + "UseLetInEveryBoundCaseVariable" : false, + "UseShorthandTypeNames" : true, + "UseSingleLinePropertyGetter" : false, + "UseSynthesizedInitializer" : false, + "UseTripleSlashForDocumentationComments" : true, + "UseWhereClausesInForLoops" : false, + "ValidateDocumentationComments" : false + } +} diff --git a/.swiftformat b/.swiftformat deleted file mode 100644 index 14fb33f..0000000 --- a/.swiftformat +++ /dev/null @@ -1,26 +0,0 @@ -# Minimum swiftformat version ---minversion 0.53.10 - -# Swift version ---swiftversion 5.9 - -# file options ---exclude .build - -# rules ---disable redundantReturn, extensionAccessControl, typeSugar, conditionalAssignment, preferForLoop, redundantInternal, redundantStaticSelf - -# format options ---ifdef no-indent ---nospaceoperators ...,..< ---patternlet inline ---self insert ---stripunusedargs unnamed-only - -#--maxwidth 150 ---wraparguments before-first ---wrapparameters before-first ---wrapcollections before-first - -#file header -# --header "//===----------------------------------------------------------------------===//\n//\n// This source file is part of the Hummingbird server framework project\n//\n// Copyright (c) {created.year}-{year} the Hummingbird authors\n// Licensed under Apache License v2.0\n//\n// See LICENSE.txt for license information\n// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors\n//\n// SPDX-License-Identifier: Apache-2.0\n//\n//===----------------------------------------------------------------------===//" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 14b9831..8f5de31 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,4 +28,4 @@ The main development branch of the repository is `main`. ### Formatting -We use Nick Lockwood's SwiftFormat for formatting code. PRs will not be accepted if they haven't be formatted. The current version of SwiftFormat we are using is v0.53.10. +We use Apple's swift-format for formatting code. PRs will not be accepted if they haven't be formatted. \ No newline at end of file diff --git a/Package.swift b/Package.swift index 57018c5..7ef8dc9 100644 --- a/Package.swift +++ b/Package.swift @@ -9,7 +9,7 @@ let package = Package( name: "swift-jobs", platforms: [.macOS(.v14), .iOS(.v17), .tvOS(.v17)], products: [ - .library(name: "Jobs", targets: ["Jobs"]), + .library(name: "Jobs", targets: ["Jobs"]) ], dependencies: [ .package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.0"), @@ -34,9 +34,12 @@ let package = Package( swiftSettings: swiftSettings ), // test targets - .testTarget(name: "JobsTests", dependencies: [ - .byName(name: "Jobs"), - .product(name: "Atomics", package: "swift-atomics"), - ]), + .testTarget( + name: "JobsTests", + dependencies: [ + .byName(name: "Jobs"), + .product(name: "Atomics", package: "swift-atomics"), + ] + ), ] ) diff --git a/Sources/Jobs/JobMetricsHelper.swift b/Sources/Jobs/JobMetricsHelper.swift index 487477a..0db7e14 100644 --- a/Sources/Jobs/JobMetricsHelper.swift +++ b/Sources/Jobs/JobMetricsHelper.swift @@ -53,10 +53,13 @@ internal enum JobMetricsHelper { // with something like count(swif_jobs_meter{status="processing"} // unless on(jobID) (swif_jobs_meter{status="queued"}) // or (swif_jobs_meter{status="completed")) or vector(0) - Meter(label: JobMetricsHelper.meterLabel, dimensions: [ - ("status", JobMetricsHelper.JobStatus.completed.rawValue), - ("jobID", jobID), - ]).increment() + Meter( + label: JobMetricsHelper.meterLabel, + dimensions: [ + ("status", JobMetricsHelper.JobStatus.completed.rawValue), + ("jobID", jobID), + ] + ).increment() if retrying { Counter( @@ -66,15 +69,16 @@ internal enum JobMetricsHelper { return } - let jobStatus: JobStatus = if let error { - if error is CancellationError { - .cancelled + let jobStatus: JobStatus = + if let error { + if error is CancellationError { + .cancelled + } else { + .failed + } } else { - .failed + .succeeded } - } else { - .succeeded - } let dimensions: [(String, String)] = [ ("name", name), diff --git a/Sources/Jobs/JobParameters.swift b/Sources/Jobs/JobParameters.swift index 332515f..c8fa123 100644 --- a/Sources/Jobs/JobParameters.swift +++ b/Sources/Jobs/JobParameters.swift @@ -25,8 +25,11 @@ extension JobParameters { } /// Added so it is possible to push JobParameters referenced as Existentials to a Job queue - @discardableResult public func push(to jobQueue: JobQueue, options: JobOptions = .init()) async throws -> Queue.JobID { - return try await jobQueue.push(self, options: options) + @discardableResult public func push( + to jobQueue: JobQueue, + options: JobOptions = .init() + ) async throws -> Queue.JobID { + try await jobQueue.push(self, options: options) } } @@ -36,8 +39,11 @@ extension JobQueue { /// - parameters: parameters for the job /// - options: JobOptions /// - Returns: Identifier of queued job - @discardableResult public func push(_ parameters: Parameters, options: JobOptions = .init()) async throws -> Queue.JobID { - return try await self.push(id: Parameters.jobID, parameters: parameters, options: options) + @discardableResult public func push( + _ parameters: Parameters, + options: JobOptions = .init() + ) async throws -> Queue.JobID { + try await self.push(id: Parameters.jobID, parameters: parameters, options: options) } /// Register job type diff --git a/Sources/Jobs/JobQueue.swift b/Sources/Jobs/JobQueue.swift index 0088630..d4afd14 100644 --- a/Sources/Jobs/JobQueue.swift +++ b/Sources/Jobs/JobQueue.swift @@ -50,10 +50,13 @@ public struct JobQueue: Service { let buffer = try self.queue.encode(id: id, parameters: parameters) let jobName = id.name let id = try await self.queue.push(buffer, options: options) - Meter(label: JobMetricsHelper.meterLabel, dimensions: [ - ("status", JobMetricsHelper.JobStatus.queued.rawValue), - ("jobID", id.description), - ]).increment() + Meter( + label: JobMetricsHelper.meterLabel, + dimensions: [ + ("status", JobMetricsHelper.JobStatus.queued.rawValue), + ("jobID", id.description), + ] + ).increment() self.logger.debug( "Pushed Job", metadata: ["JobID": .stringConvertible(id), "JobName": .string(jobName)] diff --git a/Sources/Jobs/JobQueueHandler.swift b/Sources/Jobs/JobQueueHandler.swift index faa2737..af23251 100644 --- a/Sources/Jobs/JobQueueHandler.swift +++ b/Sources/Jobs/JobQueueHandler.swift @@ -69,21 +69,30 @@ final class JobQueueHandler: Sendable { let startTime = DispatchTime.now().uptimeNanoseconds logger[metadataKey: "JobID"] = .stringConvertible(queuedJob.id) // Decrement the current queue by 1 - Meter(label: JobMetricsHelper.meterLabel, dimensions: [ - ("status", JobMetricsHelper.JobStatus.queued.rawValue), - ("jobID", queuedJob.id.description), - ]).decrement() - - Meter(label: JobMetricsHelper.meterLabel, dimensions: [ - ("status", JobMetricsHelper.JobStatus.processing.rawValue), - ("jobID", queuedJob.id.description), - ]).increment() + Meter( + label: JobMetricsHelper.meterLabel, + dimensions: [ + ("status", JobMetricsHelper.JobStatus.queued.rawValue), + ("jobID", queuedJob.id.description), + ] + ).decrement() - defer { - Meter(label: JobMetricsHelper.meterLabel, dimensions: [ + Meter( + label: JobMetricsHelper.meterLabel, + dimensions: [ ("status", JobMetricsHelper.JobStatus.processing.rawValue), ("jobID", queuedJob.id.description), - ]).decrement() + ] + ).increment() + + defer { + Meter( + label: JobMetricsHelper.meterLabel, + dimensions: [ + ("status", JobMetricsHelper.JobStatus.processing.rawValue), + ("jobID", queuedJob.id.description), + ] + ).decrement() } let job: any JobInstanceProtocol @@ -92,18 +101,24 @@ final class JobQueueHandler: Sendable { } catch let error as JobQueueError where error == .unrecognisedJobId { logger.debug("Failed to find Job with ID while decoding") try await self.queue.failed(jobId: queuedJob.id, error: error) - Meter(label: JobMetricsHelper.discardedMeter, dimensions: [ - ("reason", "INVALID_JOB_ID"), - ("jobID", queuedJob.id.description), - ]).increment() + Meter( + label: JobMetricsHelper.discardedMeter, + dimensions: [ + ("reason", "INVALID_JOB_ID"), + ("jobID", queuedJob.id.description), + ] + ).increment() return } catch { logger.debug("Job failed to decode") try await self.queue.failed(jobId: queuedJob.id, error: JobQueueError.decodeJobFailed) - Meter(label: JobMetricsHelper.discardedMeter, dimensions: [ - ("reason", "DECODE_FAILED"), - ("jobID", queuedJob.id.description), - ]).increment() + Meter( + label: JobMetricsHelper.discardedMeter, + dimensions: [ + ("reason", "DECODE_FAILED"), + ("jobID", queuedJob.id.description), + ] + ).increment() return } logger[metadataKey: "JobName"] = .string(job.name) @@ -163,10 +178,13 @@ final class JobQueueHandler: Sendable { // Guard against negative queue values, this is needed because we call // the job queue directly in the retrying step - Meter(label: JobMetricsHelper.meterLabel, dimensions: [ - ("status", JobMetricsHelper.JobStatus.queued.rawValue), - ("jobID", newJobId.description), - ]).increment() + Meter( + label: JobMetricsHelper.meterLabel, + dimensions: [ + ("status", JobMetricsHelper.JobStatus.queued.rawValue), + ("jobID", newJobId.description), + ] + ).increment() JobMetricsHelper.updateMetrics( for: job.name, @@ -174,10 +192,13 @@ final class JobQueueHandler: Sendable { startTime: startTime, retrying: true ) - logger.debug("Retrying Job", metadata: [ - "attempts": .stringConvertible(attempts), - "delayedUntil": .stringConvertible(delay), - ]) + logger.debug( + "Retrying Job", + metadata: [ + "attempts": .stringConvertible(attempts), + "delayedUntil": .stringConvertible(delay), + ] + ) return } logger.debug("Finished Job") diff --git a/Sources/Jobs/JobRegistry.swift b/Sources/Jobs/JobRegistry.swift index b2c1d7c..eec9e98 100644 --- a/Sources/Jobs/JobRegistry.swift +++ b/Sources/Jobs/JobRegistry.swift @@ -37,7 +37,7 @@ struct JobRegistry: Sendable { } func decode(_ buffer: ByteBuffer) throws -> any JobInstanceProtocol { - return try JSONDecoder().decode(AnyDecodableJob.self, from: buffer, userInfoConfiguration: self).job + try JSONDecoder().decode(AnyDecodableJob.self, from: buffer, userInfoConfiguration: self).job } func decode(jobName: String, from decoder: Decoder) throws -> any JobInstanceProtocol { @@ -48,5 +48,5 @@ struct JobRegistry: Sendable { return try jobDefinitionBuilder(decoder) } - let builderTypeMap: NIOLockedValueBox < [String: @Sendable (Decoder) throws -> any JobInstanceProtocol]> = .init([:]) + let builderTypeMap: NIOLockedValueBox<[String: @Sendable (Decoder) throws -> any JobInstanceProtocol]> = .init([:]) } diff --git a/Sources/Jobs/MemoryJobQueue.swift b/Sources/Jobs/MemoryJobQueue.swift index 54b2cd3..cf927ca 100644 --- a/Sources/Jobs/MemoryJobQueue.swift +++ b/Sources/Jobs/MemoryJobQueue.swift @@ -47,7 +47,7 @@ public final class MemoryQueue: JobQueueDriver { /// - options: Job options /// - Returns: Job ID @discardableResult public func push(_ buffer: ByteBuffer, options: JobOptions) async throws -> JobID { - return try await self.queue.push(buffer, options: options) + try await self.queue.push(buffer, options: options) } public func finished(jobId: JobID) async throws { diff --git a/Sources/Jobs/Scheduler/JobSchedule.swift b/Sources/Jobs/Scheduler/JobSchedule.swift index df49d6b..bf25859 100644 --- a/Sources/Jobs/Scheduler/JobSchedule.swift +++ b/Sources/Jobs/Scheduler/JobSchedule.swift @@ -95,15 +95,16 @@ public struct JobSchedule: MutableCollection, Sendable { } func nextJob() -> (offset: Int, element: Element)? { - return self.lazy.enumerated().min(by: { $0.element.nextScheduledDate < $1.element.nextScheduledDate }) + self.lazy.enumerated().min(by: { $0.element.nextScheduledDate < $1.element.nextScheduledDate }) } mutating func updateNextScheduledDate(jobIndex: Int) { - let dateFrom: Date = switch self.self[jobIndex].accuracy { - case .latest: .now - case .all: self[jobIndex].nextScheduledDate - default: .now - } + let dateFrom: Date = + switch self.self[jobIndex].accuracy { + case .latest: .now + case .all: self[jobIndex].nextScheduledDate + default: .now + } if let nextScheduledDate = self[jobIndex].schedule.nextDate(after: dateFrom) { self[jobIndex].nextScheduledDate = nextScheduledDate } else { @@ -213,7 +214,7 @@ extension JobSchedule { public var endIndex: Index { self.elements.endIndex } /// Access element at specific position public subscript(_ index: Index) -> Element { - get { return self.elements[index] } + get { self.elements[index] } set { self.elements[index] = newValue } } diff --git a/Sources/Jobs/Scheduler/Schedule.swift b/Sources/Jobs/Scheduler/Schedule.swift index 5ffcfd8..15df880 100644 --- a/Sources/Jobs/Scheduler/Schedule.swift +++ b/Sources/Jobs/Scheduler/Schedule.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import Collections + #if os(Linux) @preconcurrency import Foundation #else @@ -122,9 +123,7 @@ public struct Schedule: Sendable { /// - minutes: Array of minutes if should return Dates for /// - second: Second value it should return a Date at public static func onMinutes(_ minutes: some Collection, second: Int = 0) -> Self { - let parameter: Parameter = minutes.count != 1 ? - .selection(Deque(minutes.sorted())) : - .specific(minutes.first!) + let parameter: Parameter = minutes.count != 1 ? .selection(Deque(minutes.sorted())) : .specific(minutes.first!) return .init(second: .specific(second), minute: parameter) } @@ -140,9 +139,7 @@ public struct Schedule: Sendable { /// - minute: Minute value it should return a Date at /// - timeZone: TimeZone to run schedule in public static func onHours(_ hours: some Collection, minute: Int = 0, timeZone: TimeZone = .current) -> Self { - let parameter: Parameter = hours.count != 1 ? - .selection(Deque(hours.sorted())) : - .specific(hours.first!) + let parameter: Parameter = hours.count != 1 ? .selection(Deque(hours.sorted())) : .specific(hours.first!) return .init(minute: .specific(minute), hour: parameter, timeZone: timeZone) } @@ -162,9 +159,7 @@ public struct Schedule: Sendable { /// - minute: Minute value it should return a Date at /// - timeZone: TimeZone to run schedule in public static func onDays(_ days: some Collection, hour: Int = 0, minute: Int = 0, timeZone: TimeZone = .current) -> Self { - let parameter: Parameter = days.count != 1 ? - .selection(Deque(days.sorted())) : - .specific(days.first!) + let parameter: Parameter = days.count != 1 ? .selection(Deque(days.sorted())) : .specific(days.first!) return .init(minute: .specific(minute), hour: .specific(hour), day: parameter, timeZone: timeZone) } @@ -185,9 +180,7 @@ public struct Schedule: Sendable { /// - timeZone: TimeZone to run schedule in /// - Returns: public static func onDates(_ dates: some Collection, hour: Int = 0, minute: Int = 0, timeZone: TimeZone = .current) -> Self { - let parameter: Parameter = dates.count != 1 ? - .selection(Deque(dates.sorted())) : - .specific(dates.first!) + let parameter: Parameter = dates.count != 1 ? .selection(Deque(dates.sorted())) : .specific(dates.first!) return .init(minute: .specific(minute), hour: .specific(hour), date: parameter, timeZone: timeZone) } @@ -210,9 +203,7 @@ public struct Schedule: Sendable { /// - timeZone: TimeZone to run schedule in /// - Returns: public static func onMonths(_ months: some Collection, date: Int, hour: Int = 0, minute: Int = 0, timeZone: TimeZone = .current) -> Self { - let parameter: Parameter = months.count != 1 ? - .selection(Deque(months.sorted())) : - .specific(months.first!) + let parameter: Parameter = months.count != 1 ? .selection(Deque(months.sorted())) : .specific(months.first!) return .init(minute: .specific(minute), hour: .specific(hour), date: .specific(date), month: parameter, timeZone: timeZone) } diff --git a/Sources/Jobs/Utils/DecodableWithUserInfoConfiguration.swift b/Sources/Jobs/Utils/DecodableWithUserInfoConfiguration.swift index 9747de6..ec5fb42 100644 --- a/Sources/Jobs/Utils/DecodableWithUserInfoConfiguration.swift +++ b/Sources/Jobs/Utils/DecodableWithUserInfoConfiguration.swift @@ -26,7 +26,10 @@ protocol DecodableWithUserInfoConfiguration: Decodable, DecodableWithConfigurati extension DecodableWithUserInfoConfiguration { init(from decoder: Decoder) throws { guard let configuration = decoder.userInfo[.configuration] as? DecodingConfiguration else { - throw DecodingError.valueNotFound(DecodingConfiguration.self, .init(codingPath: decoder.codingPath, debugDescription: "Failed to find Decoding configuration")) + throw DecodingError.valueNotFound( + DecodingConfiguration.self, + .init(codingPath: decoder.codingPath, debugDescription: "Failed to find Decoding configuration") + ) } try self.init(from: decoder, configuration: configuration) } @@ -34,7 +37,7 @@ extension DecodableWithUserInfoConfiguration { extension CodingUserInfoKey { /// Coding UserInfo key used to store DecodableWithUserInfoConfiguration configuration - static var configuration: Self { return .init(rawValue: "_configuration_")! } + static var configuration: Self { .init(rawValue: "_configuration_")! } } extension JSONDecoder { diff --git a/Tests/JobsTests/JobSchedulerTests.swift b/Tests/JobsTests/JobSchedulerTests.swift index 330ff6e..8f087f5 100644 --- a/Tests/JobsTests/JobSchedulerTests.swift +++ b/Tests/JobsTests/JobSchedulerTests.swift @@ -12,11 +12,12 @@ // //===----------------------------------------------------------------------===// -@testable import Jobs import Logging import ServiceLifecycle import XCTest +@testable import Jobs + final class JobSchedulerTests: XCTestCase { func testSchedule(start: String, expectedEnd: String, schedule: Schedule) throws { var schedule = schedule @@ -25,7 +26,7 @@ final class JobSchedulerTests: XCTestCase { dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'" dateFormatter.timeZone = schedule.calendar.timeZone guard let startDate = dateFormatter.date(from: start), - let expectedEndDate = dateFormatter.date(from: expectedEnd) + let expectedEndDate = dateFormatter.date(from: expectedEnd) else { XCTFail("Failed to parse dates") return @@ -68,14 +69,22 @@ final class JobSchedulerTests: XCTestCase { } func testDailySchedule() throws { - try self.testSchedule(start: "2021-06-21T21:10:15Z", expectedEnd: "2021-06-22T01:15:00Z", schedule: .daily(hour: 1, minute: 15, timeZone: .init(secondsFromGMT: 0)!)) + try self.testSchedule( + start: "2021-06-21T21:10:15Z", + expectedEnd: "2021-06-22T01:15:00Z", + schedule: .daily(hour: 1, minute: 15, timeZone: .init(secondsFromGMT: 0)!) + ) try self.testSchedule(start: "1999-12-31T23:59:25Z", expectedEnd: "2000-01-01T06:15:00Z", schedule: .daily(hour: 6, minute: 15)) try self.testSchedule(start: "2024-02-28T23:59:25Z", expectedEnd: "2024-02-29T06:15:00Z", schedule: .daily(hour: 6, minute: 15)) } func testWeeklySchedule() throws { try self.testSchedule(start: "2021-06-21T21:10:15Z", expectedEnd: "2021-06-27T04:00:00Z", schedule: .weekly(day: .sunday, hour: 4)) - try self.testSchedule(start: "2024-03-19T23:59:56Z", expectedEnd: "2024-03-24T04:00:00Z", schedule: .weekly(day: .sunday, hour: 4, timeZone: .init(secondsFromGMT: 0)!)) + try self.testSchedule( + start: "2024-03-19T23:59:56Z", + expectedEnd: "2024-03-24T04:00:00Z", + schedule: .weekly(day: .sunday, hour: 4, timeZone: .init(secondsFromGMT: 0)!) + ) try self.testSchedule(start: "2024-03-19T23:59:56Z", expectedEnd: "2024-03-24T04:00:00Z", schedule: .weekly(day: .sunday, hour: 4)) try self.testSchedule(start: "1999-12-31T23:59:25Z", expectedEnd: "2000-01-01T08:00:00Z", schedule: .weekly(day: .saturday, hour: 8)) } diff --git a/Tests/JobsTests/MetricsTests.swift b/Tests/JobsTests/MetricsTests.swift index 22e567a..1a53552 100644 --- a/Tests/JobsTests/MetricsTests.swift +++ b/Tests/JobsTests/MetricsTests.swift @@ -29,7 +29,7 @@ final class TestMetrics: MetricsFactory { public func makeCounter(label: String, dimensions: [(String, String)]) -> CounterHandler { self.counters.withLockedValue { counters in - return self.make(label: label, dimensions: dimensions, registry: &counters, maker: TestCounter.init) + self.make(label: label, dimensions: dimensions, registry: &counters, maker: TestCounter.init) } } @@ -54,7 +54,12 @@ final class TestMetrics: MetricsFactory { } } - private func make(label: String, dimensions: [(String, String)], registry: inout [String: Item], maker: (String, [(String, String)]) -> Item) -> Item { + private func make( + label: String, + dimensions: [(String, String)], + registry: inout [String: Item], + maker: (String, [(String, String)]) -> Item + ) -> Item { let item = maker(label, dimensions) registry[label] = item return item @@ -120,7 +125,7 @@ internal final class TestCounter: CounterHandler, Equatable { } public static func == (lhs: TestCounter, rhs: TestCounter) -> Bool { - return lhs.id == rhs.id + lhs.id == rhs.id } } @@ -163,7 +168,7 @@ internal final class TestMeter: MeterHandler, Equatable { } public static func == (lhs: TestMeter, rhs: TestMeter) -> Bool { - return lhs.id == rhs.id + lhs.id == rhs.id } } @@ -194,7 +199,7 @@ internal final class TestRecorder: RecorderHandler, Equatable { } public static func == (lhs: TestRecorder, rhs: TestRecorder) -> Bool { - return lhs.id == rhs.id + lhs.id == rhs.id } } @@ -219,7 +224,7 @@ internal final class TestTimer: TimerHandler, Equatable { } func retriveValueInPreferredUnit(atIndex i: Int) -> Double { - return self.values.withLockedValue { values in + self.values.withLockedValue { values in let value = values[i].1 return self.displayUnit.withLockedValue { displayUnit in guard let displayUnit else { @@ -238,7 +243,7 @@ internal final class TestTimer: TimerHandler, Equatable { } public static func == (lhs: TestTimer, rhs: TestTimer) -> Bool { - return lhs.id == rhs.id + lhs.id == rhs.id } } @@ -302,7 +307,7 @@ final class MetricsTests: XCTestCase { let counter = try XCTUnwrap(Self.testMetrics.counters.withLockedValue { $0 }["swift.jobs"] as? TestCounter) XCTAssertEqual(counter.values.withLockedValue { $0 }[0].1, 1) - XCTAssertEqual(counter.values.withLockedValue { $0 }.count, 1) // This technically 5, need to figueout how to await the results to get 5 + XCTAssertEqual(counter.values.withLockedValue { $0 }.count, 1) // This technically 5, need to figueout how to await the results to get 5 XCTAssertEqual(counter.dimensions.count, 2) XCTAssertEqual(counter.dimensions[0].0, "name") XCTAssertEqual(counter.dimensions[0].1, "testBasic") diff --git a/scripts/validate.sh b/scripts/validate.sh index bb67406..f949949 100755 --- a/scripts/validate.sh +++ b/scripts/validate.sh @@ -31,8 +31,6 @@ SWIFT_FORMAT_VERSION=0.53.10 set -eu here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -which swiftformat > /dev/null 2>&1 || (echo "swiftformat not installed. You can install it using 'brew install swiftformat'" ; exit -1) - function replace_acceptable_years() { # this needs to replace all acceptable forms with 'YEARS' sed -e 's/20[12][0-9]-20[12][0-9]/YEARS/' -e 's/20[12][0-9]/YEARS/' -e '/^#!/ d' @@ -40,13 +38,9 @@ function replace_acceptable_years() { printf "=> Checking format... " FIRST_OUT="$(git status --porcelain)" -if [[ -n "${CI-""}" ]]; then - printf "(using v$(mint run NickLockwood/SwiftFormat@"$SWIFT_FORMAT_VERSION" --version)) " - mint run NickLockwood/SwiftFormat@"$SWIFT_FORMAT_VERSION" . > /dev/null 2>&1 -else - printf "(using v$(swiftformat --version)) " - swiftformat . > /dev/null 2>&1 -fi +git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place +git diff --exit-code '*.swift' + SECOND_OUT="$(git status --porcelain)" if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then printf "\033[0;31mformatting issues!\033[0m\n" @@ -55,10 +49,11 @@ if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then else printf "\033[0;32mokay.\033[0m\n" fi -exit printf "=> Checking license headers... " tmp=$(mktemp /tmp/.soto-core-sanity_XXXXXX) +exit 0 + for language in swift-or-c; do declare -a matching_files declare -a exceptions @@ -66,18 +61,18 @@ for language in swift-or-c; do matching_files=( -name '*' ) case "$language" in swift-or-c) - exceptions=( -path '*Sources/INIParser/*' -o -path '*Sources/CSotoExpat/*' -o -path '*Benchmark/.build/*' -o -name Package.swift) + exceptions=( -path '*/Benchmarks/.build/*' -o -name Package.swift) matching_files=( -name '*.swift' -o -name '*.c' -o -name '*.h' ) cat > "$tmp" <<"EOF" //===----------------------------------------------------------------------===// // -// This source file is part of the Hummingbird open source project +// This source file is part of the Hummingbird server framework project // // Copyright (c) YEARS the Hummingbird authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Hummingbird authors +// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors // // SPDX-License-Identifier: Apache-2.0 // @@ -89,13 +84,13 @@ EOF cat > "$tmp" <<"EOF" ##===----------------------------------------------------------------------===## ## -## This source file is part of the Hummingbird open source project +## This source file is part of the Hummingbird server framework project ## ## Copyright (c) YEARS the Hummingbird authors ## Licensed under Apache License v2.0 ## ## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of Hummingbird authors +## See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors ## ## SPDX-License-Identifier: Apache-2.0 ##