Search in sources :

Example 56 with Cell

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);
            }
        }
    }
}
Also used : Path(java.nio.file.Path) BuckPaths(com.facebook.buck.io.BuckPaths) BuckConfig(com.facebook.buck.cli.BuckConfig) ProjectFilesystem(com.facebook.buck.io.ProjectFilesystem) Cell(com.facebook.buck.rules.Cell) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) LinkedHashMap(java.util.LinkedHashMap)

Example 57 with Cell

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());
    }
}
Also used : TargetGroupDescription(com.facebook.buck.groups.TargetGroupDescription) UnflavoredBuildTarget(com.facebook.buck.model.UnflavoredBuildTarget) VisibilityPattern(com.facebook.buck.rules.VisibilityPattern) ParamInfoException(com.facebook.buck.rules.ParamInfoException) Hasher(com.google.common.hash.Hasher) ImmutableSet(com.google.common.collect.ImmutableSet) UnflavoredBuildTarget(com.facebook.buck.model.UnflavoredBuildTarget) BuildTarget(com.facebook.buck.model.BuildTarget) HumanReadableException(com.facebook.buck.util.HumanReadableException) TargetGroup(com.facebook.buck.rules.TargetGroup) BuildRuleType(com.facebook.buck.rules.BuildRuleType) SimplePerfEvent(com.facebook.buck.event.SimplePerfEvent) Cell(com.facebook.buck.rules.Cell)

Example 58 with Cell

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();
}
Also used : TargetNode(com.facebook.buck.rules.TargetNode) ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) BuildFileParseException(com.facebook.buck.json.BuildFileParseException) AbstractMap(java.util.AbstractMap) Function(com.google.common.base.Function) ImmutableSet(com.google.common.collect.ImmutableSet) BuildTarget(com.facebook.buck.model.BuildTarget) SimplePerfEvent(com.facebook.buck.event.SimplePerfEvent) ExecutionException(java.util.concurrent.ExecutionException) Cell(com.facebook.buck.rules.Cell) Path(java.nio.file.Path) BuildTargetException(com.facebook.buck.model.BuildTargetException) IOException(java.io.IOException) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) AbstractMap(java.util.AbstractMap) TreeMap(java.util.TreeMap)

Example 59 with Cell

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;
}
Also used : TreeMap(java.util.TreeMap) Cell(com.facebook.buck.rules.Cell) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) AbstractMap(java.util.AbstractMap) TreeMap(java.util.TreeMap) Nullable(javax.annotation.Nullable)

Example 60 with Cell

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);
    }
}
Also used : Path(java.nio.file.Path) HumanReadableException(com.facebook.buck.util.HumanReadableException) ImmutableList(com.google.common.collect.ImmutableList) Cell(com.facebook.buck.rules.Cell)

Aggregations

Cell (com.facebook.buck.rules.Cell)87 Test (org.junit.Test)57 Path (java.nio.file.Path)46 TestCellBuilder (com.facebook.buck.rules.TestCellBuilder)41 BuildTarget (com.facebook.buck.model.BuildTarget)25 BuckConfig (com.facebook.buck.cli.BuckConfig)24 FakeBuckConfig (com.facebook.buck.cli.FakeBuckConfig)22 ProjectFilesystem (com.facebook.buck.io.ProjectFilesystem)21 PathSourcePath (com.facebook.buck.rules.PathSourcePath)15 FakeProjectFilesystem (com.facebook.buck.testutil.FakeProjectFilesystem)14 ImmutableSet (com.google.common.collect.ImmutableSet)14 BuckEventBus (com.facebook.buck.event.BuckEventBus)12 ImmutableMap (com.google.common.collect.ImmutableMap)12 BroadcastEventListener (com.facebook.buck.event.listener.BroadcastEventListener)11 ParserConfig (com.facebook.buck.parser.ParserConfig)11 IOException (java.io.IOException)11 Map (java.util.Map)11 TargetNode (com.facebook.buck.rules.TargetNode)10 ProjectWorkspace (com.facebook.buck.testutil.integration.ProjectWorkspace)10 ImmutableList (com.google.common.collect.ImmutableList)10