/* * Copyright 2016-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.io; import com.facebook.buck.eden.EdenClient; import com.facebook.buck.eden.EdenMount; import com.facebook.buck.eden.EdenProjectFilesystemDelegate; import com.facebook.buck.log.Logger; import com.facebook.buck.util.PrintStreamProcessExecutorFactory; import com.facebook.buck.util.autosparse.AbstractAutoSparseFactory; import com.facebook.buck.util.autosparse.AutoSparseConfig; import com.facebook.buck.util.autosparse.AutoSparseProjectFilesystemDelegate; import com.facebook.buck.util.autosparse.AutoSparseState; import com.facebook.buck.util.environment.Platform; import com.facebook.buck.util.versioncontrol.HgCmdLineInterface; import com.facebook.eden.thrift.EdenError; import com.facebook.thrift.TException; import com.google.common.collect.ImmutableMap; import java.nio.file.Path; import java.util.Optional; /** * {@link ProjectFilesystemDelegateFactory} mediates the creation of a {@link * ProjectFilesystemDelegate} for a {@link ProjectFilesystem} root. */ public final class ProjectFilesystemDelegateFactory { private static final Logger LOG = Logger.get(ProjectFilesystemDelegateFactory.class); /** Utility class: do not instantiate. */ private ProjectFilesystemDelegateFactory() {} /** Must always create a new delegate for the specified {@code root}. */ public static ProjectFilesystemDelegate newInstance( Path root, String hgCmd, AutoSparseConfig autoSparseConfig) throws InterruptedException { Optional<EdenClient> client = tryToCreateEdenClient(); if (client.isPresent()) { try { EdenMount mount = client.get().getMountFor(root); if (mount != null) { return new EdenProjectFilesystemDelegate(mount); } } catch (TException | EdenError e) { // If Eden is running but root is not a mount point, Eden getMountFor() should just return // null rather than throw an error. LOG.error(e, "Failed to find Eden client for %s.", root); } } if (autoSparseConfig.enabled()) { // We can't access BuckConfig because that class requires a // ProjectFileSystem, which we are in the process of building // Access the required info from the Config instead HgCmdLineInterface hgCmdLine = new HgCmdLineInterface( new PrintStreamProcessExecutorFactory(), root, hgCmd, ImmutableMap.of()); AutoSparseState autoSparseState = AbstractAutoSparseFactory.getAutoSparseState(root, hgCmdLine, autoSparseConfig); if (autoSparseState != null) { LOG.debug("Autosparse enabled, using AutoSparseProjectFilesystemDelegate"); return new AutoSparseProjectFilesystemDelegate(autoSparseState, root); } } // No Eden or Mercurial info available, use the default return new DefaultProjectFilesystemDelegate(root); } /** @return {@link Optional#empty()} if there is no instance of Eden running. */ private static Optional<EdenClient> tryToCreateEdenClient() { if (Platform.detect() != Platform.WINDOWS) { return EdenClient.newInstance(); } else { return Optional.empty(); } } }