Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filed for reference – Steps taken to experiment with SPM #738

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f98be36
Group core API types in `CoreAPI/` folder, with tests
mokagio Feb 27, 2024
08ae249
Move Account* types used in WordPressAuth to dedicated folder
mokagio Feb 27, 2024
982f23f
Move `WordPressComServiceRemote` into `ComAPIBasic` folder
mokagio Feb 27, 2024
702c1ff
Move everything else under `WordPressAndJetpack`
mokagio Feb 27, 2024
1ad85a7
Create target for RFC3339 (NSDate+WordPressJSON)
mokagio Feb 27, 2024
542a84e
Move "CoreAPI" to dedicated target – WIP n.1
mokagio Feb 27, 2024
f41b3a1
WIP n.2 – Move more stubs around
mokagio Feb 27, 2024
99e2e87
Update CocoaPods
mokagio Feb 27, 2024
bd20a95
WIP n.3 – Tests pass!
mokagio Feb 27, 2024
b71d784
WIP n.4 – Track missing CoreAPI header (is it even needed?)
mokagio Feb 27, 2024
281e9d0
WIP n.5 – Track xcscheme for CoreAPI
mokagio Feb 27, 2024
12ecc02
WIP n.6 – On the way to make WPKit compile
mokagio Feb 27, 2024
66e5909
Remove two JSON files from the compiled sources in Kit tests
mokagio Feb 27, 2024
55f6669
WIP n.7 – Tests builds and pass!
mokagio Feb 27, 2024
aa1b9ab
Working Package.swift with RFC3339
mokagio Feb 27, 2024
d39a05e
WIP Package.swift – CoreAPITests make them work
mokagio Feb 28, 2024
c863c2e
CoreAPITests WIP n.2 – Add Package.swift
mokagio Feb 28, 2024
d9f70b1
CoreAPITests – Add Fastlane cmd to test
mokagio Feb 28, 2024
70cba0e
CoreAPITests WIP n.3 – .resolved
mokagio Feb 28, 2024
82c3a3c
CoreAPI n.5 - Reformat stuff after Code
mokagio Feb 28, 2024
518618e
CoreAPITests WIP n.4 – Keep tests working in Xcode
mokagio Feb 28, 2024
6a6b49f
Try to add subspecs, but RFC3339 fails
mokagio Feb 28, 2024
fb0d499
Update SwiftLint config for SPM
mokagio Feb 28, 2024
fefb636
Ignore `.swiftpm`
mokagio Feb 28, 2024
cac5c03
Add workaround to locate `Bundle` across setups
mokagio Feb 28, 2024
e0cdd9a
Update `Package.swift` after moving the RFC3339 files
mokagio Feb 28, 2024
5f54851
Use `XCTUnwrap` so SPM tests won't waste time crash and restart
mokagio Feb 28, 2024
58ee932
Use correct `Package.swift` setup to get CoreAPITests to succeed
mokagio Feb 28, 2024
b7fbe4b
Move RFC3339 to `Sources/` for SPM structure alignment
mokagio Feb 28, 2024
059049d
Move CoreAPI to `Sources/` and `Tests/` for SPM structure alignment
mokagio Feb 28, 2024
e21578c
Update `podspec` to reflect new folder structure (RFC339 still fails)
mokagio Feb 28, 2024
1d10735
Remove a dead reference to CoreAPI in WordPressKit project
mokagio Feb 28, 2024
db1adf7
Move WordPressKit sources and tests in SPM-compliant location
mokagio Feb 28, 2024
dbef350
Update `podspec` with new files locations
mokagio Feb 28, 2024
a6de8c3
Rename one `Either.swift` to `Either2.swift` to please CocoaPods
mokagio Feb 28, 2024
1b4fcc8
Ditch the whole RFC3339 target. Convert to Swift and move in CoreAPI.
mokagio Feb 28, 2024
df9cd89
Remove a duplicated JSON stub entry
mokagio Feb 28, 2024
0c98cac
Remove CoreAPI target as well. Only build in SPM.
mokagio Feb 28, 2024
4312a36
Update podspec for new folder structure
mokagio Feb 28, 2024
d9fff53
Track note regarding paths in Package.swift
mokagio Feb 28, 2024
20c543b
Remove duplicated `Either` — It didn't need to be shared
mokagio Feb 28, 2024
0ea1e0d
Remove CoreAPI subspec tests because they are failing
mokagio Feb 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,7 @@ vendor/
iOSInjectionProject/

