com.facebook.buck.config.Configs.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.config.Configs.java

Source

/*
 * Copyright 2015-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.config;

import com.facebook.buck.log.Logger;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Utility functions for working with {@link Config}s.
 */
public final class Configs {
    private static final Logger LOG = Logger.get(Configs.class);

    private static final String DEFAULT_BUCK_CONFIG_FILE_NAME = ".buckconfig";
    private static final String DEFAULT_BUCK_CONFIG_OVERRIDE_FILE_NAME = ".buckconfig.local";
    private static final String DEFAULT_BUCK_CONFIG_DIRECTORY_NAME = ".buckconfig.d";

    private static final Path GLOBAL_BUCK_CONFIG_FILE_PATH = Paths.get("/etc/buckconfig");
    private static final Path GLOBAL_BUCK_CONFIG_DIRECTORY_PATH = Paths.get("/etc/buckconfig.d");

    private Configs() {
    }

    /**
     * Convienence constructor
     */
    public static Config createDefaultConfig(Path root) throws IOException {
        return createDefaultConfig(root, RawConfig.of(ImmutableMap.of()));
    }

    /**
     * Generates a Buck config by merging configs from specified locations on disk.
     *
     * In order:
     *
     * <ol>
     *   <li>{@code /etc/buckconfig}</li>
     *   <li>Files (in lexicographical order) in {@code /etc/buckconfig.d}</li>
     *   <li>{@code <HOME>/.buckconfig}</li>
     *   <li>Files (in lexicographical order) in {@code <HOME>/buckconfig.d}</li>
     *   <li>{@code <PROJECT ROOT>/.buckconfig}</li>
     *   <li>{@code <PROJECT ROOT>/.buckconfig.local}</li>
     *   <li>Any overrides (usually from the command line)</li>
     * </ol>
     *
     * @param root Project root.
     * @param configOverrides Config overrides to merge in after the other sources.
     * @return the resulting {@code Config}.
     * @throws IOException on any exceptions during the underlying filesystem operations.
     */
    public static Config createDefaultConfig(Path root, RawConfig configOverrides) throws IOException {
        LOG.debug("Loading configuration for %s", root);
        ImmutableList.Builder<Path> configFileBuilder = ImmutableList.builder();

        configFileBuilder.addAll(listFiles(GLOBAL_BUCK_CONFIG_DIRECTORY_PATH));
        if (Files.isRegularFile(GLOBAL_BUCK_CONFIG_FILE_PATH)) {
            configFileBuilder.add(GLOBAL_BUCK_CONFIG_FILE_PATH);
        }

        Path homeDirectory = Paths.get(System.getProperty("user.home"));
        Path userConfigDir = homeDirectory.resolve(DEFAULT_BUCK_CONFIG_DIRECTORY_NAME);
        configFileBuilder.addAll(listFiles(userConfigDir));
        Path userConfigFile = homeDirectory.resolve(DEFAULT_BUCK_CONFIG_FILE_NAME);
        if (Files.isRegularFile(userConfigFile)) {
            configFileBuilder.add(userConfigFile);
        }

        Path configFile = root.resolve(DEFAULT_BUCK_CONFIG_FILE_NAME);
        if (Files.isRegularFile(configFile)) {
            configFileBuilder.add(configFile);
        }
        Path overrideConfigFile = root.resolve(DEFAULT_BUCK_CONFIG_OVERRIDE_FILE_NAME);
        if (Files.isRegularFile(overrideConfigFile)) {
            configFileBuilder.add(overrideConfigFile);
        }

        ImmutableList<Path> configFiles = configFileBuilder.build();

        RawConfig.Builder builder = RawConfig.builder();
        for (Path file : configFiles) {
            try (Reader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
                ImmutableMap<String, ImmutableMap<String, String>> parsedConfiguration = Inis.read(reader);
                LOG.debug("Loaded a configuration file %s: %s", file, parsedConfiguration);
                builder.putAll(parsedConfiguration);
            }
        }
        LOG.debug("Adding configuration overrides %s", configOverrides);
        builder.putAll(configOverrides);
        return new Config(builder.build());
    }

    private static ImmutableSortedSet<Path> listFiles(Path root) throws IOException {
        if (!Files.isDirectory(root)) {
            return ImmutableSortedSet.of();
        }
        try (DirectoryStream<Path> directory = Files.newDirectoryStream(root)) {
            return ImmutableSortedSet.<Path>naturalOrder().addAll(directory.iterator()).build();
        }
    }

}