jonshipman / sveltekit-pb-boilerplate

84 stars 7 forks source link

Windows Unzipping #2

Closed stefandanzl closed 6 months ago

stefandanzl commented 6 months ago

Error message:

 TAR.EXE -xf pocketbase.zip -C C:\[FOLDERS]\[PROJECTNAME]\db\ 

TAR: This does not look like a tar archive
TAR: Skipping to next header
TAR: Exiting with failure status due to previous errors
node:internal/fs/promises:1059
  return await PromisePrototypeThen(
         ^

Error: ENOENT: no such file or directory, unlink 'C:\[FOLDERS]\[PROJECTNAME]\db\CHANGELOG.md'
    at async Object.unlink (node:internal/fs/promises:1059:10)
    at async file:///C:/Users/user/AppData/Local/npm-cache/_npx/f4833f11856e88cf/node_modules/svelte-pb/setup.mjs:56:2 {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'unlink',
  path: 'C:\\[FOLDERS]\\[PROJECTNAME]\\db\\CHANGELOG.md'
}

Systeminfo: Win10, using powershell console in VSCode Error also occurs when using WSL console (Windows Subsystem for Linux)

Possible solution

Should be solved with OS detection and using in windows:

unizip pocketbase.zip -C C:\[FOLDERS]\[PROJECTNAME]\db\ 
stefandanzl commented 6 months ago

It seems you already do differentiate:

if (os.platform() == 'win32') {
    await run('TAR.EXE', ['-xf', pbzippath, '-C', path.join(resolved, 'db') + path.sep]);
} else {
    await run('unzip', [pbzippath, '-d', path.join(resolved, 'db') + path.sep]);
}
stefandanzl commented 6 months ago

There seems to be contradictory information on whether TAR.EXE can be used for .zip files or not In my case it clearly can not be used

jonshipman commented 6 months ago

Yes, I am using Windows 11. I'll see about getting Windows 10 and finding a solution there.

WSL should be seeing it as a nix based os and should be using unzip. I'll see if that's a different issue.

jonshipman commented 6 months ago

Looks like Windows 10 build 17063 or later comes with tar.exe. I'll look into other solutions, but at the very least I may include that disclaimer in the README.

jonshipman commented 6 months ago

Try out this branch and let me know if it works, haven't used extract-zip before but it seems to work all the same in my tests.

https://github.com/jonshipman/sveltekit-pb-boilerplate/pull/3

stefandanzl commented 6 months ago

Your fix was not very straightforward on my system and it's really sad how bad Windows' built in tools are but here is the best solution I came up with that should be reliable no matter which console is used on Windows:

powershell -command "Expand-Archive -Force '%~dp0my_zip_file.zip' '%~dp0'"

So in our case something like:

await run('Expand-Archive', [`-Force '${pbzippath}' -DestinationPath '${path.join(resolved, 'db')}'`])

with following modification further down:

        if (os.platform() === 'win32') {
            if (command === 'Expand-Archive'){
                options.execPath = 'powershell.EXE';
                options.execArgv = ['-Command'];
            } else {
                options.execPath = 'CMD.EXE';
                options.execArgv = ['/C'];
            }

full code: setup.txt

jonshipman commented 6 months ago

Did the branch not work for you? You would need to run npm install as it introduces a dependency.

stefandanzl commented 6 months ago

Yes when cloning the entire issue-2 branch repository it works but how will this behave with npx? Will it create a node_modules in the current directory before creating the project folder and those "installation files" remain afterwards (cluttering the system)?

Also using a different Windows 10 Computer, TAR.EXE in the main branch was now able to extract pocketbase.zip - very inconsistent behaviour indeed ...

Are you opposed to the powershell solution?

jonshipman commented 6 months ago

npx takes care of it. npx installs the module as a global package. Anything that you install with npx remains in the global installation directory after installation. npx just runs the bin package prop after installation (I do need to add a check for if the dir is empty).

Run npm link inside issue-2 as a branch and npx svelte-pb your-project will use the local folder as the source for npx. That's the procedure for testing executable node libraries.

I have nothing against powershell in general. I would probably move it up to the actual run command(so run('powershell.exe',['-Command'....) as out of scope conditionals are bad practice. Admittingly the library is small, but I do like to use this function in other projects as it lets me have TTY to respond to prompts. On windows, npm by default uses cmd.exe. I do tend to add an npm.ps1 in the folder, but some processes actually run npm.cmd on windows.

Introducing dependencies does tend to be the "node way" but I'll think on it. I do like that no dependencies are introduced on your version.

jonshipman commented 6 months ago

I may use https://github.com/thejoshwolfe/yauzl. Looks like extract-zip is just a wrapper around yauzl that provides things like builtin tree building. Since pocketbase.zip doesn't use directories, it may be leaner to just use that lib.

Also, wanted to mention that yauzl is a native node unzipping utility. So theoretically it should work in environments where "unzip" isn't available on linux. Not installed by default on a lot of server environments.

stefandanzl commented 6 months ago

According to my own testing, run('powershell.exe',['-Command'.... will not work - it will not fail, but simply not extract anything. Possibly because it's from starting a console from a console from a console 😅

The thought about unzip not being present on server systems is a good thought though ...