# SwiftLint Remote Config Cache
.swiftlint/RemoteConfigCache
.swiftlint/RemoteConfigCache

# SPM
.swiftpm
4 changes: 4 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ swiftlint_version: 0.54.0
parent_config: https://raw.githubusercontent.com/Automattic/swiftlint-config/0f8ab6388bd8d15a04391825ab125f80cfb90704/.swiftlint.yml
remote_timeout: 10.0

excluded:
- .swiftpm
- .build

opt_in_rules:
- overridden_super_call
- discarded_notification_center_observer
Expand Down
21 changes: 12 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.6)
CFPropertyList (3.0.7)
base64
nkf
rexml
activesupport (7.1.2)
activesupport (7.1.3.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
Expand Down Expand Up @@ -39,16 +41,16 @@ GEM
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
bigdecimal (3.1.5)
bigdecimal (3.1.6)
claide (1.1.0)
claide-plugins (0.9.2)
cork
nap
open4 (~> 1.3)
cocoapods (1.14.3)
cocoapods (1.15.2)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.14.3)
cocoapods-core (= 1.15.2)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 2.1, < 3.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
Expand All @@ -65,7 +67,7 @@ GEM
xcodeproj (>= 1.23.0, < 2.0)
cocoapods-check (1.1.0)
cocoapods (~> 1.0)
cocoapods-core (1.14.3)
cocoapods-core (1.15.2)
activesupport (>= 5.0, < 8)
addressable (~> 2.8)
algoliasearch (~> 1.0)
Expand All @@ -88,7 +90,7 @@ GEM
colored2 (3.1.2)
commander (4.6.0)
highline (~> 2.0.0)
concurrent-ruby (1.2.2)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
cork (0.3.0)
colored2 (~> 3.1)
Expand Down Expand Up @@ -272,7 +274,7 @@ GEM
language_server-protocol (3.17.0.3)
mini_magick (4.12.0)
mini_mime (1.1.5)
minitest (5.20.0)
minitest (5.22.2)
molinillo (0.8.0)
multi_json (1.15.0)
multipart-post (2.3.0)
Expand All @@ -281,6 +283,7 @@ GEM
nap (1.1.0)
naturally (2.2.1)
netrc (0.11.0)
nkf (0.2.0)
no_proxy_fix (0.1.2)
octokit (8.1.0)
base64
Expand Down Expand Up @@ -354,7 +357,7 @@ GEM
unicode-display_width (2.5.0)
webrick (1.8.1)
word_wrap (1.0.0)
xcodeproj (1.23.0)
xcodeproj (1.24.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
Expand Down
41 changes: 41 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"pins" : [
{
"identity" : "alamofire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire",
"state" : {
"revision" : "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad",
"version" : "5.8.1"
}
},
{
"identity" : "ohhttpstubs",
"kind" : "remoteSourceControl",
"location" : "https://github.com/AliSoftware/OHHTTPStubs",
"state" : {
"revision" : "12f19662426d0434d6c330c6974d53e2eb10ecd9",
"version" : "9.1.0"
}
},
{
"identity" : "wordpress-ios-shared",
"kind" : "remoteSourceControl",
"location" : "https://github.com/wordpress-mobile/WordPress-iOS-Shared.git",
"state" : {
"revision" : "f22f2bf5612b2d1f1b41bf27d646df5bd80c5dfa",
"version" : "2.3.0"
}
},
{
"identity" : "wpxmlrpc",
"kind" : "remoteSourceControl",
"location" : "https://github.com/wordpress-mobile/wpxmlrpc",
"state" : {
"revision" : "bfc413d336bdeaab89e62dc483380baa99b2257e",
"version" : "0.10.0"
}
}
],
"version" : 2
}
44 changes: 44 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// swift-tools-version: 5.9

import PackageDescription

