Skip to content

Commit 736c11d

Browse files
authored
Merge branch 'trunk' into woo-pos-enable-barcode-scanning-i2-feature-flag
2 parents 4c55640 + 38cc12e commit 736c11d

File tree

124 files changed

+1833
-621
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+1833
-621
lines changed

.buildkite/commands/build-for-testing.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ echo "--- :hammer_and_wrench: Building"
1818
bundle exec fastlane build_for_testing
1919

2020
echo "--- :arrow_up: Upload Build Products"
21-
tar -cf build-products.tar DerivedData/Build/Products/
21+
tar -cf build-products.tar DerivedData/Build/Products/ DerivedData/Index.noindex/DataStore/
2222
buildkite-agent artifact upload build-products.tar
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash -eu
2+
3+
if .buildkite/commands/should-skip-job.sh --job-type validation; then
4+
exit 0
5+
fi
6+
7+
### Prepare
8+
9+
echo '--- 📦 Downloading Build Artifacts'
10+
buildkite-agent artifact download build-products.tar .
11+
tar -xf build-products.tar
12+
13+
### Run the Tests
14+
15+
PERIPHERY_OUTPUT_FILE="periphery-errors.txt"
16+
17+
echo '+++ :zombie: Detecting unused code'
18+
set +e
19+
# This is the script in the root.
20+
./Scripts/Periphery/setup-and-run-periphery.sh \
21+
--strict --quiet --skip-build --index-store-path 'DerivedData/Index.noindex/DataStore/' \
22+
--write-results "$PERIPHERY_OUTPUT_FILE"
23+
TESTS_EXIT_STATUS=$?
24+
set -e
25+
26+
# Handle the result of the periphery scan
27+
if [[ "$TESTS_EXIT_STATUS" -ne 0 ]]; then
28+
echo '😱 Unused code detected!'
29+
echo ''
30+
echo '💡 You can run Periphery locally by calling `setup-and-run-periphery.sh` from `./Scripts/Periphery/` in the repo.'
31+
echo ''
32+
echo 'If you think there is a false positive violation, please check the known issues of Periphery at https://github.com/peripheryapp/periphery/issues.'
33+
echo 'If you think a violation is valid but it should be surpressed for any reason, please apply the `// periphery: ignore - {your-reason-here}` comment.'
34+
echo ''
35+
# Add the periphery errors as a Buildkite annotation
36+
(echo "### Periphery found unused code"; echo ''; echo '```'; cat "$PERIPHERY_OUTPUT_FILE"; echo ''; echo '```') \
37+
| buildkite-agent annotate --context periphery --style error
38+
else
39+
echo '😊 No unused code found.'
40+
buildkite-agent annotate --context periphery --style success 'No unused code found by Periphery :tada:'
41+
fi
42+
43+
echo '--- 🚦 Report Exit code'
44+
exit $TESTS_EXIT_STATUS

.buildkite/pipeline.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ steps:
7979
agents:
8080
queue: linter
8181

82+
- label: "🧟 Detect unused code"
83+
command: ".buildkite/commands/run-periphery.sh"
84+
depends_on: build
85+
plugins: [$CI_TOOLKIT]
86+
notify:
87+
- github_commit_status:
88+
context: Periphery - Detect unused code
89+
8290
- label: 🧹 Lint Translations
8391
command: gplint /workdir/WooCommerce/Resources/AppStoreStrings.pot
8492
plugins:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,6 @@ WooCommerce/WooCommerceScreenshots/Mocks/vendor/
102102
Modules/.build
103103
Modules/.swiftpm/configuration/registries.json
104104
Modules/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
105+
106+
# Periphery install
107+
vendor/Periphery/

