Make platform a property of ExecutionContext.

Summary:
It is better to assign platform to a instance of `ExecutionContext`
for testing purposes than calling `Platfrom.detect()`.

Test Plan: Unit tests.
diff --git a/src/com/facebook/buck/android/GenerateManifestStep.java b/src/com/facebook/buck/android/GenerateManifestStep.java
index 76767c0..efb8e1b 100644
--- a/src/com/facebook/buck/android/GenerateManifestStep.java
+++ b/src/com/facebook/buck/android/GenerateManifestStep.java
@@ -105,7 +105,7 @@
       throw new HumanReadableException("Error generating manifest file");
     }
 
-    if (Platform.detect() == Platform.WINDOWS) {
+    if (context.getPlatform() == Platform.WINDOWS) {
       // Convert line endings to Lf on Windows.
       try {
         String xmlText = Files.toString(outManifestFile, Charsets.UTF_8);
diff --git a/src/com/facebook/buck/cli/AbstractCommandRunner.java b/src/com/facebook/buck/cli/AbstractCommandRunner.java
index bd189ab..38b59e2 100644
--- a/src/com/facebook/buck/cli/AbstractCommandRunner.java
+++ b/src/com/facebook/buck/cli/AbstractCommandRunner.java
@@ -28,6 +28,7 @@
 import com.facebook.buck.step.ExecutionContext;
 import com.facebook.buck.util.Console;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
@@ -49,6 +50,7 @@
   private final ArtifactCacheFactory artifactCacheFactory;
   private final Parser parser;
   private final BuckEventBus eventBus;
+  private final Platform platform;
 
   /** This is constructed lazily. */
   @Nullable private T options;
@@ -64,6 +66,7 @@
     this.artifactCacheFactory = Preconditions.checkNotNull(params.getArtifactCacheFactory());
     this.parser = Preconditions.checkNotNull(params.getParser());
     this.eventBus = Preconditions.checkNotNull(params.getBuckEventBus());
+    this.platform = Preconditions.checkNotNull(params.getPlatform());
   }
 
   abstract T createOptions(BuckConfig buckConfig);
@@ -216,6 +219,7 @@
             options.findAndroidPlatformTarget(dependencyGraph, getBuckEventBus()))
         .setNdkRoot(options.findAndroidNdkDir(getProjectFilesystem()))
         .setEventBus(eventBus)
+        .setPlatform(platform)
         .build();
   }
 
diff --git a/src/com/facebook/buck/cli/BuckConfig.java b/src/com/facebook/buck/cli/BuckConfig.java
index 3c01746..c59880c 100644
--- a/src/com/facebook/buck/cli/BuckConfig.java
+++ b/src/com/facebook/buck/cli/BuckConfig.java
@@ -95,6 +95,8 @@
 
   private final BuildTargetParser buildTargetParser;
 
+  private final Platform platform;
+
   private enum ArtifactCacheNames {
     dir,
     cassandra
@@ -115,7 +117,8 @@
   @VisibleForTesting
   BuckConfig(Map<String, Map<String, String>> sectionsToEntries,
       ProjectFilesystem projectFilesystem,
-      BuildTargetParser buildTargetParser) {
+      BuildTargetParser buildTargetParser,
+      Platform platform) {
     this.projectFilesystem = Preconditions.checkNotNull(projectFilesystem);
     this.buildTargetParser = Preconditions.checkNotNull(buildTargetParser);
 
@@ -132,6 +135,8 @@
     this.aliasToBuildTargetMap = createAliasToBuildTargetMap(
         this.getEntriesForSection(ALIAS_SECTION_HEADER),
         buildTargetParser);
+
+    this.platform = platform;
   }
 
   /**
@@ -142,7 +147,8 @@
    * @param files The sequence of {@code .buckconfig} files to load.
    */
   public static BuckConfig createFromFiles(ProjectFilesystem projectFilesystem,
-      Iterable<File> files)
+      Iterable<File> files,
+      Platform platform)
       throws IOException {
     Preconditions.checkNotNull(projectFilesystem);
     Preconditions.checkNotNull(files);
@@ -152,7 +158,8 @@
       return new BuckConfig(
           ImmutableMap.<String, Map<String, String>>of(),
           projectFilesystem,
-          buildTargetParser);
+          buildTargetParser,
+          platform);
     }
 
     // Convert the Files to Readers.
@@ -160,7 +167,7 @@
     for (File file : files) {
       readers.add(Files.newReader(file, Charsets.UTF_8));
     }
