Skip to content

Commit f39d3a1

Browse files
authored
THRIFT-5957: Add phpstan static analysis with CI guardrail (#3436)
Client: php Adds phpstan/phpstan ^1.12 as a require-dev dependency, plus a "scripts.phpstan" composer alias for local use. Adds lib/php/phpstan.neon (level 1) targeting lib/php/lib/ with test/bootstrap.php for autoload, and a generated baseline. Adds a "Run phpstan" step alongside the existing per-language steps (cppcheck, flake8, phpcs, rubocop) in the sca.yml workflow, and wires its outcome into the aggregate "Fail if any SCA check failed" gate. Runs with --error- format=github so findings show up as inline annotations on PRs. Generated-by: Claude Opus 4.7 (1M context)
1 parent ef7fda7 commit f39d3a1

6 files changed

Lines changed: 56 additions & 3 deletions

File tree

.github/workflows/sca.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ jobs:
177177
composer install --quiet
178178
./vendor/bin/phpcs
179179
180+
- name: Run phpstan
181+
id: phpstan
182+
continue-on-error: true
183+
run: |
184+
# PHP static analysis
185+
./vendor/bin/phpstan analyse -c lib/php/phpstan.neon --no-progress --error-format=github
186+
180187
- name: Run rubocop
181188
id: rubocop
182189
continue-on-error: true
@@ -209,6 +216,7 @@ jobs:
209216
CPPCHECK_OUTCOME: ${{ steps.cppcheck.outcome }}
210217
FLAKE8_OUTCOME: ${{ steps.flake8.outcome }}
211218
PHPCS_OUTCOME: ${{ steps.phpcs.outcome }}
219+
PHPSTAN_OUTCOME: ${{ steps.phpstan.outcome }}
212220
RUBOCOP_OUTCOME: ${{ steps.rubocop.outcome }}
213221
run: |
214222
failed=0
@@ -225,6 +233,10 @@ jobs:
225233
echo "::error::Step 'phpcs' failed (outcome: $PHPCS_OUTCOME)"
226234
failed=1
227235
fi
236+
if [ "$PHPSTAN_OUTCOME" != "success" ]; then
237+
echo "::error::Step 'phpstan' failed (outcome: $PHPSTAN_OUTCOME)"
238+
failed=1
239+
fi
228240
if [ "$RUBOCOP_OUTCOME" != "success" ]; then
229241
echo "::error::Step 'rubocop' failed (outcome: $RUBOCOP_OUTCOME)"
230242
failed=1

composer.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@
2424
"phpunit/phpunit": "^9.5",
2525
"squizlabs/php_codesniffer": "^3.10",
2626
"php-mock/php-mock-phpunit": "^2.10",
27+
"phpstan/phpstan": "^1.12",
2728
"ext-json": "*",
2829
"ext-xml": "*",
2930
"ext-curl": "*",
3031
"ext-pcntl": "*"
3132
},
33+
"scripts": {
34+
"phpstan": "phpstan analyse -c lib/php/phpstan.neon"
35+
},
3236
"autoload": {
3337
"psr-4": {"Thrift\\": "lib/php/lib/"}
3438
},

lib/php/lib/Transport/TBufferedTransport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public function readAll($len)
132132
} elseif ($have == $len) {
133133
$data = $this->rBuf_;
134134
$this->rBuf_ = '';
135-
} elseif ($have > $len) {
135+
} else {
136136
$data = TStringFuncFactory::create()->substr($this->rBuf_, 0, $len);
137137
$this->rBuf_ = TStringFuncFactory::create()->substr($this->rBuf_, $len);
138138
}

lib/php/lib/Transport/TSocketPool.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ public function open()
192192
$numServers = count($this->servers_);
193193

194194
for ($i = 0; $i < $numServers; ++$i) {
195-
// This extracts the $host and $port variables
196-
extract($this->servers_[$i]);
195+
$host = $this->servers_[$i]['host'];
196+
$port = $this->servers_[$i]['port'];
197197

198198
// Check APCu cache for a record of this server being down
199199
$failtimeKey = 'thrift_failtime:' . $host . ':' . $port . '~';

lib/php/phpstan-baseline.neon

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
parameters:
2+
ignoreErrors:
3+
-
4+
message: "#^Method Thrift\\\\ClassLoader\\\\ThriftClassLoader\\:\\:findFile\\(\\) should return string but return statement is missing\\.$#"
5+
count: 1
6+
path: lib/ClassLoader/ThriftClassLoader.php
7+
8+
-
9+
message: "#^Method Thrift\\\\Protocol\\\\TJSONProtocol\\:\\:writeStructBegin\\(\\) should return int but return statement is missing\\.$#"
10+
count: 1
11+
path: lib/Protocol/TJSONProtocol.php
12+
13+
-
14+
message: "#^Method Thrift\\\\Protocol\\\\TJSONProtocol\\:\\:writeStructEnd\\(\\) should return int but return statement is missing\\.$#"
15+
count: 1
16+
path: lib/Protocol/TJSONProtocol.php
17+
18+
-
19+
message: "#^Method Thrift\\\\Protocol\\\\TSimpleJSONProtocol\\:\\:writeStructBegin\\(\\) should return int but return statement is missing\\.$#"
20+
count: 1
21+
path: lib/Protocol/TSimpleJSONProtocol.php
22+
23+
-
24+
message: "#^Method Thrift\\\\Protocol\\\\TSimpleJSONProtocol\\:\\:writeStructEnd\\(\\) should return int but return statement is missing\\.$#"
25+
count: 1
26+
path: lib/Protocol/TSimpleJSONProtocol.php

lib/php/phpstan.neon

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
parameters:
2+
level: 1
3+
paths:
4+
- lib
5+
bootstrapFiles:
6+
- test/bootstrap.php
7+
treatPhpDocTypesAsCertain: false
8+
excludePaths:
9+
- test/Resources/packages/*
10+
includes:
11+
- phpstan-baseline.neon

0 commit comments

Comments
 (0)