let package = Package(
name: "WordPressKit",
platforms: [.iOS(.v13)],
products: [
.library(
name: "CoreAPI",
targets: ["CoreAPI"]
),
],
dependencies: [
.package(url: "https://github.com/wordpress-mobile/WordPress-iOS-Shared.git", from: "2.3.0"),
.package(url: "https://github.com/wordpress-mobile/wpxmlrpc", from: "0.10.0"),
// Test dependencies
.package(url: "https://github.com/AliSoftware/OHHTTPStubs", from: "9.1.0"),
.package(url: "https://github.com/Alamofire/Alamofire", from: "5.8.1"),
],
targets: [
.target(
name: "CoreAPI",
dependencies: [
.product(name: "WordPressShared", package: "WordPress-iOS-Shared"),
"wpxmlrpc",
],
path: "Sources/CoreAPI"
),
.testTarget(
name: "CoreAPITests",
dependencies: [
.target(name: "CoreAPI"),
.product(name: "OHHTTPStubs", package: "OHHTTPStubs"),
.product(name: "OHHTTPStubsSwift", package: "OHHTTPStubs"),
"Alamofire",
],
path: "Tests/CoreAPITests",
resources: [
.process("Stubs") // Relative to path
]
),
]
)
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 64af6d71574c7a92d01a9446aa874e066917ebe5

COCOAPODS: 1.14.3
COCOAPODS: 1.15.2
2 changes: 0 additions & 2 deletions WordPressKit/Either.swift → Sources/CoreAPI/Either.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Foundation