-    return createFromReaders(readers.build(), projectFilesystem, buildTargetParser);
+    return createFromReaders(readers.build(), projectFilesystem, buildTargetParser, platform);
   }
 
   /**
@@ -199,9 +206,11 @@
   static BuckConfig createFromReader(
       Reader reader,
       ProjectFilesystem projectFilesystem,
-      BuildTargetParser buildTargetParser)
+      BuildTargetParser buildTargetParser,
+      Platform platform)
       throws IOException {
-    return createFromReaders(ImmutableList.of(reader), projectFilesystem, buildTargetParser);
+    return createFromReaders(
+        ImmutableList.of(reader), projectFilesystem, buildTargetParser, platform);
   }
 
   @VisibleForTesting
@@ -256,10 +265,11 @@
   @VisibleForTesting
   static BuckConfig createFromReaders(Iterable<Reader> readers,
       ProjectFilesystem projectFilesystem,
-      BuildTargetParser buildTargetParser)
+      BuildTargetParser buildTargetParser,
+      Platform platform)
       throws IOException {
     Map<String, Map<String, String>> sectionsToEntries = createFromReaders(readers);
-    return new BuckConfig(sectionsToEntries, projectFilesystem, buildTargetParser);
+    return new BuckConfig(sectionsToEntries, projectFilesystem, buildTargetParser, platform);
   }
 
   public ImmutableMap<String, String> getEntriesForSection(String section) {
@@ -462,7 +472,7 @@
       // It would be nice to be able to mirror those nuances.
       case "auto":
       default:
-        return new Ansi(Platform.detect());
+        return new Ansi(platform);
     }
   }
 
diff --git a/src/com/facebook/buck/cli/BuildCommand.java b/src/com/facebook/buck/cli/BuildCommand.java
index 8e15e56..72cddd2 100644
--- a/src/com/facebook/buck/cli/BuildCommand.java
+++ b/src/com/facebook/buck/cli/BuildCommand.java
@@ -106,7 +106,8 @@
         artifactCache,
         console,
         getBuckEventBus(),
-        Optional.<TargetDevice>absent());
+        Optional.<TargetDevice>absent(),
+        getCommandRunnerParams().getPlatform());
     int exitCode = 0;
     try {
       exitCode = executeBuildAndPrintAnyFailuresToConsole(build, console);
diff --git a/src/com/facebook/buck/cli/BuildCommandOptions.java b/src/com/facebook/buck/cli/BuildCommandOptions.java
index d99a6ce..73caba9 100644
--- a/src/com/facebook/buck/cli/BuildCommandOptions.java
+++ b/src/com/facebook/buck/cli/BuildCommandOptions.java
@@ -26,6 +26,7 @@
 import com.facebook.buck.util.HumanReadableException;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.facebook.buck.util.Verbosity;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.base.Supplier;
@@ -139,7 +140,8 @@
       ArtifactCache artifactCache,
       Console console,
       BuckEventBus eventBus,
-      Optional<TargetDevice> targetDevice) {
+      Optional<TargetDevice> targetDevice,
+      Platform platform) {
     if (console.getVerbosity() == Verbosity.ALL) {
       console.getStdErr().printf("Creating a build with %d threads.\n", numThreads);
     }
@@ -156,6 +158,7 @@
         isCodeCoverageEnabled(),
         isDebugEnabled(),
         getBuildDependencies(),
-        eventBus);
+        eventBus,
+        platform);
   }
 }
diff --git a/src/com/facebook/buck/cli/CommandRunnerParams.java b/src/com/facebook/buck/cli/CommandRunnerParams.java
index f12c5a6..52ca882 100644
--- a/src/com/facebook/buck/cli/CommandRunnerParams.java
+++ b/src/com/facebook/buck/cli/CommandRunnerParams.java
@@ -23,6 +23,7 @@
 import com.facebook.buck.util.Console;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.facebook.buck.util.Verbosity;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Preconditions;
 
 /**
@@ -37,6 +38,7 @@
   private final Console console;
   private final Parser parser;
   private final BuckEventBus eventBus;
+  private final Platform platform;
 
   public CommandRunnerParams(
       Console console,
@@ -44,13 +46,15 @@
       KnownBuildRuleTypes buildRuleTypes,
       ArtifactCacheFactory artifactCacheFactory,
       BuckEventBus eventBus,
-      String pythonInterpreter) {
+      String pythonInterpreter,
+      Platform platform) {
     this(console,
         projectFilesystem,
         buildRuleTypes,
         artifactCacheFactory,
         eventBus,
-        new Parser(projectFilesystem, buildRuleTypes, console, pythonInterpreter));
+        new Parser(projectFilesystem, buildRuleTypes, console, pythonInterpreter),
+        platform);
   }
 
   public CommandRunnerParams(
@@ -59,13 +63,15 @@
       KnownBuildRuleTypes buildRuleTypes,
       ArtifactCacheFactory artifactCacheFactory,
       BuckEventBus eventBus,
-      Parser parser) {
+      Parser parser,
+      Platform platform) {
     this.console = Preconditions.checkNotNull(console);
     this.projectFilesystem = Preconditions.checkNotNull(projectFilesystem);
     this.buildRuleTypes = Preconditions.checkNotNull(buildRuleTypes);
     this.artifactCacheFactory = Preconditions.checkNotNull(artifactCacheFactory);
     this.eventBus = Preconditions.checkNotNull(eventBus);
     this.parser = Preconditions.checkNotNull(parser);
+    this.platform = Preconditions.checkNotNull(platform);
   }
 
   public Ansi getAnsi() {
@@ -99,4 +105,8 @@
   public BuckEventBus getBuckEventBus() {
     return eventBus;
   }
+
+  public Platform getPlatform() {
+    return platform;
+  }
 }
diff --git a/src/com/facebook/buck/cli/Main.java b/src/com/facebook/buck/cli/Main.java
index 6680bf4..a4d5a04 100644
--- a/src/com/facebook/buck/cli/Main.java
+++ b/src/com/facebook/buck/cli/Main.java
@@ -77,6 +77,8 @@
 
   private static final Semaphore commandSemaphore = new Semaphore(1);
 
+  private final Platform platform;
+
   /**
    * Daemon used to monitor the file system and cache build rules between Main() method
    * invocations is static so that it can outlive Main() objects and survive for the lifetime
@@ -160,6 +162,7 @@
   public Main(PrintStream stdOut, PrintStream stdErr) {
     this.stdOut = Preconditions.checkNotNull(stdOut);
     this.stdErr = Preconditions.checkNotNull(stdErr);
+    this.platform = Platform.detect();
   }
 
   /** Prints the usage message to standard error. */
