Search code examples
rubycommand-lineoperating-systempdftk

Use Ruby to detect if platform responds to CLI command


I'm working on an open source Rails 4 project that uses PDF Tool Kit ('pdf-forms' gem) to auto-fill PDF forms based on info stored in the app's database. PDFtk requires binaries to be installed, and the instantiated PDFtk model requires a path to the binaries. The path needs to be dynamic so it will work on Heroku, Mac OS X, and Windows. I can find the path on a *nix machine with the 'which' command. But, Windows doesn't use 'which', it uses 'where'.

Is there a way to detect if the platform responds to a command, and if so, then execute command?

My best attempt is to detect platform with RbConfig (see below). However, some Windows platforms (e.g. Cygwin) respond to *nix commands. As a Mac user I'm not familiar with every platform for Windows.

def pdftk
  # Use path stored in Heroku env vars or else get path to local binaries
  @pdftk ||= PdfForms.new(ENV['PDFTK_PATH'] || local_path) 
end

def local_path
  os = RbConfig::CONFIG['arch']
  if /mswin/ =~ os
    path = `where pdftk` # Get pdftk filepath, Windows equiv of *nix 'which' command
  else
    path = `which pdftk` # Get pdftk filepath on POSIX systems
  end

  path
end

Solution

  • The stdlib mkmf module has a little known helper function, find_executable() which should give you what you want

    require 'mkmf'
    path = find_executable('cli-command')
    

    I haven't personally tested it on Windows, but I would assume it should work... http://ruby-doc.org/stdlib-2.3.0/libdoc/mkmf/rdoc/MakeMakefile.html#method-i-find_executable