in reply to Incomplete file write under Dancer2

Excel::Writer::XLSX uses Archive::Zip internally. So you can test that this does the job right inside your provided Dancer2 handler.

But it is likely that the culprit is here: https://metacpan.org/module/Excel::Writer::XLSX::Workbook/source#L1195 where File::Find finds files and also in the previous line:

my $wanted = sub { push @xlsx_files, $File::Find::name if -f };

If for some reason the file paths are different not visible or not accessible inside Dancer then the above silently ignores them.

One simple way to debug this is to edit https://metacpan.org/module/Excel::Writer::XLSX::Workbook/source#L1195 and print messages etc. as to which files are found and added (whichpm Excel::Writer::XLSX::Workbook or perldoc -D Excel::Writer::XLSX::Workbook will tell you where said module is located)

Replies are listed 'Best First'.
Re^2: Incomplete file write under Dancer2
by realflash (Acolyte) on Jul 25, 2024 at 18:02 UTC

    Getting closer...

    After sprinkling File::Find with print statements I find that in the latest version of File::Find does this at line 444:

                        if (-d _) {

    This is the code that decides whether or not the thing it has found is a directory, and whether to recurse into it. Under Dancer this test fails for the subdirectories and it never recurses into them. But what is _ meant to be? Is that a thing I don't know about? If I change it to $_ it does recurse into the directory, and I end up with a valid XLSX file. There are lots of uses of an underscore on its own across this module.

      Possibly it is related to the lstat call on line 442.

      What happens if you add a stat call with the same arguments immediately after it? This will reset the value in _

      ... $sub_nlink = (lstat ($no_chdir ? $dir_pref . $FN : $FN))[3]; my $debug = stat ($no_chdir ? $dir_pref . $FN : $FN))[3]; if (-d _) { ...
      I forget where this is described in the docs, but it refers to the most recently called 'stat' results. It's handy, but a bit arcane.
Re^2: Incomplete file write under Dancer2
by realflash (Acolyte) on Jul 25, 2024 at 16:27 UTC

    Thank you, you were right that the problem is here; interestingly it seems to be that File::Find enumerates the directories but then doesn't recurse into them. Whereas on the command line it does. Thus the files at the top level end up in the zip file, but anything below it doesn't.

    This is all happening in a temp dir, so it can't be a permissions things as the files in the temp directory are being created (successfully) by the same process as creates the temp directory; indeed I see the user running Dancer (me) has full control over the temp dir, the top level files and the subdirs and the files in them as I would expect; identical permissions throughout. This is all on Windows.

    So why is File::Find not recursing in?

Re^2: Incomplete file write under Dancer2
by realflash (Acolyte) on Jul 25, 2024 at 18:54 UTC

    The problem is actually the line before - the stat of the sub-directories is failing so it can't tell if the file is a directory, so it is not recursing into it. Getting closer, and further out of my depth.