.periphery.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# This option tells Periphery to not report any Swift code as unused if it's accessible from Objective-C. This includes any class that inherits from NSObject, and any method or property marked with the @objc or @objcMembers attribute.
2+
# Woocommerce-ios, is a mixed Swift and Objective-C project. Swift code is often called from Objective-C and vice-versa. Without this flag, Periphery would incorrectly flag Swift code that is only used by Objective-C parts of the app as "unused," which would be a false positive. Setting this to true is essential for getting accurate results in a mixed-language codebase.
3+
retain_objc_accessible: true
4+
5+
# This option prevents Periphery from flagging unused parameters in protocol method implementations.
6+
# Often, a protocol will define a method with parameters that are needed by some, but not all, conforming types. If a specific implementation doesn't need to use a parameter, Swift still requires that the method signature matches the protocol exactly. Periphery would normally see this unused parameter and flag it. However, removing it would cause a compile error because the method signature would no longer match the protocol. This flag tells Periphery to ignore these cases, avoiding false positives.
7+
retain_unused_protocol_func_params: true
8+
9+
# This option retains all code within a previews struct that conforms to SwiftUI's PreviewProvider protocol.
10+
# SwiftUI Previews are a powerful feature for UI development in Xcode. The code you write for previews is often not directly called from your main application target; it's used by Xcode's canvas. Periphery would see this and incorrectly mark the preview code as unused. This flag correctly tells Periphery to always keep preview provider code, which is the desired behavior.
11+
retain_swift_ui_previews: true
12+
13+
# This option disables the check for public declarations that are only used within their own module.
14+
# Normally, Periphery would suggest changing public to internal or private in these cases to reduce the public API surface of a module.
15+
disable_redundant_public_analysis: false
16+
17+
# By default, Periphery will scan all targets in your project, including test targets.
18+
# This can lead to false positives, as test code is not part of the main application.
19+
# This option tells Periphery to exclude all test targets from the scan, ensuring that only the application code is analyzed.
20+
exclude_tests: true
21+
22+
schemes:
23+
- WooCommerce
24+
25+
project: WooCommerce.xcworkspace
26+
27+
# Used for local run by `periphery scan`
28+
# This will not conflict with CI build configuration because of build skipping by `--skip-build` and `--index-store-path`
29+
build_arguments:
30+
- -xcconfig
31+
- config/WooCommerce.debug.xcconfig
32+
33+
# A baseline is used to manage the large number of warnings from a mature codebase.
34+
# It contains a snapshot of all "existing/acceptable" warnings. Periphery will ignore all
35+
# warnings in this file, allowing you to focus on new issues in pull requests.
36+
#
37+
# After fixing existing warnings, regenerate this file with:
38+
# periphery scan --write-baseline Scripts/Periphery/periphery_baseline.json
39+
baseline: Scripts/Periphery/periphery_baseline.json
40+
41+
exclude_targets:
42+
- GenerateCredentials
43+
- WooCommerceScreenshots
44+
- WordPressAuthenticator
45+
- WordPressAuthenticatorTests
46+
- WooCommerceTests
47+
- WooCommerceUITests
48+
- NotificationExtension
49+
- StoreWidgetsExtension
50+
- WatchWidgetsExtension
51+
- "Woo Watch App"
52+
- Fakes
53+
- XcodeTarget_WooCommerceTests
54+
- XcodeTarget_WooCommerceUITests
55+
- XcodeTarget_WordPressAuthenticatorTests
56+
57+
index_exclude:
58+
- Pods/*
59+
- vendor/**
60+
- BuildTools/.build/**
61+
- "**/Tests/*"
62+
- "**/Test*/*"
63+
- "docs/*"
64+
- "fastlane/*"
65+
- "config/*"
66+
- "**/*.xib"
67+
- "**/*.storyboard"
68+
- "**/*.generated.swift"

