/** * Finds the build file responsible for the given {@link Path} and invalidates all of the cached * rules dependent on it. * * @param path A {@link Path} "contained" within the build file to find and invalidate. */ private void invalidateContainingBuildFile(Path path) throws IOException { String packageBuildFilePath = buildFileTreeCache .getInput() .getBasePathOfAncestorTarget( projectFilesystem.getProjectRoot().toPath().relativize(path).toString()); invalidateDependents( projectFilesystem .getFileForRelativePath(packageBuildFilePath + '/' + BuckConstant.BUILD_RULES_FILE_NAME) .toPath()); }
/** * Called when file change events are posted to the file change EventBus to invalidate cached * build rules if required. */ @Subscribe public synchronized void onFileSystemChange(WatchEvent<?> event) throws IOException { if (console.getVerbosity() == Verbosity.ALL) { console .getStdErr() .printf( "Parser watched event %s %s\n", event.kind(), projectFilesystem.createContextString(event)); } if (projectFilesystem.isPathChangeEvent(event)) { Path path = (Path) event.context(); if (isPathCreateOrDeleteEvent(event)) { if (path.endsWith(BuckConstant.BUILD_RULES_FILE_NAME)) { // If a build file has been added or removed, reconstruct the build file tree. buildFileTreeCache.invalidate(); } // Added or removed files can affect globs, so invalidate the package build file // "containing" {@code path} unless its filename matches a temp file pattern. if (!isTempFile(path)) { invalidateContainingBuildFile(path); } } // Invalidate the raw rules and targets dependent on this file. invalidateDependents(path); } else { // Non-path change event, likely an overflow due to many change events: invalidate everything. buildFileTreeCache.invalidate(); invalidateCache(); } }
/** @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); } }