← Back to issue list

Strange behaviour when organizing from an empty string

View original Github issue

Metadata

Project
craft-parts
Number
#1526
Type
issue
State
closed
Author
lengau
Labels
Status: Triaged Type: Bug
Created
Updated
Closed

Current evaluation

Fixed by merged PR #1532 in commit 46eeb3e8, which handles empty-string organize paths as a no-op when source and destination resolve to the same directory.

Resolution: closed resolved

Reason: PR #1532 was merged as commit 46eeb3e8. It fixes empty-string organize handling and adds regression coverage.

Evaluated by: mr-cal-bot

No scores available.

Issue body

### Bug Description Files or directories seem to disappear if an organize key is an empty string. I can't find the pattern by which the file disappears, but pretty consistently there is at least one missing file/directory. They either don't make it into the install directory or are removed during the organize process. ### To Reproduce Consider the part YAML below. When used as-is, the expected behaviour occurs: ``` (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ python -m craft_parts prime INFO:craft_parts.executor.executor:Installing build-packages Execute: Pull a Execute: Overlay a Execute: Build a Execute: Stage a Execute: Prime a (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ tree prime prime ├── my-dir │   └── subdir-a │   └── file └── my-file 3 directories, 2 files ``` When organizing `'*'` to `''`, it works as expected as well: ``` (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ python -m craft_parts clean Clean all parts. (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ python -m craft_parts prime INFO:craft_parts.executor.executor:Installing build-packages Execute: Pull a Execute: Overlay a Execute: Build a Execute: Stage a Execute: Prime a (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ tree prime prime ├── my-dir │   └── subdir-a │   └── file └── my-file 3 directories, 2 files ``` However, when organizing from an empty string, a file goes missing: ``` (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ python -m craft_parts clean Clean all parts. (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ python -m craft_parts prime INFO:craft_parts.executor.executor:Installing build-packages Execute: Pull a Execute: Overlay a Execute: Build a Error: Failed to copy '/home/lengau/Work/Code/craft-parts/parts/a/install/my-file': no such file or directory. (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ tree parts/a/install/ parts/a/install/ └── my-dir └── subdir-a └── file 3 directories, 1 file ``` If you comment out the creation of `my-file`, then `my-dir/subdir-a/file` goes missing instead: ``` (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ python -m craft_parts clean Clean all parts. (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ python -m craft_parts prime INFO:craft_parts.executor.executor:Installing build-packages Execute: Pull a Execute: Overlay a Execute: Build a Error: Failed to copy '/home/lengau/Work/Code/craft-parts/parts/a/install/my-dir/subdir-a/file': no such file or directory. (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ tree parts/a/install/ parts/a/install/ └── my-dir └── subdir-a 3 directories, 0 files ``` ### part yaml ```shell parts: a: plugin: nil override-build: | mkdir -p "${CRAFT_PART_INSTALL}/my-dir/subdir-a" touch "${CRAFT_PART_INSTALL}/my-file" touch "${CRAFT_PART_INSTALL}/my-dir/subdir-a/file" # organize: # '': '' ``` ### Relevant log output ```shell DEBUG:craft_parts.packages:get repository attribute: attr=configure, repository:<class 'craft_parts.packages.deb.Ubuntu'> DEBUG:craft_parts.utils.os_utils:is_snap: False, SNAP_NAME set to None DEBUG:craft_parts.sequencer:process a:1 DEBUG:craft_parts.sequencer:add action a:1(0) DEBUG:craft_parts.sequencer:process a:2 DEBUG:craft_parts.sequencer:add action a:2(0) DEBUG:craft_parts.sequencer:process a:3 DEBUG:craft_parts.sequencer:add action a:3(0) DEBUG:craft_parts.sequencer:process a:4 DEBUG:craft_parts.sequencer:add action a:4(0) DEBUG:craft_parts.sequencer:process a:5 DEBUG:craft_parts.sequencer:add action a:5(0) INFO:craft_parts.executor.executor:Installing build-packages DEBUG:craft_parts.packages:get repository attribute: attr=install_packages, repository:<class 'craft_parts.packages.deb.Ubuntu'> DEBUG:craft_parts.executor.executor:verify plugin environment for part 'a' DEBUG:craft_parts.packages:set repository attribute: attr=stage_packages_filters, value=None, repo:<class 'craft_parts.packages.deb.Ubuntu'> Execute: Pull a DEBUG:craft_parts.executor.executor:execute action a:Action(part_name='a', step=Step.PULL, action_type=ActionType.RUN, reason=None, project_vars=ProjectVarInfo(root={}), properties=ActionProperties(changed_files=None, changed_dirs=None)) Execute: Overlay a DEBUG:craft_parts.executor.executor:execute action a:Action(part_name='a', step=Step.OVERLAY, action_type=ActionType.RUN, reason=None, project_vars=ProjectVarInfo(root={}), properties=ActionProperties(changed_files=None, changed_dirs=None)) Execute: Build a DEBUG:craft_parts.executor.executor:execute action a:Action(part_name='a', step=Step.BUILD, action_type=ActionType.RUN, reason=None, project_vars=ProjectVarInfo(root={}), properties=ActionProperties(changed_files=None, changed_dirs=None)) DEBUG:craft_parts.state_manager.states:load state file: /home/lengau/Work/Code/craft-parts/parts/a/state/pull DEBUG:craft_parts.packages:get repository attribute: attr=unpack_stage_packages, repository:<class 'craft_parts.packages.deb.Ubuntu'> DEBUG:craft_parts.executor.part_handler:remove directory /home/lengau/Work/Code/craft-parts/parts/a/build DEBUG:craft_parts.executor.step_handler:Executing PosixPath('/tmp/tmp___xqkav/scriptlet.sh') DEBUG:craft_parts.executor.part_handler:Run pre-organize callbacks Error: Failed to copy '/home/lengau/Work/Code/craft-parts/parts/a/install/my-file': no such file or directory. ```

