Wire Psalm into CI, fix a real bug it found in user-migration import

RepositoryImportSource::copyToFolder() called putContent() on the generic
return type of Node::get(), which doesn't declare that method -- only
File does. Existing-file overwrite during a per-user restore would have
fatally errored at runtime; added an instanceof check and a resource leak
fix (finally-close) while there. Also guarded getFileAsStream() against
fopen() returning false.

Everything else Psalm (strict level) currently flags is mechanical
(missing `final` on leaf classes -- applied everywhere safe) or pre-existing
array-shape/type gaps, captured in psalm-baseline.xml so CI fails only on
new issues from here on, not the whole backlog at once.
This commit is contained in:
2026-10-05 11:45:37 +02:00
parent 48ea6bb33d
commit 807353cbe4
58 changed files with 626 additions and 60 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ use OCA\NgBackup\Repository\ICatalogAnchor;
use OCP\IAppConfig;
/** Keeps the newest catalog generation seen per repository in the app config (outside the location). */
class AppConfigCatalogAnchor implements ICatalogAnchor {
final class AppConfigCatalogAnchor implements ICatalogAnchor {
public function __construct(
private IAppConfig $appConfig,
) {
+1 -1
View File
@@ -11,7 +11,7 @@ use OCA\NgBackup\Repository\IIndexCache;
use OCP\DB\Exception;
use OCP\IDBConnection;
class DbIndexCache implements IIndexCache {
final class DbIndexCache implements IIndexCache {
public function __construct(
private IDBConnection $db,
) {
+1 -1
View File
@@ -33,7 +33,7 @@ use OCP\AppFramework\Db\Entity;
* @method int|null getFinishedAt()
* @method void setFinishedAt(?int $v)
*/
class Run extends Entity {
final class Run extends Entity {
public const RUNNING = 'running';
public const DONE = 'done';
public const FAILED = 'failed';
+1 -1
View File
@@ -12,7 +12,7 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
/** @template-extends QBMapper<Run> */
class RunMapper extends QBMapper {
final class RunMapper extends QBMapper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'ngb_runs', Run::class);
}
+1 -1
View File
@@ -25,7 +25,7 @@ use OCP\AppFramework\Db\Entity;
* @method int|null getBytes()
* @method void setBytes(?int $v)
*/
class Snapshot extends Entity {
final class Snapshot extends Entity {
protected int $targetId = 0;
protected string $snapshotId = '';
protected string $kind = '';
+1 -1
View File
@@ -12,7 +12,7 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
/** @template-extends QBMapper<Snapshot> */
class SnapshotMapper extends QBMapper {
final class SnapshotMapper extends QBMapper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'ngb_snapshots', Snapshot::class);
}
+1 -1
View File
@@ -29,7 +29,7 @@ use OCP\AppFramework\Db\Entity;
* @method int getCreatedAt()
* @method void setCreatedAt(int $v)
*/
class Target extends Entity {
final class Target extends Entity {
protected string $name = '';
protected string $backend = '';
protected string $auth = '';
+1 -1
View File
@@ -11,7 +11,7 @@ use OCP\AppFramework\Db\QBMapper;
use OCP\IDBConnection;
/** @template-extends QBMapper<Target> */
class TargetMapper extends QBMapper {
final class TargetMapper extends QBMapper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'ngb_targets', Target::class);
}