/** * Note that if this Parser is populated via {@link #filterAllTargetsInProject}, then this method * should not be called. */ private void parseBuildFileContainingTarget( BuildTarget buildTarget, Iterable<String> defaultIncludes, ProjectBuildFileParser buildFileParser) throws BuildFileParseException, BuildTargetException, IOException { if (isCacheComplete(defaultIncludes)) { // In this case, all of the build rules should have been loaded into the knownBuildTargets // Map before this method was invoked. Therefore, there should not be any more build files to // parse. This must be the result of traversing a non-existent dep in a build rule, so an // error is reported to the user. Unfortunately, the source of the build file where the // non-existent rule was declared is not known at this point, which is why it is not included // in the error message. throw new HumanReadableException("No such build target: %s.", buildTarget); } File buildFile = buildTarget.getBuildFile(projectFilesystem); if (isCached(buildFile, defaultIncludes)) { throw new HumanReadableException( "The build file that should contain %s has already been parsed (%s), " + "but %s was not found. Please make sure that %s is defined in %s.", buildTarget, buildFile, buildTarget, buildTarget, buildFile); } parseBuildFile(buildFile, defaultIncludes, buildFileParser); }
/** * @param buildTargets the build targets to generate a dependency graph for. * @param defaultIncludes the files to include before executing build files. * @param eventBus used to log events while parsing. * @return the dependency graph containing the build targets and their related targets. */ public DependencyGraph parseBuildFilesForTargets( Iterable<BuildTarget> buildTargets, Iterable<String> defaultIncludes, BuckEventBus eventBus) throws BuildFileParseException, BuildTargetException, IOException { // Make sure that knownBuildTargets is initially populated with the BuildRuleBuilders for the // seed BuildTargets for the traversal. eventBus.post(ParseEvent.started(buildTargets)); DependencyGraph graph = null; try (ProjectBuildFileParser buildFileParser = buildFileParserFactory.createParser(defaultIncludes)) { if (!isCacheComplete(defaultIncludes)) { Set<File> buildTargetFiles = Sets.newHashSet(); for (BuildTarget buildTarget : buildTargets) { File buildFile = buildTarget.getBuildFile(projectFilesystem); boolean isNewElement = buildTargetFiles.add(buildFile); if (isNewElement) { parseBuildFile(buildFile, defaultIncludes, buildFileParser); } } } graph = findAllTransitiveDependencies(buildTargets, defaultIncludes, buildFileParser); return graph; } finally { eventBus.post(ParseEvent.finished(buildTargets, Optional.fromNullable(graph))); } }
/** @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; } BuildRuleType buildRuleType = parseBuildRuleTypeFromRawRule(map); BuildTarget target = parseBuildTargetFromRawRule(map); BuildRuleFactory<?> factory = buildRuleTypes.getFactory(buildRuleType); if (factory == null) { throw new HumanReadableException( "Unrecognized rule %s while parsing %s.", buildRuleType, target.getBuildFile(projectFilesystem)); } BuildFileTree buildFileTree; buildFileTree = buildFileTreeCache.getInput(); BuildRuleBuilder<?> buildRuleBuilder = factory.newInstance( new BuildRuleFactoryParams( map, projectFilesystem, buildFileTree, buildTargetParser, target, ruleKeyBuilderFactory)); Object existingRule = knownBuildTargets.put(target, buildRuleBuilder); if (existingRule != null) { throw new RuntimeException("Duplicate definition for " + target.getFullyQualifiedName()); } parsedBuildFiles.put(normalize(target.getBuildFile(projectFilesystem).toPath()), map); } }