@@ -209,8 +212,8 @@
     // solves a bootstrapping issue).
     ProjectFilesystem projectFilesystem = new ProjectFilesystem(
         projectRoot,
-        createBuckConfig(new ProjectFilesystem(projectRoot)).getIgnorePaths());
-    BuckConfig config = createBuckConfig(projectFilesystem);
+        createBuckConfig(new ProjectFilesystem(projectRoot), platform).getIgnorePaths());
+    BuckConfig config = createBuckConfig(projectFilesystem, platform);
     Verbosity verbosity = VerbosityParser.parse(args);
     final Console console = new Console(verbosity, stdOut, stdErr, config.createAnsi());
     KnownBuildRuleTypes knownBuildRuleTypes = new KnownBuildRuleTypes();
@@ -271,7 +274,8 @@
           new KnownBuildRuleTypes(),
           artifactCacheFactory,
           buildEventBus,
-          parser));
+          parser,
+          platform));
 
       buildEventBus.post(CommandEvent.finished(commandName, isDaemon(), exitCode));
 
@@ -331,7 +335,7 @@
   /**
    * @param projectFilesystem The directory that is the root of the project being built.
    */
-  private static BuckConfig createBuckConfig(ProjectFilesystem projectFilesystem)
+  private static BuckConfig createBuckConfig(ProjectFilesystem projectFilesystem, Platform platform)
       throws IOException {
     ImmutableList.Builder<File> configFileBuilder = ImmutableList.builder();
     File configFile = projectFilesystem.getFileForRelativePath(DEFAULT_BUCK_CONFIG_FILE_NAME);
@@ -345,7 +349,7 @@
     }
 
     ImmutableList<File> configFiles = configFileBuilder.build();
-    return BuckConfig.createFromFiles(projectFilesystem, configFiles);
+    return BuckConfig.createFromFiles(projectFilesystem, configFiles, platform);
   }
 
   @VisibleForTesting
