@Override public void registerFlavors( Arg arg, BuildRule buildRule, ProjectFilesystem projectFilesystem, RuleKeyBuilderFactory ruleKeyBuilderFactory, BuildRuleResolver ruleResolver) { BuildTarget prebuiltJarBuildTarget = buildRule.getBuildTarget(); BuildTarget flavoredBuildTarget = BuildTargets.createFlavoredBuildTarget( prebuiltJarBuildTarget, JavaLibrary.GWT_MODULE_FLAVOR); BuildRuleParams params = new BuildRuleParams( flavoredBuildTarget, /* declaredDeps */ ImmutableSortedSet.of(buildRule), /* inferredDeps */ ImmutableSortedSet.<BuildRule>of(), BuildTargetPattern.PUBLIC, projectFilesystem, ruleKeyBuilderFactory, BuildRuleType.GWT_MODULE); BuildRule gwtModule = createGwtModule(params, arg); ruleResolver.addToIndex(gwtModule.getBuildTarget(), gwtModule); }
/** * @param rules the raw rule objects to parse. */ @VisibleForTesting synchronized void parseRawRulesInternal(Iterable<Map<String, Object>> rules) throws BuildTargetException, IOException { for (Map<String, Object> map : rules) { if (isMetaRule(map)) { parseMetaRule(map); continue; } BuildTarget target = parseBuildTargetFromRawRule(map); BuildRuleType buildRuleType = parseBuildRuleTypeFromRawRule(map); Description<?> description = repository.getDescription(buildRuleType); if (description == null) { throw new HumanReadableException("Unrecognized rule %s while parsing %s.", buildRuleType, repository.getAbsolutePathToBuildFile(target)); } state.put(target, map); } }
public static ImmutableSet<BuildRule> getSchemeBuildableRules(BuildRule primaryRule) { final Iterable<BuildRule> buildRulesIterable = Iterables.concat( getRecursiveRuleDependenciesOfTypes( RecursiveRuleDependenciesMode.BUILDING, primaryRule, Optional.<ImmutableSet<BuildRuleType>>absent()), ImmutableSet.of(primaryRule)); return ImmutableSet.copyOf( Iterables.filter( buildRulesIterable, new Predicate<BuildRule>() { @Override public boolean apply(@Nullable BuildRule input) { if (!isXcodeTargetBuildRuleType(input.getType()) && XcodeNativeDescription.TYPE != input.getType()) { return false; } return true; } })); }
/** * Collect resources from recursive dependencies. * * @param rule Build rule at the tip of the traversal. * @return The recursive resource buildables. */ private Iterable<AppleResource> collectRecursiveResources( BuildRule rule, BuildRuleType resourceRuleType) { Iterable<BuildRule> resourceRules = AppleBuildRules.getRecursiveRuleDependenciesOfType( AppleBuildRules.RecursiveRuleDependenciesMode.COPYING, rule, resourceRuleType); ImmutableSet.Builder<AppleResource> resources = ImmutableSet.builder(); for (BuildRule resourceRule : resourceRules) { AppleResource resource = (AppleResource) Preconditions.checkNotNull(resourceRule); resources.add(resource); } return resources.build(); }
/** * @param referencedPaths All of these paths must be relative to the project root. */ public TargetsCommandPredicate( PartialGraph partialGraph, ImmutableSet<BuildRuleType> buildRuleTypes, ImmutableSet<String> referencedPaths, ImmutableSet<BuildTarget> matchingBuildRules) { this.graph = partialGraph.getActionGraph(); this.buildRuleTypes = Preconditions.checkNotNull(buildRuleTypes); this.matchingBuildRules = Preconditions.checkNotNull(matchingBuildRules); Preconditions.checkNotNull(referencedPaths); if (!referencedPaths.isEmpty()) { this.referencedInputs = MorePaths.asPaths(referencedPaths); BuildFileTree tree = new InMemoryBuildFileTree(partialGraph.getTargets()); basePathOfTargets = Sets.newHashSet(); dependentTargets = Sets.newHashSet(); for (Path input : referencedInputs) { basePathOfTargets.add(tree.getBasePathOfAncestorTarget(input)); } } else { basePathOfTargets = ImmutableSet.of(); dependentTargets = ImmutableSet.of(); } }
@Test public void testIncludingATestOnTheCommandLineMeansYouWouldLikeItRun() throws CmdLineException { String excludedLabel = "exclude_me"; BuckConfig config = new FakeBuckConfig( ImmutableMap.<String, Map<String, String>>of( "test", ImmutableMap.of("excluded_labels", excludedLabel))); assertThat(config.getDefaultRawExcludedLabelSelectors(), contains(excludedLabel)); TestCommandOptions options = new TestCommandOptions(config); new CmdLineParserAdditionalOptions(options).parseArgument("//example:test"); FakeTestRule rule = new FakeTestRule( new BuildRuleType("java_test"), /* labels */ ImmutableSet.of(new Label(excludedLabel)), BuildTargetFactory.newInstance("//example:test"), /* deps */ ImmutableSortedSet.<BuildRule>of(), /* visibility */ ImmutableSet.<BuildTargetPattern>of()); Iterable<TestRule> filtered = TestCommand.filterTestRules(options, ImmutableSet.<TestRule>of(rule)); assertEquals(rule, Iterables.getOnlyElement(filtered)); }
public ImmutableSortedSet<Flavor> addImplicitFlavorsForRuleTypes( ImmutableSortedSet<Flavor> argDefaultFlavors, BuildRuleType... types) { Optional<Flavor> platformFlavor = getCxxPlatformsProvider().getCxxPlatforms().getFlavor(argDefaultFlavors); for (BuildRuleType type : types) { ImmutableMap<String, Flavor> libraryDefaults = cxxBuckConfig.getDefaultFlavorsForRuleType(type); if (!platformFlavor.isPresent()) { platformFlavor = Optional.ofNullable(libraryDefaults.get(CxxBuckConfig.DEFAULT_FLAVOR_PLATFORM)); } } if (platformFlavor.isPresent()) { return ImmutableSortedSet.of(platformFlavor.get()); } else { // To avoid changing the output path of binaries built without a flavor, // we'll default to no flavor, which implicitly builds the default platform. return ImmutableSortedSet.of(); } }
@SuppressWarnings("unchecked") private Optional<ImmutableSet<Class<? extends Description<?>>>> getDescriptionClassFromParams( CommandRunnerParams params) { ImmutableSet<String> types = getTypes(); ImmutableSet.Builder<Class<? extends Description<?>>> descriptionClassesBuilder = ImmutableSet.builder(); for (String name : types) { try { KnownBuildRuleTypes knownBuildRuleTypes = params.getKnownBuildRuleTypesProvider().get(params.getCell()); BuildRuleType type = knownBuildRuleTypes.getBuildRuleType(name); Description<?> description = knownBuildRuleTypes.getDescription(type); descriptionClassesBuilder.add((Class<? extends Description<?>>) description.getClass()); } catch (IllegalArgumentException e) { params.getBuckEventBus().post(ConsoleEvent.severe("Invalid build rule type: " + name)); return Optional.empty(); } } return Optional.of(descriptionClassesBuilder.build()); }
/** * Creates a {@link BuildRule} with the {@link JavaLibrary#GWT_MODULE_FLAVOR}, if appropriate. * <p> * If {@code arg.srcs} or {@code arg.resources} is non-empty, then the return value will not be * absent. */ @VisibleForTesting static Optional<GwtModule> tryCreateGwtModule( BuildTarget originalBuildTarget, ProjectFilesystem projectFilesystem, RuleKeyBuilderFactory ruleKeyBuilderFactory, Arg arg) { if (arg.srcs.get().isEmpty() && arg.resources.get().isEmpty() && Flavor.DEFAULT.equals(originalBuildTarget.getFlavor())) { return Optional.absent(); } BuildTarget gwtModuleBuildTarget = BuildTargets.createFlavoredBuildTarget( originalBuildTarget.getUnflavoredTarget(), JavaLibrary.GWT_MODULE_FLAVOR); ImmutableSortedSet<SourcePath> filesForGwtModule = ImmutableSortedSet .<SourcePath>naturalOrder() .addAll(arg.srcs.get()) .addAll(arg.resources.get()) .build(); // If any of the srcs or resources are BuildRuleSourcePaths, then their respective BuildRules // must be included as deps. ImmutableSortedSet<BuildRule> deps = ImmutableSortedSet.copyOf(SourcePaths.filterBuildRuleInputs(filesForGwtModule)); GwtModule gwtModule = new GwtModule( new BuildRuleParams( gwtModuleBuildTarget, deps, /* inferredDeps */ ImmutableSortedSet.<BuildRule>of(), BuildTargetPattern.PUBLIC, projectFilesystem, ruleKeyBuilderFactory, BuildRuleType.GWT_MODULE), filesForGwtModule); return Optional.of(gwtModule); }
public static RuleJsonPredicate matchBuildRuleType(final BuildRuleType type) { return new RuleJsonPredicate() { @Override public boolean isMatch( Map<String, Object> rawParseData, BuildRuleType buildRuleType, BuildTarget buildTarget) { return buildRuleType == type; } }; }
public static RuleJsonPredicate isTestRule() { return new RuleJsonPredicate() { @Override public boolean isMatch( Map<String, Object> rawParseData, BuildRuleType buildRuleType, BuildTarget buildTarget) { return buildRuleType.isTestRule(); } }; }
public ImmutableSet<BuildTarget> filterTargets(RuleJsonPredicate filter) { ImmutableSet.Builder<BuildTarget> matchingTargets = ImmutableSet.builder(); for (Map<String, Object> map : parsedBuildFiles.values()) { BuildRuleType buildRuleType = parseBuildRuleTypeFromRawRule(map); BuildTarget target = parseBuildTargetFromRawRule(map); if (filter.isMatch(map, buildRuleType, target)) { matchingTargets.add(target); } } return matchingTargets.build(); }
private void addRunScriptBuildPhasesForDependenciesWithType( BuildRule rule, PBXNativeTarget target, BuildRuleType type) { for (BuildRule dependency : rule.getDeps()) { if (dependency.getType().equals(type)) { Genrule genrule = (Genrule) dependency; addRunScriptBuildPhase(target, genrule.getSrcs(), genrule.createGenruleStep()); } } }
private Iterable<BuildRule> getRuleDependenciesOfType( final Iterable<BuildRule> rules, BuildRuleType... types) { final ImmutableSet<BuildRuleType> requestedTypes = ImmutableSet.copyOf(types); return Iterables.filter( rules, new Predicate<BuildRule>() { @Override public boolean apply(BuildRule input) { return requestedTypes.contains(input.getType()); } }); }
/** * Returns transitive android resource deps which are _not_ sorted topologically, only to be used * when the order of the resource rules does not matter, for instance, when graph enhancing * UberRDotJava, DummyRDotJava, AaptPackageResources where we only need the deps to correctly * order the execution of those buildables. */ public static UnsortedAndroidResourceDeps createFrom( Collection<BuildRule> rules, final Optional<Callback> callback) { final ImmutableSet.Builder<HasAndroidResourceDeps> androidResources = ImmutableSet.builder(); // This visitor finds all AndroidResourceRules that are reachable from the specified rules via // rules with types in the TRAVERSABLE_TYPES collection. AbstractDependencyVisitor visitor = new AbstractDependencyVisitor(rules) { @Override public ImmutableSet<BuildRule> visit(BuildRule rule) { HasAndroidResourceDeps androidResourceRule = null; if (rule instanceof HasAndroidResourceDeps) { androidResourceRule = (HasAndroidResourceDeps) rule; } if (androidResourceRule != null && androidResourceRule.getRes() != null) { androidResources.add(androidResourceRule); } // Only certain types of rules should be considered as part of this traversal. BuildRuleType type = rule.getType(); ImmutableSet<BuildRule> depsToVisit = maybeVisitAllDeps(rule, TRAVERSABLE_TYPES.contains(type)); if (callback.isPresent()) { callback.get().onRuleVisited(rule, depsToVisit); } return depsToVisit; } }; visitor.start(); return new UnsortedAndroidResourceDeps(androidResources.build()); }
public Optional<DummyRDotJava> createBuildableForAndroidResources( BuildRuleResolver ruleResolver, boolean createBuildableIfEmptyDeps) { ImmutableSortedSet<BuildRule> originalDeps = originalBuildRuleParams.getDeps(); ImmutableSet<HasAndroidResourceDeps> androidResourceDeps = UnsortedAndroidResourceDeps.createFrom(originalDeps, Optional.<Callback>absent()) .getResourceDeps(); if (androidResourceDeps.isEmpty() && !createBuildableIfEmptyDeps) { return Optional.absent(); } // The androidResourceDeps may contain Buildables, but we need the actual BuildRules. Since this // is going to be used to modify the build graph, we can't just wrap the buildables. Fortunately // we know that the buildables come from the originalDeps. ImmutableSortedSet.Builder<BuildRule> actualDeps = ImmutableSortedSet.naturalOrder(); for (HasAndroidResourceDeps dep : androidResourceDeps) { // If this ever returns null, something has gone horrifically awry. actualDeps.add(ruleResolver.get(dep.getBuildTarget())); } BuildRuleParams dummyRDotJavaParams = originalBuildRuleParams.copyWithChanges( BuildRuleType.DUMMY_R_DOT_JAVA, dummyRDotJavaBuildTarget, actualDeps.build(), /* extraDeps */ ImmutableSortedSet.<BuildRule>of()); DummyRDotJava dummyRDotJava = new DummyRDotJava( dummyRDotJavaParams, androidResourceDeps, javacOptions); ruleResolver.addToIndex(dummyRDotJavaBuildTarget, dummyRDotJava); return Optional.of(dummyRDotJava); }
public AbstractGenruleStep( BuildRuleType type, BuildTarget target, CommandString commandString, Set<BuildRule> depsToSubstituteInCommandString, @Nullable File workingDirectory) { super(workingDirectory); this.type = type; this.target = target; this.commandString = Preconditions.checkNotNull(commandString); this.depsToSubstituteInCommandString = ImmutableSortedSet.copyOf( depsToSubstituteInCommandString); }
@Override public boolean isMatch( Map<String, Object> rawParseData, BuildRuleType buildRuleType, BuildTarget buildTarget) { Object rawValue = rawParseData.get(JavaLibraryDescription.ANNOTATION_PROCESSORS); return ((rawValue instanceof Iterable) && !Iterables.isEmpty((Iterable<?>) rawValue)); }
private static ImmutableSet<BuildTarget> getAllTargetsOfType( Iterable<BuildRule> nodes, BuildRuleType type) { ImmutableSet.Builder<BuildTarget> targetsBuilder = ImmutableSet.builder(); for (BuildRule node : nodes) { if (node.getType() == type) { targetsBuilder.add(node.getBuildTarget()); } } return targetsBuilder.build(); }
public FakeJavaLibrary( BuildRuleType type, BuildTarget target, ImmutableSortedSet<BuildRule> deps, ImmutableSet<BuildTargetPattern> visibilityPatterns) { super(type, target, deps, visibilityPatterns); this.visibilityPatterns = visibilityPatterns; }
public ImmutableSortedSet<Flavor> addImplicitFlavorsForRuleTypes( ImmutableSortedSet<Flavor> argDefaultFlavors, BuildRuleType... types) { Optional<Flavor> typeFlavor = CxxLibraryDescription.LIBRARY_TYPE.getFlavor(argDefaultFlavors); CxxPlatformsProvider cxxPlatformsProvider = getCxxPlatformsProvider(); Optional<Flavor> platformFlavor = cxxPlatformsProvider.getCxxPlatforms().getFlavor(argDefaultFlavors); LOG.debug("Got arg default type %s platform %s", typeFlavor, platformFlavor); for (BuildRuleType type : types) { ImmutableMap<String, Flavor> libraryDefaults = cxxBuckConfig.getDefaultFlavorsForRuleType(type); if (!typeFlavor.isPresent()) { typeFlavor = Optional.ofNullable(libraryDefaults.get(CxxBuckConfig.DEFAULT_FLAVOR_LIBRARY_TYPE)); } if (!platformFlavor.isPresent()) { platformFlavor = Optional.ofNullable(libraryDefaults.get(CxxBuckConfig.DEFAULT_FLAVOR_PLATFORM)); } } ImmutableSortedSet<Flavor> result = ImmutableSortedSet.of( // Default to static if not otherwise specified. typeFlavor.orElse(CxxDescriptionEnhancer.STATIC_FLAVOR), platformFlavor.orElse(cxxPlatformsProvider.getDefaultCxxPlatform().getFlavor())); LOG.debug("Got default flavors %s for rule types %s", result, Arrays.toString(types)); return result; }
@Override public RuleKeyHasher<FullRuleKey> putBuildRuleType(BuildRuleType buildRuleType) { push( Value.buildRuleType( new com.facebook.buck.log.thrift.rulekeys.BuildRuleType(buildRuleType.getName()))); return this; }
@Override protected final RuleKeyBuilder<RULE_KEY> setSingleValue(@Nullable Object val) { if (val == null) { // Null value first hasher.putNull(); } else if (val instanceof Boolean) { // JRE types hasher.putBoolean((boolean) val); } else if (val instanceof Enum) { hasher.putString(String.valueOf(val)); } else if (val instanceof Number) { hasher.putNumber((Number) val); } else if (val instanceof String) { hasher.putString((String) val); } else if (val instanceof Pattern) { hasher.putPattern((Pattern) val); } else if (val instanceof BuildRuleType) { // Buck types hasher.putBuildRuleType((BuildRuleType) val); } else if (val instanceof RuleKey) { hasher.putRuleKey((RuleKey) val); } else if (val instanceof BuildTarget) { hasher.putBuildTarget((BuildTarget) val); } else if (val instanceof SourceRoot) { hasher.putSourceRoot((SourceRoot) val); } else if (val instanceof Sha1HashCode) { hasher.putSha1((Sha1HashCode) val); } else if (val instanceof byte[]) { hasher.putBytes((byte[]) val); } else { throw new RuntimeException("Unsupported value type: " + val.getClass()); } return this; }
@Override public BuildRuleType getBuildRuleType() { return TYPE; }
@Override public boolean isMatch(Map<String, Object> rawParseData, BuildRuleType buildRuleType, BuildTarget buildTarget) { return true; }
public boolean isMatch( Map<String, Object> rawParseData, BuildRuleType buildRuleType, BuildTarget buildTarget);
/** * @param map the map of values that define the rule. * @return the type of rule defined by the map. */ private BuildRuleType parseBuildRuleTypeFromRawRule(Map<String, Object> map) { String type = (String) map.get("type"); return repository.getBuildRuleType(type); }
@Nullable public TargetNode<?> get(BuildTarget buildTarget) { // Fast path. TargetNode<?> toReturn = memoizedTargetNodes.get(buildTarget); if (toReturn != null) { return toReturn; } BuildTarget unflavored = buildTarget.getUnflavoredTarget(); List<Map<String, Object>> rules = state.getRawRules(unflavored.getBuildFilePath()); for (Map<String, Object> map : rules) { if (!buildTarget.getShortNameOnly().equals(map.get("name"))) { continue; } BuildRuleType buildRuleType = parseBuildRuleTypeFromRawRule(map); targetsToFile.put( unflavored, normalize(Paths.get((String) map.get("buck.base_path"))) .resolve("BUCK").toAbsolutePath()); Description<?> description = repository.getDescription(buildRuleType); if (description == null) { throw new HumanReadableException("Unrecognized rule %s while parsing %s%s.", buildRuleType, BuildTarget.BUILD_TARGET_PREFIX, unflavored.getBuildFilePath()); } if ((description instanceof Flavored) && !((Flavored) description).hasFlavor(buildTarget.getFlavor())) { throw new HumanReadableException("Unrecognized flavor in target %s while parsing %s%s.", buildTarget, BuildTarget.BUILD_TARGET_PREFIX, buildTarget.getBuildFilePath()); } BuildRuleFactoryParams factoryParams = new BuildRuleFactoryParams( map, repository.getFilesystem(), buildTargetParser, // Although we store the rule by its unflavoured name, when we construct it, we need the // flavour. buildTarget, ruleKeyBuilderFactory); TargetNode<?> targetNode; try { targetNode = new TargetNode<>(description, factoryParams); } catch (NoSuchBuildTargetException e) { // throw new HumanReadableException(e); } TargetNode<?> existingTargetNode = memoizedTargetNodes.put(buildTarget, targetNode); if (existingTargetNode != null) { throw new HumanReadableException("Duplicate definition for " + unflavored); } // PMD considers it bad form to return while in a loop. } return memoizedTargetNodes.get(buildTarget); }
/** * Return a {@link BuildRule} that constructs the source file which contains the list * of test modules this python test rule will run. Setting up a separate build rule * for this allows us to use the existing python binary rule without changes to account * for the build-time creation of this file. */ private static BuildRule createTestModulesSourceBuildRule( BuildRuleParams params, final Path outputPath, ImmutableSet<String> testModules) { // Modify the build rule params to change the target, type, and remove all deps. BuildRuleParams newParams = params.copyWithChanges( new BuildRuleType("create_test_modules_list"), BuildTargets.createFlavoredBuildTarget( params.getBuildTarget(), new Flavor("test_module")), ImmutableSortedSet.<BuildRule>of(), ImmutableSortedSet.<BuildRule>of()); final String contents = getTestModulesListContents(testModules); return new AbstractBuildRule(newParams) { @Override protected Iterable<Path> getInputsToCompareToOutput() { return ImmutableList.of(); } @Override protected RuleKey.Builder appendDetailsToRuleKey(RuleKey.Builder builder) { return builder .set("contents", contents) .set("output", outputPath.toString()); } @Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { buildableContext.recordArtifact(outputPath); return ImmutableList.of( new MkdirStep(outputPath.getParent()), new WriteFileStep(contents, outputPath)); } @Override public Path getPathToOutputFile() { return outputPath; } }; }