Modules/Sources/Fakes/Networking.generated.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,18 @@ extension Networking.InboxNote {
631631
)
632632
}
633633
}
634+
extension Networking.JetpackConnectionData {
635+
/// Returns a "ready to use" type filled with fake values.
636+
///
637+
public static func fake() -> Networking.JetpackConnectionData {
638+
.init(
639+
currentUser: .fake(),
640+
isRegistered: .fake(),
641+
connectionOwner: .fake(),
642+
blogID: .fake()
643+
)
644+
}
645+
}
634646
extension Networking.JetpackUser {
635647
/// Returns a "ready to use" type filled with fake values.
636648
///
@@ -640,7 +652,8 @@ extension Networking.JetpackUser {
640652
isPrimary: .fake(),
641653
username: .fake(),
642654
wpcomUser: .fake(),
643-
gravatar: .fake()
655+
gravatar: .fake(),
656+
blogID: .fake()
644657
)
645658
}
646659
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import Codegen
2+
import Foundation
3+
4+
/// Mapper: Jetpack connection data
5+
///
6+
struct JetpackConnectionDataMapper: Mapper {
7+
8+
func map(response: Data) throws -> JetpackConnectionData {
9+
let decoder = JSONDecoder()
10+
return try decoder.decode(JetpackConnectionData.self, from: response)
11+
}
12+
}
13+
14+
/// JetpackConnectionData Disposable Entity:
15+
/// This entity allows us to parse JetpackUser with JSONDecoder.
16+
///
17+
public struct JetpackConnectionData: Decodable, GeneratedFakeable, GeneratedCopiable {
18+
/// The connection state for the authenticated user
19+
public let currentUser: JetpackUser
20+
21+
/// Whether the site is already registered with Jetpack.
22+
/// This field is available only from Jetpack 14.4, so would be nil on older versions.
23+
/// Ref: pe5sF9-401-p2
24+
/// periphery: ignore - used in UI module
25+
public let isRegistered: Bool?
26+
27+
/// Username of the Jetpack connection owner.
28+
/// This field is non-nil for sites that already register a connection with Jetpack.
29+
/// periphery: ignore - used in UI module
30+
public let connectionOwner: String?
31+
32+
/// WP blog ID, available only if site has once connected to Jetpack.
33+
/// periphery: ignore - used in UI module
34+
public let blogID: Int64?
35+
36+
/// periphery: ignore - used by codegen
37+
public init(currentUser: JetpackUser,
38+
isRegistered: Bool?,
39+
connectionOwner: String?,
40+
blogID: Int64?) {
41+
self.currentUser = currentUser
42+
self.isRegistered = isRegistered
43+
self.connectionOwner = connectionOwner
44+
self.blogID = blogID
45+
}
46+
47+
public init(from decoder: Decoder) throws {
48+
let container = try decoder.container(keyedBy: CodingKeys.self)
49+
currentUser = try container.decode(JetpackUser.self, forKey: .currentUser)
50+
isRegistered = try container.decodeIfPresent(Bool.self, forKey: .isRegistered)
51+
connectionOwner = try? container.decodeIfPresent(String.self, forKey: .connectionOwner)
52+
blogID = currentUser.blogID // moved to data for easier access
53+
}
54+
55+
private enum CodingKeys: String, CodingKey {
56+
case currentUser
57+
case isRegistered
58+
case connectionOwner
59+
}
60+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Foundation
2+
3+
/// Mapper: Jetpack connection registration
4+
///
5+
/// periphery: ignore - used in `JetpackConnectionRemote`
6+
struct JetpackConnectionProvisionMapper: Mapper {
7+
8+
/// (Attempts) to extract the updated `currentUser` field from a given JSON Encoded response.
9+
///
10+
func map(response: Data) throws -> JetpackConnectionProvisionResponse {
11+
let decoder = JSONDecoder()
12+
decoder.keyDecodingStrategy = .convertFromSnakeCase
13+
return try decoder.decode(JetpackConnectionProvisionResponse.self, from: response)
14+
}
15+
}
16+
17+
public struct JetpackConnectionProvisionResponse: Decodable {
18+
public let userId: Int64
19+
public let scope: String
20+
public let secret: String
21+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Foundation
2+
3+
/// Mapper: Jetpack connection registration
4+
///
5+
/// periphery: ignore - used in `JetpackConnectionRemote`
6+
struct JetpackConnectionRegistrationMapper: Mapper {
7+
8+
/// (Attempts) to extract the updated `currentUser` field from a given JSON Encoded response.
9+
///
10+
func map(response: Data) throws -> JetpackConnectionRegistration {
11+
let decoder = JSONDecoder()
12+
return try decoder.decode(JetpackConnectionRegistration.self, from: response)
13+
}
14+
}
15+
16+
struct JetpackConnectionRegistration: Decodable {
17+
let authorizeUrl: String
18+
}

Modules/Sources/Networking/Mapper/JetpackConnectionURLMapper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ struct JetpackConnectionURLMapper: Mapper {
88
///
99
func map(response: Data) throws -> URL {
1010
guard let escapedString = String(data: response, encoding: .utf8) else {
11-
throw JetpackConnectionRemote.ConnectionError.malformedURL
11+
throw JetpackConnectionError.malformedURL
1212
}
1313
// The API returns an escaped string with double quotes, so we need to clean it up.
1414
let urlString = escapedString

0 commit comments

Comments
 (0)