@@ -360,7 +364,7 @@
       Console console = new Console(Verbosity.STANDARD_INFORMATION,
           stdOut,
           stdErr,
-          new Ansi(Platform.detect()));
+          new Ansi(platform));
       console.printBuildFailure(e.getHumanReadableErrorMessage());
       return FAIL_EXIT_CODE;
     } finally {
diff --git a/src/com/facebook/buck/cli/TestCommand.java b/src/com/facebook/buck/cli/TestCommand.java
index b3cd150..a52baf6 100644
--- a/src/com/facebook/buck/cli/TestCommand.java
+++ b/src/com/facebook/buck/cli/TestCommand.java
@@ -295,7 +295,8 @@
         getArtifactCache(),
         console,
         getBuckEventBus(),
-        options.getTargetDeviceOptional());
+        options.getTargetDeviceOptional(),
+        getCommandRunnerParams().getPlatform());
     int exitCode = BuildCommand.executeBuildAndPrintAnyFailuresToConsole(build, console);
     if (exitCode != 0) {
       return exitCode;
diff --git a/src/com/facebook/buck/command/BUCK b/src/com/facebook/buck/command/BUCK
index 9d4d0be..7e6210b 100644
--- a/src/com/facebook/buck/command/BUCK
+++ b/src/com/facebook/buck/command/BUCK
@@ -23,6 +23,7 @@
     '//src/com/facebook/buck/util:exceptions',
     '//src/com/facebook/buck/util:io',
     '//src/com/facebook/buck/util:util',
+    '//src/com/facebook/buck/util/environment:environment',
   ],
   visibility = [
     '//src/com/facebook/buck/cli:cli',
diff --git a/src/com/facebook/buck/command/Build.java b/src/com/facebook/buck/command/Build.java
index 92af738..54a04b9 100644
--- a/src/com/facebook/buck/command/Build.java
+++ b/src/com/facebook/buck/command/Build.java
@@ -38,6 +38,7 @@
 import com.facebook.buck.util.AndroidPlatformTarget;
 import com.facebook.buck.util.Console;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -86,7 +87,8 @@
       boolean isCodeCoverageEnabled,
       boolean isDebugEnabled,
       BuildDependencies buildDependencies,
-      BuckEventBus eventBus) {
+      BuckEventBus eventBus,
+      Platform platform) {
     this.dependencyGraph = Preconditions.checkNotNull(dependencyGraph);
 
     Optional<AndroidPlatformTarget> androidPlatformTarget = findAndroidPlatformTarget(
@@ -101,6 +103,7 @@
         .setCodeCoverageEnabled(isCodeCoverageEnabled)
         .setDebugEnabled(isDebugEnabled)
         .setEventBus(eventBus)
+        .setPlatform(platform)
         .build();
     this.artifactCache = Preconditions.checkNotNull(artifactCache);
     this.stepRunner = new DefaultStepRunner(executionContext, listeningExecutorService);
diff --git a/src/com/facebook/buck/shell/RunShTestAndRecordResultStep.java b/src/com/facebook/buck/shell/RunShTestAndRecordResultStep.java
index 0827581..0d06b56 100644
--- a/src/com/facebook/buck/shell/RunShTestAndRecordResultStep.java
+++ b/src/com/facebook/buck/shell/RunShTestAndRecordResultStep.java
@@ -56,7 +56,7 @@
   @Override
   public int execute(ExecutionContext context) {
     TestResultSummary summary;
-    if (Platform.detect() == Platform.WINDOWS) {
+    if (context.getPlatform() == Platform.WINDOWS) {
       // Ignore sh_test on Windows.
       summary = new TestResultSummary(
           pathToShellScript,
diff --git a/src/com/facebook/buck/step/BUCK b/src/com/facebook/buck/step/BUCK
index afd8a13..fd33bc6 100644
--- a/src/com/facebook/buck/step/BUCK
+++ b/src/com/facebook/buck/step/BUCK
@@ -10,6 +10,7 @@
     '//src/com/facebook/buck/util:exceptions',
     '//src/com/facebook/buck/util:io',
     '//src/com/facebook/buck/util:util',
+    '//src/com/facebook/buck/util/environment:environment',
     '//src/com/facebook/buck/util/concurrent:concurrent',
   ],
   visibility = [ 'PUBLIC' ],
diff --git a/src/com/facebook/buck/step/ExecutionContext.java b/src/com/facebook/buck/step/ExecutionContext.java
index ab85b03..a9f4f8d 100644
--- a/src/com/facebook/buck/step/ExecutionContext.java
+++ b/src/com/facebook/buck/step/ExecutionContext.java
@@ -24,6 +24,7 @@
 import com.facebook.buck.util.ProcessExecutor;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.facebook.buck.util.Verbosity;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 
@@ -43,6 +44,7 @@
   private final boolean isDebugEnabled;
   private final ProcessExecutor processExecutor;
   private final BuckEventBus eventBus;
+  private final Platform platform;
 
   private ExecutionContext(
       ProjectFilesystem projectFilesystem,
@@ -53,7 +55,8 @@
       long defaultTestTimeoutMillis,
       boolean isCodeCoverageEnabled,
       boolean isDebugEnabled,
-      BuckEventBus eventBus) {
+      BuckEventBus eventBus,
+      Platform platform) {
     this.verbosity = Preconditions.checkNotNull(console).getVerbosity();
     this.projectFilesystem = Preconditions.checkNotNull(projectFilesystem);
     this.console = Preconditions.checkNotNull(console);
@@ -65,6 +68,7 @@
     this.isDebugEnabled = isDebugEnabled;
     this.processExecutor = new ProcessExecutor(console);
     this.eventBus = Preconditions.checkNotNull(eventBus);
+    this.platform = Preconditions.checkNotNull(platform);
   }
 
   /**
@@ -81,7 +85,8 @@
         getDefaultTestTimeoutMillis(),
         isCodeCoverageEnabled(),
         isDebugEnabled,
-        eventBus);
+        eventBus,
+        platform);
   }
 
   public Verbosity getVerbosity() {
@@ -116,6 +121,10 @@
     return eventBus;
   }
 
+  public Platform getPlatform() {
+    return platform;
+  }
+
   /**
    * Returns the {@link AndroidPlatformTarget}, if present. If not, throws a
    * {@link NoAndroidSdkException}. Use this when your logic requires the user to specify the
@@ -186,6 +195,7 @@
     private boolean isCodeCoverageEnabled = false;
     private boolean isDebugEnabled = false;
     private BuckEventBus eventBus = null;
+    private Platform platform = null;
 
     private Builder() {}
 
@@ -199,7 +209,8 @@
           defaultTestTimeoutMillis,
           isCodeCoverageEnabled,
           isDebugEnabled,
-          eventBus);
+          eventBus,
+          platform);
     }
 
     public Builder setExecutionContext(ExecutionContext executionContext) {
@@ -212,6 +223,7 @@
       setCodeCoverageEnabled(executionContext.isCodeCoverageEnabled());
       setDebugEnabled(executionContext.isDebugEnabled());
       setEventBus(executionContext.getBuckEventBus());
+      setPlatform(executionContext.getPlatform());
       return this;
     }
 
@@ -262,5 +274,10 @@
       this.eventBus = Preconditions.checkNotNull(eventBus);
       return this;
     }
+
+    public Builder setPlatform(Platform platform) {
+      this.platform = Preconditions.checkNotNull(platform);
+      return this;
+    }
   }
 }
diff --git a/test/com/facebook/buck/android/AndroidBinaryRuleTest.java b/test/com/facebook/buck/android/AndroidBinaryRuleTest.java
index 0c9b71e..c7982cc 100644
--- a/test/com/facebook/buck/android/AndroidBinaryRuleTest.java
+++ b/test/com/facebook/buck/android/AndroidBinaryRuleTest.java
@@ -51,6 +51,7 @@
 import com.facebook.buck.util.Paths;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.facebook.buck.util.ZipSplitter;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
@@ -601,6 +602,7 @@
         .setConsole(new TestConsole())
         .setProjectFilesystem(new ProjectFilesystem(new File(".")))
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
 
     assertEquals(UnzipStep.class, steps.get(1).getClass());
diff --git a/test/com/facebook/buck/android/ApkGenruleTest.java b/test/com/facebook/buck/android/ApkGenruleTest.java
index 74afec6..e2c16ce 100644
--- a/test/com/facebook/buck/android/ApkGenruleTest.java
+++ b/test/com/facebook/buck/android/ApkGenruleTest.java
@@ -48,6 +48,7 @@
 import com.facebook.buck.step.fs.RmStep;
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Function;
 import com.google.common.base.Functions;
 import com.google.common.collect.ImmutableList;
@@ -236,6 +237,7 @@
           }
         })
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.LINUX) // Fix platform to Linux to use bash in genrule.
         .build();
   }
 }
diff --git a/test/com/facebook/buck/android/BUCK b/test/com/facebook/buck/android/BUCK
index ba27005..c6d9a76 100644
--- a/test/com/facebook/buck/android/BUCK
+++ b/test/com/facebook/buck/android/BUCK
@@ -25,6 +25,7 @@
     '//src/com/facebook/buck/util:exceptions',
     '//src/com/facebook/buck/util:io',
     '//src/com/facebook/buck/util:util',
+    '//src/com/facebook/buck/util/environment:environment',
     '//test/com/facebook/buck/java:fakes',
     '//test/com/facebook/buck/event:testutil',
     '//test/com/facebook/buck/model:BuildTargetFactory',
diff --git a/test/com/facebook/buck/android/GenerateManifestStepTest.java b/test/com/facebook/buck/android/GenerateManifestStepTest.java
index 7ef8693..64779b7 100644
--- a/test/com/facebook/buck/android/GenerateManifestStepTest.java
+++ b/test/com/facebook/buck/android/GenerateManifestStepTest.java
@@ -16,10 +16,13 @@
 
 package com.facebook.buck.android;
 
-import static org.easymock.EasyMock.createMock;
 import static org.junit.Assert.assertEquals;
 
+import com.facebook.buck.event.BuckEventBusFactory;
 import com.facebook.buck.step.ExecutionContext;
+import com.facebook.buck.testutil.TestConsole;
+import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.io.Files;
@@ -58,7 +61,13 @@
     libraryManifestFiles.add(libraryManifestB);
     libraryManifestFiles.add(libraryManifestC);
 
-    ExecutionContext context = createMock(ExecutionContext.class);
+    ExecutionContext context = ExecutionContext.builder()
+        .setConsole(new TestConsole())
+        .setProjectFilesystem(new ProjectFilesystem(new File(".")))
+        .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
+        .build();
+
     GenerateManifestStep manifestCommand = new GenerateManifestStep(
         skeletonPath,
         libraryManifestFiles.build(),
diff --git a/test/com/facebook/buck/cli/AbstractCommandOptionsTest.java b/test/com/facebook/buck/cli/AbstractCommandOptionsTest.java
index 0ddcbab..cf2d79b 100644
--- a/test/com/facebook/buck/cli/AbstractCommandOptionsTest.java
+++ b/test/com/facebook/buck/cli/AbstractCommandOptionsTest.java
@@ -24,15 +24,12 @@
 
 import com.facebook.buck.util.HumanReadableException;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.google.common.base.Optional;
+import org.easymock.EasyMockSupport;
+import org.junit.Test;
 
 import java.io.File;
 
-import org.easymock.EasyMockSupport;
-
-import com.google.common.base.Optional;
-
-import org.junit.Test;
-
 /** Unit test for {@link AbstractCommandOptions}. */
 public class AbstractCommandOptionsTest extends EasyMockSupport {
 
diff --git a/test/com/facebook/buck/cli/AuditClasspathCommandTest.java b/test/com/facebook/buck/cli/AuditClasspathCommandTest.java
index e3d77cb..94c1b82 100644
--- a/test/com/facebook/buck/cli/AuditClasspathCommandTest.java
+++ b/test/com/facebook/buck/cli/AuditClasspathCommandTest.java
@@ -39,6 +39,7 @@
 import com.facebook.buck.testutil.RuleMap;
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableSet;
@@ -74,7 +75,8 @@
         buildRuleTypes,
         new InstanceArtifactCacheFactory(artifactCache),
         eventBus,
-        BuckTestConstant.PYTHON_INTERPRETER));
+        BuckTestConstant.PYTHON_INTERPRETER,
+        Platform.detect()));
   }
 
   private PartialGraph createGraphFromBuildRules(BuildRuleResolver ruleResolver,
diff --git a/test/com/facebook/buck/cli/AuditOwnerCommandTest.java b/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
index f560a0f..1566eb8 100644
--- a/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
+++ b/test/com/facebook/buck/cli/AuditOwnerCommandTest.java
@@ -40,6 +40,7 @@
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.Console;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSortedSet;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -236,7 +237,8 @@
         buildRuleTypes,
         new InstanceArtifactCacheFactory(artifactCache),
         eventBus,
-        buckConfig.getPythonInterpreter()));
+        buckConfig.getPythonInterpreter(),
+        Platform.detect()));
   }
 
   @Test
