use of com.facebook.buck.rules.Cell in project buck by facebook.
the class Build method createConfiguredBuckOutSymlinks.
/**
* When the user overrides the configured buck-out directory via the `.buckconfig` and also sets
* the `project.buck_out_compat_link` setting to `true`, we symlink the original output path
* (`buck-out/`) to this newly configured location for backwards compatibility.
*/
private void createConfiguredBuckOutSymlinks() throws IOException {
for (Cell cell : getAllCells()) {
BuckConfig buckConfig = cell.getBuckConfig();
ProjectFilesystem filesystem = cell.getFilesystem();
BuckPaths configuredPaths = filesystem.getBuckPaths();
if (!configuredPaths.getConfiguredBuckOut().equals(configuredPaths.getBuckOut()) && buckConfig.getBuckOutCompatLink() && Platform.detect() != Platform.WINDOWS) {
BuckPaths unconfiguredPaths = configuredPaths.withConfiguredBuckOut(configuredPaths.getBuckOut());
ImmutableMap<Path, Path> paths = ImmutableMap.of(unconfiguredPaths.getGenDir(), configuredPaths.getGenDir(), unconfiguredPaths.getScratchDir(), configuredPaths.getScratchDir());
for (Map.Entry<Path, Path> entry : paths.entrySet()) {
filesystem.deleteRecursivelyIfExists(entry.getKey());
filesystem.createSymLink(entry.getKey(), entry.getKey().getParent().relativize(entry.getValue()), /* force */
false);
}
}
}
}
use of com.facebook.buck.rules.Cell in project buck by facebook.
the class DefaultParserTargetGroupFactory method createTargetNode.
@Override
public TargetGroup createTargetNode(Cell cell, Path buildFile, BuildTarget target, Map<String, Object> rawNode, Function<PerfEventId, SimplePerfEvent.Scope> perfEventScope) {
Preconditions.checkArgument(!target.isFlavored());
UnflavoredBuildTarget unflavoredBuildTarget = target.withoutCell().getUnflavoredBuildTarget();
UnflavoredBuildTarget unflavoredBuildTargetFromRawData = RawNodeParsePipeline.parseBuildTargetFromRawRule(cell.getRoot(), rawNode, buildFile);
if (!unflavoredBuildTarget.equals(unflavoredBuildTargetFromRawData)) {
throw new IllegalStateException(String.format("Inconsistent internal state, target from data: %s, expected: %s, raw data: %s", unflavoredBuildTargetFromRawData, unflavoredBuildTarget, Joiner.on(',').withKeyValueSeparator("->").join(rawNode)));
}
BuildRuleType buildRuleType = parseBuildRuleTypeFromRawRule(cell, rawNode);
// Because of the way that the parser works, we know this can never return null.
Description<?> description = cell.getDescription(buildRuleType);
Cell targetCell = cell.getCell(target);
TargetGroupDescription.Arg constructorArg = (TargetGroupDescription.Arg) description.createUnpopulatedConstructorArg();
try {
ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder();
ImmutableSet.Builder<VisibilityPattern> visibilityPatterns = ImmutableSet.builder();
try (SimplePerfEvent.Scope scope = perfEventScope.apply(PerfEventId.of("MarshalledConstructorArg"))) {
marshaller.populate(targetCell.getCellPathResolver(), targetCell.getFilesystem(), target, constructorArg, declaredDeps, visibilityPatterns, rawNode);
}
try (SimplePerfEvent.Scope scope = perfEventScope.apply(PerfEventId.of("CreatedTargetNode"))) {
Hasher hasher = Hashing.sha1().newHasher();
hasher.putString(BuckVersion.getVersion(), UTF_8);
JsonObjectHashing.hashJsonObject(hasher, rawNode);
TargetGroup node = new TargetGroup(constructorArg.targets, constructorArg.restrictOutboundVisibility, target);
return node;
}
} catch (ParamInfoException e) {
throw new HumanReadableException("%s: %s", target, e.getMessage());
}
}
use of com.facebook.buck.rules.Cell in project buck by facebook.
the class Parser method resolveTargetSpecs.
private ImmutableList<ImmutableSet<BuildTarget>> resolveTargetSpecs(PerBuildState state, BuckEventBus eventBus, Cell rootCell, Iterable<? extends TargetNodeSpec> specs, final ParserConfig.ApplyDefaultFlavorsMode applyDefaultFlavorsMode) throws BuildFileParseException, BuildTargetException, InterruptedException, IOException {
ParserConfig parserConfig = rootCell.getBuckConfig().getView(ParserConfig.class);
ParserConfig.BuildFileSearchMethod buildFileSearchMethod;
if (parserConfig.getBuildFileSearchMethod().isPresent()) {
buildFileSearchMethod = parserConfig.getBuildFileSearchMethod().get();
} else if (parserConfig.getAllowSymlinks() == ParserConfig.AllowSymlinks.FORBID) {
// If unspecified, only use Watchman in repositories which enforce a "no symlinks" rule
// (Watchman doesn't follow symlinks).
buildFileSearchMethod = ParserConfig.BuildFileSearchMethod.WATCHMAN;
} else {
buildFileSearchMethod = ParserConfig.BuildFileSearchMethod.FILESYSTEM_CRAWL;
}
// Convert the input spec iterable into a list so we have a fixed ordering, which we'll rely on
// when returning results.
final ImmutableList<TargetNodeSpec> orderedSpecs = ImmutableList.copyOf(specs);
// Resolve all the build files from all the target specs. We store these into a multi-map which
// maps the path to the build file to the index of it's spec file in the ordered spec list.
Multimap<Path, Integer> perBuildFileSpecs = LinkedHashMultimap.create();
for (int index = 0; index < orderedSpecs.size(); index++) {
TargetNodeSpec spec = orderedSpecs.get(index);
Cell cell = rootCell.getCell(spec.getBuildFileSpec().getCellPath());
ImmutableSet<Path> buildFiles;
try (SimplePerfEvent.Scope perfEventScope = SimplePerfEvent.scope(eventBus, PerfEventId.of("FindBuildFiles"), "targetNodeSpec", spec)) {
// Iterate over the build files the given target node spec returns.
buildFiles = spec.getBuildFileSpec().findBuildFiles(cell, buildFileSearchMethod);
}
for (Path buildFile : buildFiles) {
perBuildFileSpecs.put(buildFile, index);
}
}
// Kick off parse futures for each build file.
ArrayList<ListenableFuture<ImmutableList<Map.Entry<Integer, ImmutableSet<BuildTarget>>>>> targetFutures = new ArrayList<>();
for (Path buildFile : perBuildFileSpecs.keySet()) {
final Collection<Integer> buildFileSpecs = perBuildFileSpecs.get(buildFile);
TargetNodeSpec firstSpec = orderedSpecs.get(Iterables.get(buildFileSpecs, 0));
Cell cell = rootCell.getCell(firstSpec.getBuildFileSpec().getCellPath());
// Format a proper error message for non-existent build files.
if (!cell.getFilesystem().isFile(buildFile)) {
throw new MissingBuildFileException(firstSpec, cell.getFilesystem().getRootPath().relativize(buildFile));
}
// Build up a list of all target nodes from the build file.
targetFutures.add(Futures.transform(state.getAllTargetNodesJob(cell, buildFile), new Function<ImmutableSet<TargetNode<?, ?>>, ImmutableList<Map.Entry<Integer, ImmutableSet<BuildTarget>>>>() {
@Override
public ImmutableList<Map.Entry<Integer, ImmutableSet<BuildTarget>>> apply(ImmutableSet<TargetNode<?, ?>> nodes) {
ImmutableList.Builder<Map.Entry<Integer, ImmutableSet<BuildTarget>>> targets = ImmutableList.builder();
for (int index : buildFileSpecs) {
// Call back into the target node spec to filter the relevant build targets.
// We return a pair of spec index and build target set, so that we can build a
// final result list that maintains the input spec ordering.
targets.add(new AbstractMap.SimpleEntry<>(index, applySpecFilter(orderedSpecs.get(index), nodes, applyDefaultFlavorsMode)));
}
return targets.build();
}
}));
}
// Now walk through and resolve all the futures, and place their results in a multimap that
// is indexed by the integer representing the input target spec order.
LinkedHashMultimap<Integer, BuildTarget> targetsMap = LinkedHashMultimap.create();
try {
for (ListenableFuture<ImmutableList<Map.Entry<Integer, ImmutableSet<BuildTarget>>>> targetFuture : targetFutures) {
ImmutableList<Map.Entry<Integer, ImmutableSet<BuildTarget>>> results = targetFuture.get();
for (Map.Entry<Integer, ImmutableSet<BuildTarget>> ent : results) {
targetsMap.putAll(ent.getKey(), ent.getValue());
}
}
} catch (ExecutionException e) {
Throwables.throwIfInstanceOf(e.getCause(), BuildFileParseException.class);
Throwables.throwIfInstanceOf(e.getCause(), BuildTargetException.class);
Throwables.throwIfInstanceOf(e.getCause(), IOException.class);
Throwables.throwIfUnchecked(e.getCause());
throw new RuntimeException(e.getCause());
}
// Finally, pull out the final build target results in input target spec order, and place them
// into a list of sets that exactly matches the ihput order.
ImmutableList.Builder<ImmutableSet<BuildTarget>> targets = ImmutableList.builder();
for (int index = 0; index < orderedSpecs.size(); index++) {
targets.add(ImmutableSet.copyOf(targetsMap.get(index)));
}
return targets.build();
}
use of com.facebook.buck.rules.Cell in project buck by facebook.
the class Parser method getRawTargetNode.
@Nullable
public SortedMap<String, Object> getRawTargetNode(PerBuildState state, Cell cell, TargetNode<?, ?> targetNode) throws BuildFileParseException {
try {
Cell owningCell = cell.getCell(targetNode.getBuildTarget());
ImmutableSet<Map<String, Object>> allRawNodes = getRawTargetNodes(state, owningCell, cell.getAbsolutePathToBuildFile(targetNode.getBuildTarget()));
String shortName = targetNode.getBuildTarget().getShortName();
for (Map<String, Object> rawNode : allRawNodes) {
if (shortName.equals(rawNode.get("name"))) {
SortedMap<String, Object> toReturn = new TreeMap<>();
toReturn.putAll(rawNode);
toReturn.put("buck.direct_dependencies", targetNode.getDeps().stream().map(Object::toString).collect(MoreCollectors.toImmutableList()));
return toReturn;
}
}
} catch (Cell.MissingBuildFileException e) {
throw new RuntimeException("Deeply unlikely to be true: the cell is missing: " + targetNode);
}
return null;
}
use of com.facebook.buck.rules.Cell in project buck by facebook.
the class PerBuildState method registerInputsUnderSymlinks.
private void registerInputsUnderSymlinks(Path buildFile, TargetNode<?, ?> node) throws IOException {
Map<Path, Path> newSymlinksEncountered = inputFilesUnderSymlink(node.getInputs(), node.getFilesystem(), symlinkExistenceCache);
if (!newSymlinksEncountered.isEmpty()) {
ParserConfig.AllowSymlinks allowSymlinks = Preconditions.checkNotNull(cellSymlinkAllowability.get(node.getBuildTarget().getCellPath()));
if (allowSymlinks == ParserConfig.AllowSymlinks.FORBID) {
throw new HumanReadableException("Target %s contains input files under a path which contains a symbolic link " + "(%s). To resolve this, use separate rules and declare dependencies instead of " + "using symbolic links.", node.getBuildTarget(), newSymlinksEncountered);
}
Optional<ImmutableList<Path>> readOnlyPaths = getCell(node.getBuildTarget()).getBuckConfig().getView(ParserConfig.class).getReadOnlyPaths();
Cell currentCell = cells.get(node.getBuildTarget().getCellPath());
if (readOnlyPaths.isPresent() && currentCell != null) {
Path cellRootPath = currentCell.getFilesystem().getRootPath();
for (Path readOnlyPath : readOnlyPaths.get()) {
if (buildFile.startsWith(cellRootPath.resolve(readOnlyPath))) {
LOG.debug("Target %s is under a symlink (%s). It will be cached because it belongs " + "under %s, a read-only path white listed in .buckconfing. under [project]" + " read_only_paths", node.getBuildTarget(), newSymlinksEncountered, readOnlyPath);
return;
}
}
}
// If we're not explicitly forbidding symlinks, either warn to the console or the log file
// depending on the config setting.
String msg = String.format("Disabling parser cache for target %s, because one or more input files are under a " + "symbolic link (%s). This will severely impact the time spent in parsing! To " + "resolve this, use separate rules and declare dependencies instead of using " + "symbolic links.", node.getBuildTarget(), newSymlinksEncountered);
if (allowSymlinks == ParserConfig.AllowSymlinks.WARN) {
eventBus.post(ConsoleEvent.warning(msg));
} else {
LOG.warn(msg);
}
eventBus.post(ParsingEvent.symlinkInvalidation(buildFile.toString()));
buildInputPathsUnderSymlink.add(buildFile);
}
}
Aggregations