enum Either<L, R> {
case left(L)
case right(R)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import UIKit

/// URLAuthenticationChallenge Handler: It's up to the Host App to actually use this, whenever `WordPressOrgXMLRPCApi.onChallenge` is hit!
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extension URLSession {
/// - parentProgress: A `Progress` instance that will be used as the parent progress of the HTTP request's overall
/// progress. See the function documentation regarding requirements on this argument.
/// - errorType: The concret endpoint error type.
func perform<E: LocalizedError>(
public func perform<E: LocalizedError>(
request builder: HTTPRequestBuilder,
acceptableStatusCodes: [ClosedRange<Int>] = [200...299],
taskCreated: ((Int) -> Void)? = nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import wpxmlrpc
///
/// Calling this class's url related functions (the ones that changes path, query, etc) does not modify the
/// original URL string. The URL will be perserved in the final result that's returned by the `build` function.
final class HTTPRequestBuilder {
enum Method: String, CaseIterable {
public final class HTTPRequestBuilder {
public enum Method: String, CaseIterable {
case get = "GET"
case post = "POST"
case put = "PUT"
Expand All @@ -28,7 +28,7 @@ final class HTTPRequestBuilder {
private(set) var multipartForm: [MultipartFormField]?
private(set) var xmlrpcRequest: XMLRPCRequest?

init(url: URL) {
public init(url: URL) {
assert(url.scheme == "http" || url.scheme == "https")
assert(url.host != nil)

Expand All @@ -43,7 +43,7 @@ final class HTTPRequestBuilder {
/// Append path to the original URL.
///
/// The argument will be appended to the original URL as it is.
func append(percentEncodedPath path: String) -> Self {
public func append(percentEncodedPath path: String) -> Self {
assert(!path.contains("?") && !path.contains("#"), "Path should not have query or fragment: \(path)")

appendedPath = Self.join(appendedPath, path)
Expand Down Expand Up @@ -78,11 +78,11 @@ final class HTTPRequestBuilder {
return self
}

func query(name: String, value: String?, override: Bool = false) -> Self {
public func query(name: String, value: String?, override: Bool = false) -> Self {
append(query: [URLQueryItem(name: name, value: value)], override: override)
}

func query(_ parameters: [String: Any]) -> Self {
public func query(_ parameters: [String: Any]) -> Self {
append(query: parameters.flatten(), override: false)
}

Expand Down Expand Up @@ -141,7 +141,7 @@ final class HTTPRequestBuilder {
return self
}

func build(encodeBody: Bool = false) throws -> URLRequest {
public func build(encodeBody: Bool = false) throws -> URLRequest {
var components = original

var newPath = Self.join(components.percentEncodedPath, appendedPath)
Expand Down
File renamed without changes.
30 changes: 30 additions & 0 deletions Sources/CoreAPI/NSDate+RFC3339.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Foundation

public extension NSDate {

@objc
static func rfc3339DateFormatter() -> DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) as TimeZone
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
return formatter
}

/// Parses a date string
///
/// Dates in the format specified in http://www.w3.org/TR/NOTE-datetime should be OK.
/// The kind of dates returned by the REST API should match that format, even if the doc promises ISO 8601.
///
/// Parsing the full ISO 8601, or even RFC 3339 is more complex than this, and makes no sense right now.
/// @warning this method doesn't support fractional seconds or dates with leap seconds (23:59:60 turns into 23:59:00)
@objc(dateWithWordPressComJSONString:)
static func with(wordPressComJSONString jsonString: String) -> Date? {
self.rfc3339DateFormatter().date(from: jsonString)
}

@objc
func WordPressComJSONString() -> String? {
NSDate.rfc3339DateFormatter().string(from: self as Date)
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extension Swift.Result {
public extension Swift.Result {

// Notice there are no explicit unit tests for this utility because it is implicitly tested via the consuming code's tests.
func execute(onSuccess: (Success) -> Void, onFailure: (Failure) -> Void) {
Expand Down
44 changes: 44 additions & 0 deletions Sources/CoreAPI/StringEncoding+IANA.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Foundation

extension String.Encoding {
/// See: https://www.iana.org/assignments/character-sets/character-sets.xhtml
init?(ianaCharsetName: String) {
let encoding: CFStringEncoding = CFStringConvertIANACharSetNameToEncoding(ianaCharsetName as CFString)
guard encoding != kCFStringEncodingInvalidId,
let builtInEncoding = CFStringBuiltInEncodings(rawValue: encoding)
else {
return nil
}

switch builtInEncoding {
case .macRoman:
self = .macOSRoman
case .windowsLatin1:
self = .windowsCP1252
case .isoLatin1:
self = .isoLatin1
case .nextStepLatin:
self = .nextstep
case .ASCII:
self = .ascii
case .unicode:
self = .unicode
case .UTF8:
self = .utf8
case .nonLossyASCII:
self = .nonLossyASCII
case .UTF16BE:
self = .utf16BigEndian
case .UTF16LE:
self = .utf16LittleEndian
case .UTF32:
self = .utf32
case .UTF32BE:
self = .utf32BigEndian
case .UTF32LE:
self = .utf32LittleEndian
@unknown default:
return nil
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public final class WordPressComOAuthClient: NSObject {
.mapSuccess { response in
let responseObject = try JSONSerialization.jsonObject(with: response.body)

WPKitLogVerbose("Received OAuth2 response: \(self.cleanedUpResponseForLogging(responseObject as AnyObject? ?? "nil" as AnyObject))")
// WPKitLogVerbose("Received OAuth2 response: \(self.cleanedUpResponseForLogging(responseObject as AnyObject? ?? "nil" as AnyObject))")

guard let responseDictionary = responseObject as? [String: AnyObject] else {
throw URLError(.cannotParseResponse)
Expand Down Expand Up @@ -380,7 +380,7 @@ public final class WordPressComOAuthClient: NSObject {
.perform(request: builder, errorType: AuthenticationFailure.self)
.mapUnacceptableStatusCodeError(AuthenticationFailure.init(response:body:))
.mapSuccess { response in
WPKitLogVerbose("Received Social Login Oauth response.")
// WPKitLogVerbose("Received Social Login Oauth response.")

// Make sure we received expected data.
let responseObject = try? JSONSerialization.jsonObject(with: response.body)
Expand Down Expand Up @@ -700,7 +700,7 @@ public final class WordPressComOAuthClient: NSObject {
.mapSuccess { response in
let responseObject = try JSONSerialization.jsonObject(with: response.body)

WPKitLogVerbose("Received Social Login Oauth response: \(self.cleanedUpResponseForLogging(responseObject as AnyObject? ?? "nil" as AnyObject))")
// WPKitLogVerbose("Received Social Login Oauth response: \(self.cleanedUpResponseForLogging(responseObject as AnyObject? ?? "nil" as AnyObject))")
guard let responseDictionary = responseObject as? [String: AnyObject],
let responseData = responseDictionary["data"] as? [String: AnyObject],
let authToken = responseData["bearer_token"] as? String else {
Expand Down
Loading