/*
* 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.haskell;
import com.facebook.buck.cli.BuckConfig;
import com.facebook.buck.io.ExecutableFinder;
import com.facebook.buck.rules.ConstantToolProvider;
import com.facebook.buck.rules.HashedFileTool;
import com.facebook.buck.rules.ToolProvider;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
public class HaskellBuckConfig implements HaskellConfig {
private static final String SECTION = "haskell";
private final BuckConfig delegate;
private final ExecutableFinder finder;
public HaskellBuckConfig(BuckConfig delegate, ExecutableFinder finder) {
this.delegate = delegate;
this.finder = finder;
}
private Optional<ImmutableList<String>> getFlags(String field) {
Optional<String> value = delegate.getValue(SECTION, field);
if (!value.isPresent()) {
return Optional.empty();
}
ImmutableList.Builder<String> split = ImmutableList.builder();
if (!value.get().trim().isEmpty()) {
split.addAll(Splitter.on(" ").split(value.get().trim()));
}
return Optional.of(split.build());
}
@VisibleForTesting
protected Optional<Path> getSystemCompiler() {
return finder.getOptionalExecutable(Paths.get("ghc"), delegate.getEnvironment());
}
@Override
public ToolProvider getCompiler() {
Optional<ToolProvider> configuredCompiler = delegate.getToolProvider(SECTION, "compiler");
if (configuredCompiler.isPresent()) {
return configuredCompiler.get();
}
Optional<Path> systemCompiler = getSystemCompiler();
if (systemCompiler.isPresent()) {
return new ConstantToolProvider(new HashedFileTool(systemCompiler.get()));
}
throw new HumanReadableException(
"No Haskell compiler found in .buckconfig (%s.compiler) or on system", SECTION);
}
private static final Integer DEFAULT_MAJOR_VERSION = 7;
@Override
public HaskellVersion getHaskellVersion() {
Optional<Integer> majorVersion = delegate.getInteger(SECTION, "compiler_major_version");
return HaskellVersion.of(majorVersion.orElse(DEFAULT_MAJOR_VERSION));
}
@Override
public ImmutableList<String> getCompilerFlags() {
return getFlags("compiler_flags").orElse(ImmutableList.of());
}
@Override
public ToolProvider getLinker() {
Optional<ToolProvider> configuredLinker = delegate.getToolProvider(SECTION, "linker");
if (configuredLinker.isPresent()) {
return configuredLinker.get();
}
Optional<Path> systemLinker = getSystemCompiler();
if (systemLinker.isPresent()) {
return new ConstantToolProvider(new HashedFileTool(systemLinker.get()));
}
throw new HumanReadableException(
"No Haskell linker found in .buckconfig (%s.linker) or on system", SECTION);
}
@Override
public ImmutableList<String> getLinkerFlags() {
return getFlags("linker_flags").orElse(ImmutableList.of());
}
@VisibleForTesting
protected Optional<Path> getSystemPackager() {
return finder.getOptionalExecutable(Paths.get("ghc-pkg"), delegate.getEnvironment());
}
@Override
public ToolProvider getPackager() {
Optional<ToolProvider> configuredPackager = delegate.getToolProvider(SECTION, "packager");
if (configuredPackager.isPresent()) {
return configuredPackager.get();
}
Optional<Path> systemPackager = getSystemPackager();
if (systemPackager.isPresent()) {
return new ConstantToolProvider(new HashedFileTool(systemPackager.get()));
}
throw new HumanReadableException(
"No Haskell packager found in .buckconfig (%s.compiler) or on system", SECTION);
}
@Override
public boolean shouldCacheLinks() {
return delegate.getBooleanValue(SECTION, "cache_links", true);
}
@Override
public Optional<Boolean> shouldUsedOldBinaryOutputLocation() {
return delegate.getBoolean(SECTION, "old_binary_output_location");
}
}