diff --git a/test/com/facebook/buck/cli/BUCK b/test/com/facebook/buck/cli/BUCK
index 767981d..0db9351 100644
--- a/test/com/facebook/buck/cli/BUCK
+++ b/test/com/facebook/buck/cli/BUCK
@@ -17,6 +17,7 @@
     '//src/com/facebook/buck/parser:support',
     '//src/com/facebook/buck/rules:rules',
     '//src/com/facebook/buck/util:io',
+    '//src/com/facebook/buck/util/environment:environment',
   ],
 )
 
@@ -77,6 +78,7 @@
     '//src/com/facebook/buck/util:exceptions',
     '//src/com/facebook/buck/util:io',
     '//src/com/facebook/buck/util:util',
+    '//src/com/facebook/buck/util/environment:environment',
     '//src/com/facebook/buck/timing:timing',
     '//test/com/facebook/buck/event:testutil',
     '//test/com/facebook/buck/model:BuildTargetFactory',
diff --git a/test/com/facebook/buck/cli/BuckConfigTest.java b/test/com/facebook/buck/cli/BuckConfigTest.java
index a16c193..bfaf5d9 100644
--- a/test/com/facebook/buck/cli/BuckConfigTest.java
+++ b/test/com/facebook/buck/cli/BuckConfigTest.java
@@ -33,6 +33,7 @@
 import com.facebook.buck.util.BuckConstant;
 import com.facebook.buck.util.HumanReadableException;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Functions;
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
@@ -342,7 +343,7 @@
     Reader reader = new StringReader(Joiner.on('\n').join(
         "[project]",
         "ignore = .git, foo, bar/, baz//, a/b/c"));
