schovi / baked_file_system

Virtual File System for Crystal language. Embedding your assets into final binary.
MIT License
177 stars 18 forks source link

Is baked_file_system supposed to work under Windows ? #47

Open serge-hulne opened 1 year ago

serge-hulne commented 1 year ago

When trying the following code on Windows 11 (code which works under macOS)

require "baked_file_system"
require "http/server"

HOST = "127.0.0.1"
PORT = 8080

# URL to archive path mapping
def get_file_from_url?(url : String) : String 
  if url == "/" || url == ""
    url = "/index.html"
  end
  path = url
  file = ""
  begin
    file = FileStorage.get path
    return file.gets_to_end
  rescue BakedFileSystem::NoSuchFileError
    puts "File #{path} is missing"
    return "Path: #{path} not found!"
  end   
end

# Archive
class FileStorage
  extend BakedFileSystem
  bake_folder "../public"
end

# Server using URL to archive path mapping
server = HTTP::Server.new do |context|
  context.response.print get_file_from_url?(context.request.path)
end

# Running server
puts "Listening on http://#{HOST}:#{PORT}"
server.bind_tcp HOST , PORT
server.listen

I got the error message:

.\bin\app.exe
Unhandled exception: BakedFileSystem empty: no files in C:\Users\serge\Documents\vue-tests\vue-tests-nomodules\_temp\Baked\app\public (Exception)
  from src\[app.cr:30](http://app.cr:30/) in '__crystal_main'
  from C:\Users\serge\scoop\apps\crystal\current\src\crystal\[main.cr:115](http://main.cr:115/) in 'main_user_code'
  from C:\Users\serge\scoop\apps\crystal\current\src\crystal\[main.cr:101](http://main.cr:101/) in 'main'
  from C:\Users\serge\scoop\apps\crystal\current\src\crystal\[main.cr:127](http://main.cr:127/) in 'main'
  from C:\Users\serge\scoop\apps\crystal\current\src\crystal\system\win32\[wmain.cr:37](http://wmain.cr:37/) in 'wmain'
  from D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288 in '__scrt_common_main_seh'
  from C:\WINDOWS\System32\KERNEL32.DLL +75453 in 'BaseThreadInitThunk'
  from C:\WINDOWS\SYSTEM32\ntdll.dll +384952 in 'RtlUserThreadStart'
straight-shoota commented 1 year ago

Win32 isn't explicitly tested but I suppose it should work. Does the folder mentioned in the error message contain any files?

serge-hulne commented 1 year ago

Yes, I used the same set-up as on macOS: Screenshot (261)

serge-hulne commented 1 year ago

If you want to try it, I put the code on GitHub: https://github.com/serge-hulne/crystal_serve_baked

jansul commented 1 year ago

I think I figured out the main issue why it's failing on Windows.

baked_file_system uses Dir.glob to find the files. The documentation for this method specifies that the path seperator must be /:

NOTE Path separator in patterns needs to be always /. The returned file names use system-specific path separators.

On Windows the path seperator of course ends up being \

Not sure if this is the best way, but I was able to fix this by using to_posix, something like:

- files = Dir.glob(File.join(root_path, "**", "*"))
+ files = Dir.glob(Path[root_path, "**", "*"].to_posix)

Some of the tests will still fail even with this, mostly due to more path issues, but a couple due to git handily converting files to CRLF :sweat_smile: But nothing big preventing this from working!