1

I'm trying write a build script with rake which will run on Windows and Linux. Assume that I have the following rake task:

task:check do
    sh "dir"
end

This will work on Windows but not in other operating systems. What is the best way to handle operating system differences with sh command? I specifically want to make following task work between operating systems but it currently on works on Windows:

task:check do
    %w(npm bower kpm gulp).each do |cmd|
        begin sh "#{cmd} --version > NUL" rescue raise "#{cmd} doesn't exists globally" end
    end
end
tugberk
  • 57,477
  • 67
  • 243
  • 335
  • This is almost a duplicate of "[How can I find which operating system my Ruby program is running on?](http://stackoverflow.com/questions/170956/how-can-i-find-which-operating-system-my-ruby-program-is-running-on)" – the Tin Man Oct 24 '14 at 17:41
  • @theTinMan not entirely. Check out the excepted answer. – tugberk Oct 24 '14 at 17:52
  • "almost a duplicate", not "a duplicate", otherwise I'd have closed it as a duplicate. – the Tin Man Oct 24 '14 at 19:36

2 Answers2

4

Check out the os gem. You could wrap your task definitions in checks for the platform, or even use some of the helpers to write more generic tasks.

Something like this may be handy:

>> OS.dev_null
=> "NUL" # or "/dev/null" depending on which platform

Or just make them specific to the OS:

if OS.windows?

  task :whatever do
    # ...
  end

elsif OS.linux?

  task :whatever do
    # ...
  end

end
Nick Veys
  • 23,458
  • 4
  • 47
  • 64
  • awesome, thanks! went with this: `sh "#{cmd} --version >> #{OS.dev_null}"` – tugberk Oct 24 '14 at 17:34
  • Note that this gem [treats Cygwin as Linux](https://github.com/rdp/os/blob/master/lib/os.rb#L5), not Windows! Depending on your use-case this might not be what you expect. – sschuberth Sep 09 '15 at 08:09
2

Ruby knows the OS it was compiled on, and what it's running on, because it has to be aware of path delimiters, line-ending characters, etc. We can find out about what it knows using built-in constants and/or modules.

Using the RUBY_PLATFORM constant:

On Mac OSX:

RUBY_PLATFORM # => "x86_64-darwin13.0"

On Linux:

RUBY_PLATFORM # => "x86_64-linux"

You can also use Gem::Platform:

On Mac OSX:

Gem::Platform.local # => #<Gem::Platform:0x3fe859440ef4 @cpu="x86_64", @os="darwin", @version="13">
Gem::Platform.local.os # => "darwin"

And on Linux:

Gem::Platform.local # => #<Gem::Platform:0x13e0b60 @cpu="x86_64", @os="linux", @version=nil>
Gem::Platform.local.os # => "linux"

And then there's the RbConfig module that comes with Ruby:

On Mac OS:

RbConfig::CONFIG['target_cpu']   # => "x86_64"
RbConfig::CONFIG['target_os']    # => "darwin13.0"
RbConfig::CONFIG['host_cpu']     # => "x86_64"
RbConfig::CONFIG['host_os']      # => "darwin13.4.0"

And on Linux:

 RbConfig::CONFIG['target_cpu'] # => "x86_64"
 RbConfig::CONFIG['target_os']  # => "linux"
 RbConfig::CONFIG['host_cpu']   # => "x86_64"
 RbConfig::CONFIG['host_os']    # => "linux-gnu"

A quick search returns a number of hits for this, including many here on Stack Overflow.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303