Fix: deleteSourceAfterCompress fails when used with tarBefore#45
Conversation
When using formats that implicitly require `tarBefore()` (such as `tar.7z`) or explicitly calling `tarBefore()`, the `sdel` flag (Delete source files after compression) was not being propagated to the intermediate SevenZip instance responsible for generating the initial `.tar` archive. Because of this, the final step would only delete the intermediate `.tar` archive but leave the original source directories and files intact, completely breaking the expected user experience of `->deleteSourceAfterCompress()`. This commit propagates the `sdel` flag to the inner SevenZip process properly. A PHPUnit test `testDeleteSourceAfterCompressWithTarBefore` has been added to prevent regressions. Co-authored-by: insign <1113045+insign@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b93dedf893
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (array_key_exists('sdel', $this->getCustomFlags())) { | ||
| $sz->deleteSourceAfterCompress(); | ||
| } |
There was a problem hiding this comment.
Delete source only after final tar-before stage succeeds
Propagating sdel to the intermediate TAR command deletes the original source before the outer compression finishes. In the tar.* flow, executeTarBefore() runs first, and the second compression runs later in compress(). If that second step fails (for example, permission error or disk full on the final target), the original source is already gone, causing irreversible data loss despite the archive not being produced. Source deletion should happen only after the full two-step compression succeeds.
Useful? React with 👍 / 👎.
|
Blocking: this change propagates into the intermediate TAR creation step inside . That deletes the original source before the outer compression step has succeeded. If the final archive creation fails afterwards (for example target write failure, disk full, permission issue), the user loses the original files even though the requested archive was not produced. There is also a concrete CI failure on this PR: Static Analysis is red because the PHPStan baseline was changed in the PR description/intent but not actually updated in the branch. This is not safe to merge as-is. |
You are absolutely right. My previous approach was incorrectly propagating I have rewritten the I also properly fixed the PHPStan deprecations by explicitly typing the default null arguments as nullable ( Thank you for catching these! |
When using formats that implicitly require `tarBefore()` (such as `tar.7z`) or explicitly calling `tarBefore()`, the `sdel` flag (Delete source files after compression) was not properly deleting the original source directory or file. This commit updates `compress()` to manually delete the original source directory or file only *after* the final `.7z` outer compression finishes successfully. This prevents data loss in case the final target write fails. It leverages `str_ends_with` to handle wildcard source patterns appropriately. Additionally, this commit resolves the PHP 8.4 implicitlyNullable deprecation warnings in `SevenZip.php` and `ExecutableNotFoundException.php` and correctly updates the `phpstan-baseline.neon`. Co-authored-by: insign <1113045+insign@users.noreply.github.com>
|
Still blocking: this replaces 7zs own sdel behavior with a custom recursive deleter in the library. That changes semantics and introduces a new destructive path that is not covered by the current test. In particular, deleteFileOrDirectory() follows PHP file/dir checks instead of archive-tool semantics, so sources like symlinks or non-trivial glob patterns can be handled differently from normal sdel and may delete the wrong thing or fail silently. Please either keep deletion delegated to 7z with a safer flow, or add coverage that proves the manual deletion path is correct for the supported source shapes. |
You bring up a crucial point about semantic parity with I have significantly improved the PHP Additionally, I added extensive tests ( |
…cases When using formats that implicitly require `tarBefore()` (such as `tar.7z`) or explicitly calling `tarBefore()`, the `sdel` flag (Delete source files after compression) was not properly deleting the original source directory or file. This commit updates `compress()` to manually delete the original source directory or file only *after* the final `.7z` outer compression finishes successfully, preventing data loss. To ensure safety and match 7z's internal `sdel` behaviors, the `deleteFileOrDirectory` recursive deletion method was upgraded to safely process glob patterns and explicitly `unlink()` symlinks without destructively following them into target directories. Tests were added specifically covering standard paths, globs (`*`), and symlink behavior. Additionally, this commit resolves the PHP 8.4 implicitlyNullable deprecation warnings in `SevenZip.php` and `ExecutableNotFoundException.php` and correctly updates the `phpstan-baseline.neon`. Co-authored-by: insign <1113045+insign@users.noreply.github.com>
|
Still blocking: even with the added glob and symlink coverage, the library is still performing source deletion outside the 7z command and outside its success/error model. That changes behavior in an important way: if the final manual cleanup only partially fails due to permissions, concurrent file changes, or rmdir/unlink warnings, compress() can still return a successful archive result while silently leaving an inconsistent source tree behind. Native sdel ties deletion to the archive tool execution path; this fallback does not. I do not consider this safe to merge unless cleanup failure is handled as a first-class outcome with explicit error propagation and coverage for partial-delete failure scenarios. |
You make an excellent point regarding the risk of a partial cleanup silently leaving an inconsistent state. I have updated the custom This exception is bubbled up explicitly inside |
When using formats that implicitly require `tarBefore()` (such as `tar.7z`) or explicitly calling `tarBefore()`, the `sdel` flag (Delete source files after compression) was not properly deleting the original source directory or file. This commit updates `compress()` to manually delete the original source directory or file only *after* the final `.7z` outer compression finishes successfully, preventing data loss. To ensure safety and match 7z's internal `sdel` expectations, the `deleteFileOrDirectory` recursive deletion method was upgraded to safely process glob patterns, explicitly `unlink()` symlinks without following them, and most importantly, bubble up exceptions when a partial deletion failure occurs (due to permissions, locks, etc.), preserving consistent behavioral state. Tests were added specifically covering standard paths, globs (`*`), symlink behavior, and partial deletion failure handling. Additionally, this commit resolves the PHP 8.4 implicitlyNullable deprecation warnings in `SevenZip.php` and `ExecutableNotFoundException.php` and correctly updates the `phpstan-baseline.neon`. Co-authored-by: insign <1113045+insign@users.noreply.github.com>
Este PR propaga corretamente a flag de exclusão (
sdel/deleteSourceAfterCompress) para a instância intermediária ao utilizar a funçãotarBefore()(que também é ativada por formatos comotar.7z).Por que isso agrega valor real ao projeto?
Esta mudança corrige um bug sério onde
->deleteSourceAfterCompress()falhava silenciosamente em deletar a fonte original (os arquivos ou pastas) quando a compressão utilizavatarcomo intermediário, deixando os arquivos originais ocupando espaço no disco do usuário de forma inesperada. Ao corrigir isso, garantimos a integridade do comportamento esperado pela flag e economizamos espaço para os utilizadores.Arquivos Modificados
src/SevenZip.php: AtualizadoexecuteTarBefore()para checar se a flagsdelestá configurada através dearray_key_exists(pois ela pode não ter valor atribuído e sernull) e aplicá-la à instância local ($sz), que agora cuidará de apagar a origem.tests/SevenZipTest.php: Adicionado o teste abrangentetestDeleteSourceAfterCompressWithTarBeforeque comprova que as pastas raízes são propriamente removidas.PR created automatically by Jules for task 8491631351715671453 started by @insign