class ViteRuby::Runner

Public: Executes Vite commands, providing conveniences for debugging.

def capture3_with_output(*cmd, **opts)

NOTE: This improves the experience of running bin/vite build.
Internal: A modified version of capture3 that continuosly prints stdout.
def capture3_with_output(*cmd, **opts)
  return Open3.capture3(*cmd, opts) if config.hide_build_console_output
  Open3.popen3(*cmd, opts) { |_stdin, stdout, stderr, wait_threads|
    out = Thread.new { read_lines(stdout) { |l| logger.info('vite') { l } } }
    err = Thread.new { stderr.read }
    [out.value, err.value, wait_threads.value]
  }
end

def command_for(args)

Internal: Returns an Array with the command to run.
def command_for(args)
  [config.to_env].tap do |cmd|
    args = args.clone
    cmd.append('node', '--inspect-brk') if args.delete('--inspect')
    cmd.append('node', '--trace-deprecation') if args.delete('--trace_deprecation')
    cmd.append(vite_executable)
    cmd.append(*args)
    cmd.append('--mode', config.mode) unless args.include?('--mode') || args.include?('-m')
  end
end

def initialize(vite_ruby)

def initialize(vite_ruby)
  @vite_ruby = vite_ruby
end

def read_lines(io)

Internal: Reads and yield every line in the stream. Returns the full content.
def read_lines(io)
  buffer = +''
  while line = io.gets
    buffer << line
    yield line
  end
  buffer
end

def run(argv, capture: false)

Public: Executes Vite with the specified arguments.
def run(argv, capture: false)
  Dir.chdir(config.root) {
    cmd = command_for(argv)
    capture ? capture3_with_output(*cmd, chdir: config.root) : Kernel.exec(*cmd)
  }
rescue Errno::ENOENT => error
  raise ViteRuby::MissingExecutableError, error
end

def vite_executable

Internal: Resolves to an executable for Vite.
def vite_executable
  bin_path = config.vite_bin_path
  File.exist?(bin_path) ? bin_path : "#{ `npm bin`.chomp }/vite"
end