/*
* Copyright 2017-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.js;
import com.facebook.buck.io.MorePaths;
import com.facebook.buck.model.Either;
import com.facebook.buck.model.Flavor;
import com.facebook.buck.model.FlavorDomain;
import com.facebook.buck.model.InternalFlavor;
import com.facebook.buck.model.Pair;
import com.facebook.buck.model.UserFlavor;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.hash.Hashing;
import java.nio.file.Path;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JsFlavors {
public static final UserFlavor ANDROID = UserFlavor.of("android", "Build JS for Android");
public static final UserFlavor IOS = UserFlavor.of("ios", "Build JS for iOS");
public static final UserFlavor RELEASE = UserFlavor.of("release", "Optimize for release builds");
public static final UserFlavor RAM_BUNDLE_FILES =
UserFlavor.of("rambundle-files", "Output code as file-based RAM bundle. For Android.");
public static final UserFlavor RAM_BUNDLE_INDEXED =
UserFlavor.of(
"rambundle-indexed",
"Output code as indexed RAM bundle. For iOS. Only use for Android if copied to disk on "
+ "first run");
public static final UserFlavor SOURCE_MAP = UserFlavor.of("source_map", "Expose source map");
public static final FlavorDomain<String> OPTIMIZATION_DOMAIN =
new FlavorDomain<>("Build optimization", ImmutableMap.of(RELEASE, "--release"));
public static final FlavorDomain<String> PLATFORM_DOMAIN =
new FlavorDomain<>(
"Mobile platforms",
ImmutableMap.of(
ANDROID, "--platform android",
IOS, "--platform ios"));
public static final FlavorDomain<String> RAM_BUNDLE_DOMAIN =
new FlavorDomain<>(
"RAM bundle types",
ImmutableMap.of(
RAM_BUNDLE_FILES, "--files-rambundle",
RAM_BUNDLE_INDEXED, "--indexed-rambundle"));
public static final FlavorDomain<Object> SOURCE_MAP_DOMAIN =
new FlavorDomain<>("Source map support", ImmutableMap.of(SOURCE_MAP, SOURCE_MAP));
public static final InternalFlavor ANDROID_RESOURCES = InternalFlavor.of("_res_");
public static final InternalFlavor FORCE_JS_BUNDLE = InternalFlavor.of("_js_");
private static final String fileFlavorPrefix = "file-";
public static boolean validateFlavors(
ImmutableSet<Flavor> flavors, Iterable<FlavorDomain<?>> allowableDomains) {
final ImmutableSet.Builder<Flavor> allowableFlavors = ImmutableSet.builder();
for (FlavorDomain<?> domain : allowableDomains) {
// verify only one flavor of each domain is present
domain.getFlavor(flavors);
allowableFlavors.addAll(domain.getFlavors());
}
return allowableFlavors.build().containsAll(flavors);
}
public static Flavor fileFlavorForSourcePath(final Path path) {
final String hash =
Hashing.sha1()
.hashString(MorePaths.pathWithUnixSeparators(path), Charsets.UTF_8)
.toString()
.substring(0, 10);
final String safeFileName = Flavor.replaceInvalidCharacters(path.getFileName().toString());
return InternalFlavor.of(fileFlavorPrefix + safeFileName + "-" + hash);
}
public static Optional<Either<SourcePath, Pair<SourcePath, String>>> extractSourcePath(
ImmutableBiMap<Flavor, Either<SourcePath, Pair<SourcePath, String>>> flavorsToSources,
Stream<Flavor> flavors) {
return flavors.filter(JsFlavors::isFileFlavor).findFirst().map(flavorsToSources::get);
}
public static boolean isFileFlavor(Flavor flavor) {
return flavor.toString().startsWith(fileFlavorPrefix);
}
private JsFlavors() {}
public static String bundleJobArgs(Set<Flavor> flavors) {
return Stream.of(
PLATFORM_DOMAIN.getValue(flavors),
RAM_BUNDLE_DOMAIN.getValue(flavors),
OPTIMIZATION_DOMAIN.getValue(flavors))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.joining(" "));
}
public static String platformArgForRelease(Set<Flavor> flavors) {
return PLATFORM_DOMAIN
.getValue(flavors)
.orElseThrow(
() ->
new HumanReadableException("A platform flavor must be passed for release builds"));
}
}