@@ -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} "
0 commit comments