Skip to content

Commit 8cb1e71

Browse files
committed
WIP
1 parent f45327d commit 8cb1e71

File tree

6 files changed

+42
-7
lines changed

6 files changed

+42
-7
lines changed

main.cr

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ module Savi
7777
option "-b", "--backtrace", desc: "Show backtrace on error", type: Bool, default: false
7878
option "-r", "--release", desc: "Compile in release mode", type: Bool, default: false
7979
option "--fix", desc: "Auto-fix compile errors where possible", type: Bool, default: false
80+
option "--watch", desc: "Run continuously, watching for file changes (EXPERIMENTAL)", type: Bool, default: false
8081
option "--no-debug", desc: "Compile without debug info", type: Bool, default: false
8182
option "--print-ir", desc: "Print generated LLVM IR", type: Bool, default: false
8283
option "--print-perf", desc: "Print compiler performance info", type: Bool, default: false
@@ -93,7 +94,11 @@ module Savi
9394
options.target_pass = Savi::Compiler.pass_symbol(opts.pass) if opts.pass
9495
options.manifest_name = args.name.not_nil! if args.name
9596
Dir.cd(opts.cd.not_nil!) if opts.cd
96-
Cli.run options, opts.backtrace
97+
if opts.watch
98+
Cli.run_with_watch(options, opts.backtrace)
99+
else
100+
Cli.run(options, opts.backtrace)
101+
end
97102
end
98103
end
99104
sub "build" do
@@ -199,6 +204,30 @@ module Savi
199204
end
200205
end
201206

207+
# This feature is experimental - it's currently not quite working,
208+
# due to some issues with inaccurate or incomplete caching of passes.
209+
# Also, it doesn't watch precisely the right set of files -
210+
# ideally it would watch all of the package globs that are in use,
211+
# as well as the manifest files where those packages are defined.
212+
# Once we get those issues ironed out, we should mark it as being
213+
# no longer experimental, and publicize it as a recommended way of working.
214+
def self.run_with_watch(options, backtrace = false)
215+
ctx = Savi.compiler.compile(Dir.current, options.target_pass || :run, options)
216+
finish_with_errors(ctx.errors, backtrace) if ctx.errors.any?
217+
last_compiled_at = Time.utc
218+
219+
FSWatch.watch(".", latency: 0.25, recursive: true) do |event|
220+
next unless event.created? || event.updated? || event.removed? || event.renamed?
221+
next if event.timestamp < last_compiled_at
222+
223+
ctx = Savi.compiler.compile(Dir.current, options.target_pass || :run, options)
224+
finish_with_errors(ctx.errors, backtrace) if ctx.errors.any?
225+
last_compiled_at = Time.utc
226+
end
227+
228+
sleep
229+
end
230+
202231
def self.eval(code, options, backtrace = false)
203232
_add_backtrace backtrace do
204233
dirname = "/tmp/savi-eval-#{Random::Secure.hex}"

src/savi/compiler/macros.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Savi::Compiler::Macros < Savi::AST::CopyOnMutateVisitor
2525
cached_hash, cached_func = cache_result if cache_result
2626
return cached_func if cached_func && cached_hash == input_hash
2727

28-
puts " RERUN . #{self.class} #{f_link.show}" if cache_result && ctx.options.print_perf
28+
puts " RERUN . #{self} #{f_link.show}" if cache_result && ctx.options.print_perf
2929

3030
yield
3131

src/savi/compiler/populate.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class Savi::Compiler::Populate
191191
cached_hash, cached_func = cache_result if cache_result
192192
return cached_func if cached_func && cached_hash == input_hash
193193

194-
puts " RERUN . #{self.class} #{f_link.show}" if cache_result && ctx.options.print_perf
194+
puts " RERUN . #{self} #{f_link.show}" if cache_result && ctx.options.print_perf
195195

196196
yield
197197

src/savi/compiler/reparse.cr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Savi::Compiler::Reparse < Savi::AST::CopyOnMutateVisitor
2525
cached_hash, cached_func = cache_result if cache_result
2626
return cached_func if cached_func && cached_hash == input_hash
2727

28-
puts " RERUN . #{self.class} #{f_link.show}" if cache_result && ctx.options.print_perf
28+
puts " RERUN . #{self} #{f_link.show}" if cache_result && ctx.options.print_perf
2929

3030
yield
3131

@@ -42,7 +42,7 @@ class Savi::Compiler::Reparse < Savi::AST::CopyOnMutateVisitor
4242
t_cached_hash, t_cached_type = t_cache_result if t_cache_result
4343
return t_cached_type if t_cached_type && t_cached_hash == input_hash
4444

45-
puts " RERUN . #{self.class} #{t_link.show}" if t_cache_result && ctx.options.print_perf
45+
puts " RERUN . #{self} #{t_link.show}" if t_cache_result && ctx.options.print_perf
4646

4747
yield
4848

@@ -59,7 +59,7 @@ class Savi::Compiler::Reparse < Savi::AST::CopyOnMutateVisitor
5959
ta_cached_hash, ta_cached_type = ta_cache_result if ta_cache_result
6060
return ta_cached_type if ta_cached_type && ta_cached_hash == input_hash
6161

62-
puts " RERUN . #{self.class} #{t_link.show}" if ta_cache_result && ctx.options.print_perf
62+
puts " RERUN . #{self} #{t_link.show}" if ta_cache_result && ctx.options.print_perf
6363

6464
yield
6565

src/savi/compiler/sugar.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Savi::Compiler::Sugar < Savi::AST::CopyOnMutateVisitor
2020
cached_hash, cached_func = cache_result if cache_result
2121
return cached_func if cached_func && cached_hash == input_hash
2222

23-
puts " RERUN . #{self.class} #{f_link.show}" if cache_result && ctx.options.print_perf
23+
puts " RERUN . #{self} #{f_link.show}" if cache_result && ctx.options.print_perf
2424

2525
yield
2626

src/savi/ext/fswatch/event.cr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Add a timestamp property to all FSWatch events, so that we can track
2+
# when the event was received by the thread that received it, rather than
3+
# the time when we got around to first noticing it in our processing loop.
4+
struct FSWatch::Event
5+
property timestamp : Time = Time.utc
6+
end

0 commit comments

Comments
 (0)