Evaluation history

Date Model Scores Action Summary
stealth/space-bunny-alpha — closed resolved Fixed by merged PR #1532 in commit 46eeb3e8, which handles empty-string organize paths as a no-op when source and destination resolve to the same directory.
stealth/space-bunny-alpha — closed resolved Fixed in PR #1532 (commit 46eeb3e8) by correctly handling empty-string organize paths; regression coverage was added.
qwen/qwen3.6-35b-a3b — — Closed after a developer volunteered to fix the empty-string organize bug and add regression tests. An internal Jira ticket (CRAFT-5087) was created to track the resolution.
qwen/qwen3.6-35b-a3b
Staleness: 35
Complexity: 45
Confidence: 90
Support Request: 5
keep open Bug where files disappear during the organize step when using an empty string as the source key. Triaged and acknowledged; a contributor has volunteered to reproduce it and add a regression test before fixing.
qwen3.6-35b-a3b-mtp-q6
Staleness: 55
Complexity: 45
Confidence: 85
Support Request: 5
keep open Bug where files disappear during the organize step when using an empty string key. Triaged and claimed by a contributor, but inactive for ~3 months awaiting reproduction and fix.

Update history

Date Change
closed

Related work

  • Likely Fixed By: canonical/craft-parts#1532 (confidence 100%)

    Merged fix for the empty-string organize path behavior reported in #1526.

Related issues

Issue Project State Summary Similarity
#1532 fix(executor): handle empty-string organize path craft-parts merged Merged #1532 in commit 46eeb3e8, making organize: {'': ''} a no-op when source and destination resolve to the same directory; #1526 was closed.
82%
#1544 fix: prevent organizing a directory into itself craft-parts closed PR #1544 was closed unmerged as incomplete; the solution was replaced by the organize-from-build rework in #1598 (commit cc02958b).
72%
#784 Support globbing for organize snapcraft merged Merged PR #784 added glob expansion for organize entries, resolving LP #1616459, in commit 260671d1a. Empty-parent-directory cleanup was deferred.
71%
#1370 fix: make sure the destination does not exist before organizing craft-parts merged Merged PR #1370 as commit 7fe7c84e, removing any existing organize destination before moving files and fixing #1366/CRAFT-4870.
71%