Skip to content

Commit ad99355

Browse files
[HACK WEEK] Integrate periphery (#15962)
2 parents dc42a78 + 147232e commit ad99355

File tree

7 files changed

+180
-1
lines changed

7 files changed

+180
-1
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"

Scripts/Periphery/periphery_baseline.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
3+
# Define the Periphery version
4+
PERIPHERY_VERSION="3.2.0"
5+
6+
# Define the path to the periphery executable
7+
REPO_ROOT="$(git rev-parse --show-toplevel)"
8+
PERIPHERY_FOLDER_PATH="${REPO_ROOT}/vendor/Periphery"
9+
PERIPHERY_PATH="${PERIPHERY_FOLDER_PATH}/periphery"
10+
11+
# Function to compare versions
12+
version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
13+
14+
# Function to update and run Periphery
15+
update_periphery() {
16+
echo "Downloading version $PERIPHERY_VERSION..."
17+
# Download the zip file
18+
curl -L "https://github.com/peripheryapp/periphery/releases/download/${PERIPHERY_VERSION}/periphery-${PERIPHERY_VERSION}.zip" -o "periphery.zip"
19+
20+
# Create target directory if it doesn't exist
21+
mkdir -p "$PERIPHERY_FOLDER_PATH"
22+
23+
# Unzip the contents directly into the target directory, overwriting files
24+
unzip -o periphery.zip -d "$PERIPHERY_FOLDER_PATH"
25+
26+
# Clean up the zip file
27+
rm periphery.zip
28+
29+
# Make sure the executable is executable
30+
chmod +x "$PERIPHERY_PATH"
31+
32+
echo "Download and setup complete."
33+
}
34+
35+
# Check if the executable exists and is executable
36+
if [ -x "$PERIPHERY_PATH" ]; then
37+
echo "Executable found. Checking version..."
38+
# Get the current installed version
39+
CURRENT_VERSION=$("$PERIPHERY_PATH" version)
40+
41+
# Compare the current version with the desired version
42+
if version_gt "$PERIPHERY_VERSION" "$CURRENT_VERSION"; then
43+
echo "Current version ($CURRENT_VERSION) is older than $PERIPHERY_VERSION. Updating..."
44+
update_periphery
45+
else
46+
echo "Current version ($CURRENT_VERSION) is up-to-date."
47+
fi
48+
else
49+
echo "Executable not found. Downloading..."
50+
update_periphery
51+
fi
52+
53+
echo "Running periphery scan..."
54+
# Run periphery scan with additional arguments
55+
"$PERIPHERY_PATH" scan --disable-update-check --relative-results "$@"

0 commit comments

Comments
 (0)