-    BuckConfig config = BuckConfig.createFromReader(reader, filesystem, parser);
+    BuckConfig config = BuckConfig.createFromReader(reader, filesystem, parser, Platform.detect());
 
     ImmutableSet<String> ignorePaths = config.getIgnorePaths();
     assertEquals("Should ignore paths, sans trailing slashes", ignorePaths, ImmutableSet.of(
@@ -370,7 +371,7 @@
     Reader reader = new StringReader(Joiner.on('\n').join(
         "[cache]",
         "dir = cache_dir"));
-    BuckConfig config = BuckConfig.createFromReader(reader, filesystem, parser);
+    BuckConfig config = BuckConfig.createFromReader(reader, filesystem, parser, Platform.detect());
 
     ImmutableSet<String> ignorePaths = config.getIgnorePaths();
     assertTrue("Relative cache directory should be in set of ignored paths",
@@ -388,7 +389,7 @@
     Reader reader = new StringReader(Joiner.on('\n').join(
         "[cache]",
         "dir = /cache_dir"));
-    BuckConfig config = BuckConfig.createFromReader(reader, filesystem, parser);
+    BuckConfig config = BuckConfig.createFromReader(reader, filesystem, parser, Platform.detect());
 
     ImmutableSet<String> ignorePaths = config.getIgnorePaths();
     assertFalse("Absolute cache directory should not be in set of ignored paths",
@@ -436,6 +437,6 @@
     if (parser == null) {
       parser = new BuildTargetParser(projectFilesystem);
     }
-    return BuckConfig.createFromReader(reader, projectFilesystem, parser);
+    return BuckConfig.createFromReader(reader, projectFilesystem, parser, Platform.detect());
   }
 }
diff --git a/test/com/facebook/buck/cli/CleanCommandTest.java b/test/com/facebook/buck/cli/CleanCommandTest.java
index 59b3fbf..a9bc05c 100644
--- a/test/com/facebook/buck/cli/CleanCommandTest.java
+++ b/test/com/facebook/buck/cli/CleanCommandTest.java
@@ -27,6 +27,7 @@
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.BuckConstant;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 
 import org.easymock.Capture;
 import org.easymock.EasyMockSupport;
@@ -102,7 +103,8 @@
         createMock(KnownBuildRuleTypes.class),
         new InstanceArtifactCacheFactory(createMock(ArtifactCache.class)),
         createMock(BuckEventBus.class),
-        createMock(Parser.class));
+        createMock(Parser.class),
+        Platform.detect());
     return new CleanCommand(params);
   }
 
diff --git a/test/com/facebook/buck/cli/FakeBuckConfig.java b/test/com/facebook/buck/cli/FakeBuckConfig.java
index 9227fec..50b352a 100644
--- a/test/com/facebook/buck/cli/FakeBuckConfig.java
+++ b/test/com/facebook/buck/cli/FakeBuckConfig.java
@@ -18,6 +18,7 @@
 
 import com.facebook.buck.parser.BuildTargetParser;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.collect.ImmutableMap;
 
 import java.io.File;
@@ -46,7 +47,8 @@
       Map<String, Map<String, String>> sections,
       ProjectFilesystem projectFilesystem) {
     super(sections,
-      projectFilesystem,
-      new BuildTargetParser(projectFilesystem));
+        projectFilesystem,
+        new BuildTargetParser(projectFilesystem),
+        Platform.detect());
   }
 }
diff --git a/test/com/facebook/buck/cli/InstallCommandTest.java b/test/com/facebook/buck/cli/InstallCommandTest.java
index 9576f41..5f8816f 100644
--- a/test/com/facebook/buck/cli/InstallCommandTest.java
+++ b/test/com/facebook/buck/cli/InstallCommandTest.java
@@ -35,6 +35,7 @@
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.Console;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -96,7 +97,8 @@
         buildRuleTypes,
         new InstanceArtifactCacheFactory(artifactCache),
         eventBus,
