gleam-lang / gleam

⭐️ A friendly language for building type-safe, scalable systems!
https://gleam.run
Apache License 2.0
18.1k stars 759 forks source link

✨ Add a `--watch` flag to `gleam build`. #2570

Open hayleigh-dot-dev opened 10 months ago

hayleigh-dot-dev commented 10 months ago

After a bit of a discussion about how cool elm reactor is the idea of having the compiler automatically rebuild whenever files change came up. Mostly opening this here so we have a ticket to track any of that work and a place for further discussion.


Below are some reasons why this feature would be useful for a project like lustre.

If this feature also included a way to communicate with other processes in a similar fashion to how the language server works, we could also...

lpil commented 10 months ago

Sounds good!

What commands would we want it for? run, test, build and check seem like obvious ones.

Making it a flag means there's yet another flag that can't be passed easily down into the Gleam program, and --watch seems like a common one that would be wanted. Perhaps it could be a command itself: gleam watch test

If this feature also included a way to communicate with other processes in a similar fashion to how the language server works, ...

What do you mean by this?

hayleigh-dot-dev commented 10 months ago

Making it a flag means there's yet another flag that can't be passed easily down into the Gleam program

No flags can be easily passed down into a gleam program in my experience:

% gleam run -m lustre/try --include-styles
error: Found argument '--include-styles' which wasn't expected, or isn't valid in this context

        If you tried to supply `--include-styles` as a value rather than a flag, use `-- --include-styles`

USAGE:
    gleam run --module <MODULE>

For more information try --help

But a watch command sounds fine in any case.

What do you mean by this?


I'd like to be able to spawn gleam watch as a (os) process and have some way of it telling my program when/which files have changed/been compiled. Maybe that's just output on stdout or maybe its events on a socket, but some way of knowing when this stuff happened would be immensely useful I think.

I'd like to, for example, re-run lustre_ssg any time some source files change. If the compiler already has a filesystem watcher it feels a bit silly if I have to re-implement all that functionality (and it is seemingly non-trivial to do this cross-platform) so if the binary could just expose that info it'd be super great.

lpil commented 10 months ago

No flags can be easily passed down into a gleam program in my experience:

That's a bug with Clap when only flags are passed. It doesn't in any way impact how we design the CLI API.

I'd like to be able to spawn gleam watch as a (os) process and have some way of it telling my program when/which files have changed/been compiled.

Gleam won't offer anything like this as part of this feature as it means we're accidentally shifting into being a generic build tool rather than a specific one, and I want to do a lot of R&D before we consider moving into that space as it's extremely easy to make a rubbish generic build tool / task runner.

For this specific example you don't actually need anything new from the compiler to run the site generator, you just run gleam run -m lustre_ssg --watch (or whatever the command will be).

matobet commented 5 months ago

A bit related to this issue: I'd find support for gleam test --watch specifically an immensely useful feature for TDD-style rapid iteration and testing :+1:

inoas commented 5 months ago

A bit related to this issue: I'd find support for gleam test --watch specifically an immensely useful feature for TDD-style rapid iteration and testing 👍

https://hexdocs.pm/glacier/ does that.

lpil commented 5 months ago

@matobet yup we would want it for all the main commands

gdamjan commented 1 month ago

it would be interesting if on the Erlang target this uses erlang hot module reloading so your life app (in dev mode) is updated automatically.

imagine you fix your websocket server and it continues running without breaking the connection.

maybe an additional trick would be to make (in dev mode only) all function calls in the project "public" ie. called as module:function so code gets to get the new version earlier. This incurs some performance penalty though.

lpil commented 1 month ago

This ticket is only for re-running. Any work with currently running programs is out of scope. Please start a discussion if you have ideas for new features along with the design you had in mind.