From 57a170beeda73c1b0dee3fe4d1aa069bc0d33a87 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Tue, 22 Apr 2025 20:48:56 -0700 Subject: [PATCH 1/3] Unify Core and RSCore into RSCore. --- ArticlesDatabase/Package.swift | 2 +- Core/Package.swift | 21 ----------- .../FoundationExtras/Date+Extensions.swift | 37 ------------------- Core/Tests/CoreTests/CoreTests.swift | 12 ------ NetNewsWire.xcodeproj/project.pbxproj | 2 - .../contents.xcworkspacedata | 7 ++++ RSCore/Package.swift | 19 ++++++---- .../Sources/RSCore/Shared}/AppConfig.swift | 0 .../Sources/RSCore/Shared}/Cache.swift | 0 .../RSCore/Shared/Date+Extensions.swift | 10 ++++- .../contents.xcworkspacedata | 7 ++++ RSWeb/Package.swift | 8 ++-- RSWeb/Sources/RSWeb/HTMLMetadataCache.swift | 2 +- Shared/Images/FeedIconDownloader.swift | 1 - Shared/Images/ImageDownloader.swift | 2 +- 15 files changed, 41 insertions(+), 89 deletions(-) delete mode 100644 Core/Package.swift delete mode 100755 Core/Sources/Core/FoundationExtras/Date+Extensions.swift delete mode 100644 Core/Tests/CoreTests/CoreTests.swift create mode 100644 RSCore/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata rename {Core/Sources/Core => RSCore/Sources/RSCore/Shared}/AppConfig.swift (100%) rename {Core/Sources/Core => RSCore/Sources/RSCore/Shared}/Cache.swift (100%) create mode 100644 RSParser/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata diff --git a/ArticlesDatabase/Package.swift b/ArticlesDatabase/Package.swift index 414e999ab..c44a8ea77 100644 --- a/ArticlesDatabase/Package.swift +++ b/ArticlesDatabase/Package.swift @@ -5,13 +5,13 @@ import PackageDescription var dependencies: [Package.Dependency] = [ .package(url: "https://github.com/Ranchero-Software/RSDatabase.git", .upToNextMajor(from: "1.0.0")), - .package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMajor(from: "2.0.2")), ] #if swift(>=5.6) dependencies.append(contentsOf: [ .package(path: "../Articles"), .package(path: "../RSCore"), + .package(path: "../RSParser"), ]) #else dependencies.append(contentsOf: [ diff --git a/Core/Package.swift b/Core/Package.swift deleted file mode 100644 index e1882a15c..000000000 --- a/Core/Package.swift +++ /dev/null @@ -1,21 +0,0 @@ -// swift-tools-version: 6.0 - -import PackageDescription - -let package = Package( - name: "Core", - platforms: [.macOS(.v13), .iOS(.v16)], - products: [ - .library( - name: "Core", - targets: ["Core"]), - ], - targets: [ - .target( - name: "Core"), - .testTarget( - name: "CoreTests", - dependencies: ["Core"] - ), - ] -) diff --git a/Core/Sources/Core/FoundationExtras/Date+Extensions.swift b/Core/Sources/Core/FoundationExtras/Date+Extensions.swift deleted file mode 100755 index f1ef88f01..000000000 --- a/Core/Sources/Core/FoundationExtras/Date+Extensions.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// Date+Extensions.swift -// RSCore -// -// Created by Brent Simmons on 6/21/16. -// Copyright ยฉ 2016 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -public extension Date { - - // Below are for rough use only โ€” they don't use the calendar. - - func bySubtracting(days: Int) -> Date { - return addingTimeInterval(0.0 - TimeInterval(days: days)) - } - - func bySubtracting(hours: Int) -> Date { - return addingTimeInterval(0.0 - TimeInterval(hours: hours)) - } - - func byAdding(days: Int) -> Date { - return addingTimeInterval(TimeInterval(days: days)) - } -} - -public extension TimeInterval { - - init(days: Int) { - self.init(days * 24 * 60 * 60) - } - - init(hours: Int) { - self.init(hours * 60 * 60) - } -} diff --git a/Core/Tests/CoreTests/CoreTests.swift b/Core/Tests/CoreTests/CoreTests.swift deleted file mode 100644 index 3cad2b63f..000000000 --- a/Core/Tests/CoreTests/CoreTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import XCTest -@testable import Core - -final class CoreTests: XCTestCase { - func testExample() throws { - // XCTest Documentation - // https://developer.apple.com/documentation/xctest - - // Defining Test Cases and Test Methods - // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods - } -} diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 855f4f1e7..61c457f04 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -738,7 +738,6 @@ 8405DDA122168920008CE1BF /* TimelineTableView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TimelineTableView.xib; sourceTree = ""; }; 8405DDA422168C62008CE1BF /* TimelineContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineContainerViewController.swift; sourceTree = ""; }; 840BEE4021D70E64009BBAFA /* CrashReportWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportWindowController.swift; sourceTree = ""; }; - 840C544F2D0C9A4A00A240DB /* Core */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Core; sourceTree = ""; }; 840D617C2029031C009BC708 /* NetNewsWire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetNewsWire.app; sourceTree = BUILT_PRODUCTS_DIR; }; 840D61952029031D009BC708 /* NetNewsWire_iOSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetNewsWire_iOSTests.swift; sourceTree = ""; }; 840D61972029031D009BC708 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -1537,7 +1536,6 @@ 8424B3162DB73D320053AA11 /* RSParser */, 843E2F152CF2B43700ED170F /* RSWeb */, 848E84CB2DB749300023F3BA /* RSCore */, - 840C544F2D0C9A4A00A240DB /* Core */, ); sourceTree = ""; usesTabs = 1; diff --git a/RSCore/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/RSCore/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/RSCore/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/RSCore/Package.swift b/RSCore/Package.swift index e7e117f73..1959cbc7e 100644 --- a/RSCore/Package.swift +++ b/RSCore/Package.swift @@ -1,13 +1,12 @@ -// swift-tools-version:5.3 -// The swift-tools-version declares the minimum version of Swift required to build this package. +// swift-tools-version:5.10 import PackageDescription let package = Package( - name: "RSCore", - platforms: [.macOS(SupportedPlatform.MacOSVersion.v10_15), .iOS(SupportedPlatform.IOSVersion.v13)], - products: [ - .library(name: "RSCore", type: .dynamic, targets: ["RSCore"]), + name: "RSCore", + platforms: [.macOS(.v13), .iOS(.v17)], + products: [ + .library(name: "RSCore", type: .dynamic, targets: ["RSCore"]), .library(name: "RSCoreObjC", type: .dynamic, targets: ["RSCoreObjC"]), .library(name: "RSCoreResources", type: .static, targets: ["RSCoreResources"]) ], @@ -19,8 +18,12 @@ let package = Package( name: "RSCoreObjC", dependencies: [], cSettings: [ - .headerSearchPath("include") - ] + .headerSearchPath("include"), + .unsafeFlags(["-fprofile-instr-generate", "-fcoverage-mapping"]) + ], + linkerSettings: [ + .unsafeFlags(["-fprofile-instr-generate"]) + ] ), .target( name: "RSCoreResources", diff --git a/Core/Sources/Core/AppConfig.swift b/RSCore/Sources/RSCore/Shared/AppConfig.swift similarity index 100% rename from Core/Sources/Core/AppConfig.swift rename to RSCore/Sources/RSCore/Shared/AppConfig.swift diff --git a/Core/Sources/Core/Cache.swift b/RSCore/Sources/RSCore/Shared/Cache.swift similarity index 100% rename from Core/Sources/Core/Cache.swift rename to RSCore/Sources/RSCore/Shared/Cache.swift diff --git a/RSCore/Sources/RSCore/Shared/Date+Extensions.swift b/RSCore/Sources/RSCore/Shared/Date+Extensions.swift index 48421cbe5..f1ef88f01 100755 --- a/RSCore/Sources/RSCore/Shared/Date+Extensions.swift +++ b/RSCore/Sources/RSCore/Shared/Date+Extensions.swift @@ -16,14 +16,22 @@ public extension Date { return addingTimeInterval(0.0 - TimeInterval(days: days)) } + func bySubtracting(hours: Int) -> Date { + return addingTimeInterval(0.0 - TimeInterval(hours: hours)) + } + func byAdding(days: Int) -> Date { return addingTimeInterval(TimeInterval(days: days)) } } -private extension TimeInterval { +public extension TimeInterval { init(days: Int) { self.init(days * 24 * 60 * 60) } + + init(hours: Int) { + self.init(hours * 60 * 60) + } } diff --git a/RSParser/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/RSParser/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/RSParser/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/RSWeb/Package.swift b/RSWeb/Package.swift index afa2720fd..68c4553b6 100644 --- a/RSWeb/Package.swift +++ b/RSWeb/Package.swift @@ -12,15 +12,15 @@ let package = Package( targets: ["RSWeb"]), ], dependencies: [ - .package(url: "https://github.com/Ranchero-Software/RSParser.git", .upToNextMinor(from: "2.0.2")), - .package(path: "../Core") + .package(path: "../RSParser"), + .package(path: "../RSCore") ], targets: [ .target( name: "RSWeb", dependencies: [ "RSParser", - "Core" + "RSCore" ], resources: [.copy("UTS46/uts46")], swiftSettings: [.define("SWIFT_PACKAGE")]), @@ -29,7 +29,7 @@ let package = Package( dependencies: [ "RSWeb", "RSParser", - "Core" + "RSCore" ]), ] ) diff --git a/RSWeb/Sources/RSWeb/HTMLMetadataCache.swift b/RSWeb/Sources/RSWeb/HTMLMetadataCache.swift index e93cf12fd..310ac1e2d 100644 --- a/RSWeb/Sources/RSWeb/HTMLMetadataCache.swift +++ b/RSWeb/Sources/RSWeb/HTMLMetadataCache.swift @@ -6,7 +6,7 @@ // import Foundation -import Core +import RSCore @preconcurrency import RSParser public extension Notification.Name { diff --git a/Shared/Images/FeedIconDownloader.swift b/Shared/Images/FeedIconDownloader.swift index f86513a1a..8af01a5d1 100644 --- a/Shared/Images/FeedIconDownloader.swift +++ b/Shared/Images/FeedIconDownloader.swift @@ -11,7 +11,6 @@ import Account import RSCore import RSWeb import RSParser -import Core extension Notification.Name { diff --git a/Shared/Images/ImageDownloader.swift b/Shared/Images/ImageDownloader.swift index 9df7d399a..fcafe8e1f 100644 --- a/Shared/Images/ImageDownloader.swift +++ b/Shared/Images/ImageDownloader.swift @@ -10,7 +10,7 @@ import Foundation import os.log import RSCore import RSWeb -import Core +import RSCore extension Notification.Name { From 6bdd710082d6beaed846beb76fa292fdb4e53953 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Tue, 22 Apr 2025 20:49:14 -0700 Subject: [PATCH 2/3] =?UTF-8?q?Add=20quiet=5Fbuild=5Fand=5Ftest.sh=20?= =?UTF-8?q?=E2=80=94=C2=A0just=20shows=20warnings=20and=20errors.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NetNewsWire.xctestplan | 42 +++++++++++++++++++-------------------- quiet_build_and_test.sh | 44 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 21 deletions(-) create mode 100755 quiet_build_and_test.sh diff --git a/NetNewsWire.xctestplan b/NetNewsWire.xctestplan index 967295866..f5a1d35db 100644 --- a/NetNewsWire.xctestplan +++ b/NetNewsWire.xctestplan @@ -17,6 +17,27 @@ } }, "testTargets" : [ + { + "target" : { + "containerPath" : "container:RSWeb", + "identifier" : "RSWebTests", + "name" : "RSWebTests" + } + }, + { + "target" : { + "containerPath" : "container:", + "identifier" : "RSCoreTests", + "name" : "RSCoreTests" + } + }, + { + "target" : { + "containerPath" : "container:Account", + "identifier" : "AccountTests", + "name" : "AccountTests" + } + }, { "skippedTests" : [ "ScriptingTests\/testFeedOPML()" @@ -27,33 +48,12 @@ "name" : "NetNewsWireTests" } }, - { - "target" : { - "containerPath" : "container:Account", - "identifier" : "AccountTests", - "name" : "AccountTests" - } - }, { "target" : { "containerPath" : "container:RSParser", "identifier" : "RSParserTests", "name" : "RSParserTests" } - }, - { - "target" : { - "containerPath" : "container:RSWeb", - "identifier" : "RSWebTests", - "name" : "RSWebTests" - } - }, - { - "target" : { - "containerPath" : "container:Core", - "identifier" : "CoreTests", - "name" : "CoreTests" - } } ], "version" : 1 diff --git a/quiet_build_and_test.sh b/quiet_build_and_test.sh new file mode 100755 index 000000000..4804d36ff --- /dev/null +++ b/quiet_build_and_test.sh @@ -0,0 +1,44 @@ +#!/bin/bash +set -euo pipefail + +# This script is for checking that both Mac and iOS targets build and that tests pass. +# Note: depends on xcbeautify: + +# === CONFIGURABLE VARIABLES === +PROJECT_PATH="NetNewsWire.xcodeproj" +SCHEME_MAC="NetNewsWire" +SCHEME_IOS="NetNewsWire-iOS" +DESTINATION_MAC="platform=macOS,arch=arm64" +DESTINATION_IOS="platform=iOS Simulator,name=iPhone 16" + +echo "๐Ÿ›  Building macOS target..." +xcodebuild \ + -project "$PROJECT_PATH" \ + -scheme "$SCHEME_MAC" \ + -destination "$DESTINATION_MAC" \ + clean build | xcbeautify --quiet + +echo "๐Ÿ›  Building iOS target..." +xcodebuild \ + -project "$PROJECT_PATH" \ + -scheme "$SCHEME_IOS" \ + -destination "$DESTINATION_IOS" \ + clean build | xcbeautify --quiet + +echo "โœ… Builds completed." + +echo "๐Ÿงช Running tests for macOS target..." +xcodebuild \ + -project "$PROJECT_PATH" \ + -scheme "$SCHEME_MAC" \ + -destination "$DESTINATION_MAC" \ + test | xcbeautify --quiet + +echo "๐Ÿงช Running tests for iOS target..." +xcodebuild \ + -project "$PROJECT_PATH" \ + -scheme "$SCHEME_IOS" \ + -destination "$DESTINATION_IOS" \ + test | xcbeautify --quiet + +echo "๐ŸŽ‰ All builds and tests completed successfully." From 2e68347fe09371f425144c7e0082724b157eef38 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Tue, 22 Apr 2025 21:05:12 -0700 Subject: [PATCH 3/3] Normalize Swift version at 5.10 and platforms at macOS 13 and iOS 17 in Package.swift files. --- Account/Package.swift | 4 ++-- Articles/Package.swift | 4 ++-- ArticlesDatabase/Package.swift | 4 ++-- RSParser/Package.swift | 5 ++--- RSWeb/Package.swift | 4 ++-- Secrets/Package.swift | 4 ++-- SyncDatabase/Package.swift | 4 ++-- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Account/Package.swift b/Account/Package.swift index e05aaec4e..dc591cdbd 100644 --- a/Account/Package.swift +++ b/Account/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.10 import PackageDescription var dependencies: [Package.Dependency] = [ @@ -17,7 +17,7 @@ dependencies.append(contentsOf: [ let package = Package( name: "Account", - platforms: [.macOS(.v13), .iOS(.v16)], + platforms: [.macOS(.v13), .iOS(.v17)], products: [ .library( name: "Account", diff --git a/Articles/Package.swift b/Articles/Package.swift index 4fecd9564..7c124c2e8 100644 --- a/Articles/Package.swift +++ b/Articles/Package.swift @@ -1,9 +1,9 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.10 import PackageDescription let package = Package( name: "Articles", - platforms: [.macOS(.v13), .iOS(.v16)], + platforms: [.macOS(.v13), .iOS(.v17)], products: [ .library( name: "Articles", diff --git a/ArticlesDatabase/Package.swift b/ArticlesDatabase/Package.swift index c44a8ea77..cb13cebfb 100644 --- a/ArticlesDatabase/Package.swift +++ b/ArticlesDatabase/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.10 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -21,7 +21,7 @@ dependencies.append(contentsOf: [ let package = Package( name: "ArticlesDatabase", - platforms: [.macOS(.v13), .iOS(.v16)], + platforms: [.macOS(.v13), .iOS(.v17)], products: [ .library( name: "ArticlesDatabase", diff --git a/RSParser/Package.swift b/RSParser/Package.swift index 8f1206f53..fdfd7e2b2 100644 --- a/RSParser/Package.swift +++ b/RSParser/Package.swift @@ -1,11 +1,10 @@ -// swift-tools-version:5.3 -// The swift-tools-version declares the minimum version of Swift required to build this package. +// swift-tools-version:5.10 import PackageDescription let package = Package( name: "RSParser", - platforms: [.macOS(SupportedPlatform.MacOSVersion.v10_15), .iOS(SupportedPlatform.IOSVersion.v13)], + platforms: [.macOS(.v13), .iOS(.v17)], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( diff --git a/RSWeb/Package.swift b/RSWeb/Package.swift index 68c4553b6..33b01aff5 100644 --- a/RSWeb/Package.swift +++ b/RSWeb/Package.swift @@ -1,10 +1,10 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.10 import PackageDescription let package = Package( name: "RSWeb", - platforms: [.macOS(.v13), .iOS(.v16)], + platforms: [.macOS(.v13), .iOS(.v17)], products: [ .library( name: "RSWeb", diff --git a/Secrets/Package.swift b/Secrets/Package.swift index 48ebdd01f..bcd25a785 100644 --- a/Secrets/Package.swift +++ b/Secrets/Package.swift @@ -1,9 +1,9 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.10 import PackageDescription let package = Package( name: "Secrets", - platforms: [.macOS(.v13), .iOS(.v16)], + platforms: [.macOS(.v13), .iOS(.v17)], products: [ .library( name: "Secrets", diff --git a/SyncDatabase/Package.swift b/SyncDatabase/Package.swift index 1c21715f4..508851bba 100644 --- a/SyncDatabase/Package.swift +++ b/SyncDatabase/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.10 import PackageDescription var dependencies: [Package.Dependency] = [ @@ -18,7 +18,7 @@ dependencies.append(contentsOf: [ let package = Package( name: "SyncDatabase", - platforms: [.macOS(.v13), .iOS(.v16)], + platforms: [.macOS(.v13), .iOS(.v17)], products: [ .library( name: "SyncDatabase",