-        BuckTestConstant.PYTHON_INTERPRETER));
+        BuckTestConstant.PYTHON_INTERPRETER,
+        Platform.detect()));
   }
 
   /**
diff --git a/test/com/facebook/buck/cli/ProjectCommandTest.java b/test/com/facebook/buck/cli/ProjectCommandTest.java
index 4d4d060..bf6030e 100644
--- a/test/com/facebook/buck/cli/ProjectCommandTest.java
+++ b/test/com/facebook/buck/cli/ProjectCommandTest.java
@@ -46,6 +46,7 @@
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.ProcessExecutor;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
@@ -117,7 +118,8 @@
     return BuckConfig.createFromReader(
         new StringReader(contents),
         dummyProjectFilesystem,
-        new BuildTargetParser(dummyProjectFilesystem));
+        new BuildTargetParser(dummyProjectFilesystem),
+        Platform.detect());
   }
 
   private static void checkPredicate(
@@ -172,7 +174,8 @@
           new KnownBuildRuleTypes(),
           new InstanceArtifactCacheFactory(artifactCache),
           BuckEventBusFactory.newInstance(),
-          BuckTestConstant.PYTHON_INTERPRETER));
+          BuckTestConstant.PYTHON_INTERPRETER,
+          Platform.detect()));
     }
 
     @Override
diff --git a/test/com/facebook/buck/cli/TargetsCommandTest.java b/test/com/facebook/buck/cli/TargetsCommandTest.java
index 9674159..8672c1f 100644
--- a/test/com/facebook/buck/cli/TargetsCommandTest.java
+++ b/test/com/facebook/buck/cli/TargetsCommandTest.java
@@ -51,6 +51,7 @@
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.BuckConstant;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonParser.Feature;
 import com.fasterxml.jackson.databind.JsonNode;
@@ -125,7 +126,8 @@
             buildRuleTypes,
             new InstanceArtifactCacheFactory(artifactCache),
             eventBus,
-            BuckTestConstant.PYTHON_INTERPRETER));
+            BuckTestConstant.PYTHON_INTERPRETER,
+            Platform.detect()));
   }
 
   @Test
@@ -240,7 +242,7 @@
     EasyMock.replay(parser);
     Reader reader = new StringReader("");
     BuckConfig config = BuckConfig.createFromReader(
-        reader, new ProjectFilesystem(new File(".")), parser);
+        reader, new ProjectFilesystem(new File(".")), parser, Platform.detect());
     TargetsCommandOptions options = new TargetsCommandOptions(config);
 
     // Test a valid target.
diff --git a/test/com/facebook/buck/java/BUCK b/test/com/facebook/buck/java/BUCK
index a98086c..2b21356 100644
--- a/test/com/facebook/buck/java/BUCK
+++ b/test/com/facebook/buck/java/BUCK
@@ -52,6 +52,7 @@
     '//src/com/facebook/buck/util:constants',
     '//src/com/facebook/buck/util:io',
     '//src/com/facebook/buck/util:util',
+    '//src/com/facebook/buck/util/environment:environment',
     '//test/com/facebook/buck/event:testutil',
     '//test/com/facebook/buck/model:BuildTargetFactory',
     '//test/com/facebook/buck/rules:testutil',
diff --git a/test/com/facebook/buck/java/DefaultJavaLibraryRuleTest.java b/test/com/facebook/buck/java/DefaultJavaLibraryRuleTest.java
index 1ddb5f7..883474a 100644
--- a/test/com/facebook/buck/java/DefaultJavaLibraryRuleTest.java
+++ b/test/com/facebook/buck/java/DefaultJavaLibraryRuleTest.java
@@ -64,6 +64,7 @@
 import com.facebook.buck.util.DefaultDirectoryTraverser;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.facebook.buck.util.Verbosity;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Functions;
 import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
@@ -928,6 +929,7 @@
           .setConsole(new Console(Verbosity.SILENT, System.out, System.err, Ansi.withoutTty()))
           .setDebugEnabled(true)
           .setEventBus(BuckEventBusFactory.newInstance())
+          .setPlatform(Platform.detect())
           .build();
 
       ImmutableList<String> options = javacCommand.getOptions(executionContext,
diff --git a/test/com/facebook/buck/java/DependencyCheckingJavacStepTest.java b/test/com/facebook/buck/java/DependencyCheckingJavacStepTest.java
index 6acb4ab..06fa542 100644
--- a/test/com/facebook/buck/java/DependencyCheckingJavacStepTest.java
+++ b/test/com/facebook/buck/java/DependencyCheckingJavacStepTest.java
@@ -23,6 +23,7 @@
 import com.facebook.buck.step.ExecutionContext;
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Function;
 import com.google.common.base.Functions;
 import com.google.common.base.Joiner;
@@ -64,7 +65,9 @@
           }
         })
         .setConsole(new TestConsole())
-        .setEventBus(BuckEventBusFactory.newInstance()).build();
+        .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
+        .build();
 
     DependencyCheckingJavacStep firstOrder = createTestStep(BuildDependencies.FIRST_ORDER_ONLY);
     DependencyCheckingJavacStep warn = createTestStep(BuildDependencies.WARN_ON_TRANSITIVE);
diff --git a/test/com/facebook/buck/java/JUnitStepTest.java b/test/com/facebook/buck/java/JUnitStepTest.java
index 91337bf..17cf135 100644
--- a/test/com/facebook/buck/java/JUnitStepTest.java
+++ b/test/com/facebook/buck/java/JUnitStepTest.java
@@ -25,6 +25,7 @@
 import com.facebook.buck.util.AndroidPlatformTarget;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.facebook.buck.util.Verbosity;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
@@ -125,6 +126,7 @@
         .setConsole(console)
         .setDebugEnabled(true)
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
 
     List<String> observedArgs = junit.getShellCommand(executionContext);
diff --git a/test/com/facebook/buck/java/JarDirectoryStepTest.java b/test/com/facebook/buck/java/JarDirectoryStepTest.java
index c30f4db..8f30b46 100644
--- a/test/com/facebook/buck/java/JarDirectoryStepTest.java
+++ b/test/com/facebook/buck/java/JarDirectoryStepTest.java
@@ -24,6 +24,7 @@
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.testutil.Zip;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.collect.ImmutableSet;
 
 import org.junit.Rule;
@@ -53,6 +54,7 @@
         .setProjectFilesystem(new ProjectFilesystem(zipup))
         .setConsole(new TestConsole())
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
 
     int returnCode = step.execute(context);
@@ -82,6 +84,7 @@
         .setProjectFilesystem(new ProjectFilesystem(zipup))
         .setConsole(new TestConsole())
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
 
     int returnCode = step.execute(context);
diff --git a/test/com/facebook/buck/java/JavacInMemoryStepTest.java b/test/com/facebook/buck/java/JavacInMemoryStepTest.java
index 4032d28..c54e4c9 100644
--- a/test/com/facebook/buck/java/JavacInMemoryStepTest.java
+++ b/test/com/facebook/buck/java/JavacInMemoryStepTest.java
@@ -25,6 +25,7 @@
 import com.facebook.buck.step.ExecutionContext;
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Charsets;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
@@ -125,6 +126,7 @@
         .setProjectFilesystem(new ProjectFilesystem(tmp.getRoot()))
         .setConsole(new TestConsole())
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
   }
 }
diff --git a/test/com/facebook/buck/shell/GenruleTest.java b/test/com/facebook/buck/shell/GenruleTest.java
index f560160..b0fe078 100644
--- a/test/com/facebook/buck/shell/GenruleTest.java
+++ b/test/com/facebook/buck/shell/GenruleTest.java
@@ -51,6 +51,7 @@
 import com.facebook.buck.util.Console;
 import com.facebook.buck.util.ProjectFilesystem;
 import com.facebook.buck.util.Verbosity;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Function;
 import com.google.common.base.Functions;
 import com.google.common.base.Optional;
@@ -236,6 +237,7 @@
           }
         })
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
   }
 
@@ -464,6 +466,7 @@
         .setProjectFilesystem(new ProjectFilesystem(new File(".")))
         .setAndroidPlatformTarget(Optional.of(android))
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
 
     ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
diff --git a/test/com/facebook/buck/step/BUCK b/test/com/facebook/buck/step/BUCK
index c7fd96d..ee6c309 100644
--- a/test/com/facebook/buck/step/BUCK
+++ b/test/com/facebook/buck/step/BUCK
@@ -27,6 +27,7 @@
     '//src/com/facebook/buck/step:step',
     '//src/com/facebook/buck/util:io',
     '//src/com/facebook/buck/util:util',
+    '//src/com/facebook/buck/util/environment:environment',
     '//test/com/facebook/buck/event:testutil',
     '//test/com/facebook/buck/testutil:testutil',
     '//test/com/facebook/buck/timing:testutil',
diff --git a/test/com/facebook/buck/step/DefaultStepRunnerTest.java b/test/com/facebook/buck/step/DefaultStepRunnerTest.java
index ce30caa..4d0ca12 100644
--- a/test/com/facebook/buck/step/DefaultStepRunnerTest.java
+++ b/test/com/facebook/buck/step/DefaultStepRunnerTest.java
@@ -26,6 +26,7 @@
 import com.facebook.buck.event.TestEventConfigerator;
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.ListeningExecutorService;
@@ -55,6 +56,7 @@
         .setProjectFilesystem(createMock(ProjectFilesystem.class))
         .setConsole(new TestConsole())
         .setEventBus(eventBus)
+        .setPlatform(Platform.detect())
         .build();
 
     ThreadFactory threadFactory = new ThreadFactoryBuilder()
@@ -100,6 +102,7 @@
         .setProjectFilesystem(createMock(ProjectFilesystem.class))
         .setConsole(new TestConsole())
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
     ThreadFactory threadFactory = new ThreadFactoryBuilder()
         .setDaemon(true)
diff --git a/test/com/facebook/buck/step/fs/BUCK b/test/com/facebook/buck/step/fs/BUCK
index 74c7773..8a72d75 100644
--- a/test/com/facebook/buck/step/fs/BUCK
+++ b/test/com/facebook/buck/step/fs/BUCK
@@ -13,6 +13,7 @@
     '//src/com/facebook/buck/step:step',
     '//src/com/facebook/buck/step/fs:fs',
     '//src/com/facebook/buck/util:io',
+    '//src/com/facebook/buck/util/environment:environment',
     '//test/com/facebook/buck/event:testutil',
     '//test/com/facebook/buck/testutil:testutil',
     '//test/com/facebook/buck/testutil/integration:integration',
diff --git a/test/com/facebook/buck/step/fs/SymlinkFileStepTest.java b/test/com/facebook/buck/step/fs/SymlinkFileStepTest.java
index 4e6e0a1..1892796 100644
--- a/test/com/facebook/buck/step/fs/SymlinkFileStepTest.java
+++ b/test/com/facebook/buck/step/fs/SymlinkFileStepTest.java
@@ -22,6 +22,7 @@
 import com.facebook.buck.step.ExecutionContext;
 import com.facebook.buck.testutil.TestConsole;
 import com.facebook.buck.util.ProjectFilesystem;
+import com.facebook.buck.util.environment.Platform;
 import com.google.common.base.Charsets;
 import com.google.common.io.Files;
 
@@ -43,6 +44,7 @@
         .setConsole(new TestConsole())
         .setProjectFilesystem(new ProjectFilesystem(tmpDir.getRoot()))
         .setEventBus(BuckEventBusFactory.newInstance())
+        .setPlatform(Platform.detect())
         .build();
 
     File source = tmpDir.newFile();