List of usage examples for com.google.common.collect ImmutableSet contains
boolean contains(Object o);
From source file:org.waveprotocol.box.server.waveserver.Wave.java
private <T extends WaveletContainer> T getWavelet(WaveletId waveletId, LoadingCache<WaveletId, T> waveletsMap) throws WaveletStateException { ImmutableSet<WaveletId> storedWavelets; try {/*from w w w . j av a 2 s .c o m*/ storedWavelets = FutureUtil.getResultOrPropagateException(lookedupWavelets, PersistenceException.class); } catch (PersistenceException e) { throw new WaveletStateException("Failed to lookup wavelet " + WaveletName.of(waveId, waveletId), e); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new WaveletStateException("Interrupted looking up wavelet " + WaveletName.of(waveId, waveletId), e); } if (LOG.isFineLoggable()) { if (storedWavelets != null) { if (storedWavelets.contains(waveletId)) { LOG.fine("Wavelet is in storedWavelets"); } if (waveletsMap.getIfPresent(waveletId) != null) { LOG.fine("Wavelet is in wavletsMap"); } } } // Since waveletsMap is a computing map, we must call getIfPresent(waveletId) // to tell if waveletId is mapped, we cannot test if get(waveletId) returns null. if (storedWavelets != null && !storedWavelets.contains(waveletId) && waveletsMap.getIfPresent(waveletId) == null) { return null; } else { try { T wavelet = waveletsMap.get(waveletId); return wavelet; } catch (CacheLoader.InvalidCacheLoadException ex) { return null; } catch (ExecutionException ex) { throw new RuntimeException(ex); } } }
From source file:com.google.devtools.build.lib.rules.cpp.CppToolchainInfo.java
private CToolchain addLegacyFeatures(CToolchain toolchain) { CToolchain.Builder toolchainBuilder = CToolchain.newBuilder(); Set<ArtifactCategory> definedCategories = new HashSet<>(); for (ArtifactNamePattern pattern : toolchainBuilder.getArtifactNamePatternList()) { try {/* ww w . ja v a 2 s.c om*/ definedCategories.add(ArtifactCategory.valueOf(pattern.getCategoryName().toUpperCase())); } catch (IllegalArgumentException e) { // Invalid category name, will be detected later. continue; } } for (ArtifactCategory category : ArtifactCategory.values()) { if (!definedCategories.contains(category) && category.getDefaultPattern() != null) { toolchainBuilder.addArtifactNamePattern( ArtifactNamePattern.newBuilder().setCategoryName(category.toString().toLowerCase()) .setPattern(category.getDefaultPattern()).build()); } } ImmutableSet<String> featureNames = toolchain.getFeatureList().stream().map(feature -> feature.getName()) .collect(ImmutableSet.toImmutableSet()); if (!featureNames.contains(CppRuleClasses.NO_LEGACY_FEATURES)) { try { String gccToolPath = "DUMMY_GCC_TOOL"; String linkerToolPath = "DUMMY_LINKER_TOOL"; String arToolPath = "DUMMY_AR_TOOL"; String stripToolPath = "DUMMY_STRIP_TOOL"; for (ToolPath tool : toolchain.getToolPathList()) { if (tool.getName().equals(Tool.GCC.getNamePart())) { gccToolPath = tool.getPath(); linkerToolPath = crosstoolTopPathFragment.getRelative(PathFragment.create(tool.getPath())) .getPathString(); } if (tool.getName().equals(Tool.AR.getNamePart())) { arToolPath = tool.getPath(); } if (tool.getName().equals(Tool.STRIP.getNamePart())) { stripToolPath = tool.getPath(); } } // TODO(b/30109612): Remove fragile legacyCompileFlags shuffle once there are no legacy // crosstools. // Existing projects depend on flags from legacy toolchain fields appearing first on the // compile command line. 'legacy_compile_flags' feature contains all these flags, and so it // needs to appear before other features from {@link CppActionConfigs}. CToolchain.Feature legacyCompileFlagsFeature = toolchain.getFeatureList().stream() .filter(feature -> feature.getName().equals(CppRuleClasses.LEGACY_COMPILE_FLAGS)) .findFirst().orElse(null); if (legacyCompileFlagsFeature != null) { toolchainBuilder.addFeature(legacyCompileFlagsFeature); toolchain = removeLegacyCompileFlagsFeatureFromToolchain(toolchain); } TextFormat.merge( CppActionConfigs.getCppActionConfigs( getTargetLibc().equals("macosx") ? CppPlatform.MAC : CppPlatform.LINUX, featureNames, gccToolPath, linkerToolPath, arToolPath, stripToolPath, supportsEmbeddedRuntimes, toolchain.getSupportsInterfaceSharedObjects()), toolchainBuilder); } catch (ParseException e) { // Can only happen if we change the proto definition without changing our // configuration above. throw new RuntimeException(e); } } toolchainBuilder.mergeFrom(toolchain); if (!featureNames.contains(CppRuleClasses.NO_LEGACY_FEATURES)) { try { TextFormat.merge(CppActionConfigs.getFeaturesToAppearLastInToolchain(featureNames), toolchainBuilder); } catch (ParseException e) { // Can only happen if we change the proto definition without changing our // configuration above. throw new RuntimeException(e); } } return toolchainBuilder.build(); }
From source file:com.google.devtools.build.android.aapt2.ProtoResourceUsageAnalyzer.java
/** * Calculate and removes unused resource from the {@link ProtoApk}. * * @param apk An apk in the aapt2 proto format. * @param classes The associated classes for the apk. * @param destination Where to write the reduced resources. * @param keep A list of resource urls to keep, unused or not. * @param discard A list of resource urls to always discard. *//*from www .ja va 2 s . c o m*/ public void shrink(ProtoApk apk, Path classes, Path destination, Collection<String> keep, Collection<String> discard) throws IOException, ParserConfigurationException, SAXException { // record resources and manifest apk.visitResources( // First, collect all declarations using the declaration visitor. // This allows the model to start with a defined set of resources to build the reference // graph on. apk.visitResources(new ResourceDeclarationVisitor(model())).toUsageVisitor()); recordClassUsages(classes); // Have to give the model xml attributes with keep and discard urls. final NamedNodeMap toolAttributes = XmlUtils.parseDocument(String.format( "<resources xmlns:tools='http://schemas.android.com/tools' tools:keep='%s'" + " tools:discard='%s'></resources>", keep.stream().collect(joining(",")), discard.stream().collect(joining(","))), true) .getDocumentElement().getAttributes(); for (int i = 0; i < toolAttributes.getLength(); i++) { model().recordToolsAttributes((Attr) toolAttributes.item(i)); } model().processToolsAttributes(); keepPossiblyReferencedResources(); dumpReferences(); // Remove unused. final ImmutableSet<Resource> unused = ImmutableSet.copyOf(model().findUnused()); // ResourceUsageAnalyzer uses the logger to generate the report. Logger logger = Logger.getLogger(getClass().getName()); unused.forEach(resource -> logger .fine("Deleted unused file " + ((resource.locations != null && resource.locations.getFile() != null) ? resource.locations.getFile().toString() : "<apk>" + " for resource " + resource))); apk.copy(destination, (resourceType, name) -> !unused .contains(Preconditions.checkNotNull(model().getResource(resourceType, name), "%s/%s was not declared but is copied!", resourceType, name))); }
From source file:ru.tehkode.permissions.backends.hybrid.HybridBackend.java
/** * Update the cache of names for a newly created data object, if necessary. * * @param list The pointer to current cache state * @param data The data to check for presence *///from w ww . j av a 2 s.c om private void updateNameCache(AtomicReference<ImmutableSet<String>> list, PermissionsData data) { ImmutableSet<String> cache, newVal; do { newVal = cache = list.get(); if (cache == null || (!cache.contains(data.getIdentifier()) && !data.isVirtual())) { newVal = null; } } while (!list.compareAndSet(cache, newVal)); }
From source file:com.google.devtools.build.lib.rules.android.AndroidBinary.java
/** Creates one or more classes.dex files that correspond to {@code proguardedJar}. */ private static DexingOutput dex(RuleContext ruleContext, AndroidSemantics androidSemantics, Artifact binaryJar, Artifact proguardedJar, boolean isBinaryJarFiltered, AndroidCommon common, @Nullable Artifact mainDexProguardSpec, JavaTargetAttributes attributes, Function<Artifact, Artifact> derivedJarFunction) throws InterruptedException, RuleErrorException { List<String> dexopts = ruleContext.getTokenizedStringListAttr("dexopts"); MultidexMode multidexMode = getMultidexMode(ruleContext); if (!supportsMultidexMode(ruleContext, multidexMode)) { ruleContext.throwWithRuleError("Multidex mode \"" + multidexMode.getAttributeValue() + "\" not supported by this version of the Android SDK"); }// w ww .j a v a 2 s .co m int dexShards = ruleContext.attributes().get("dex_shards", Type.INTEGER); if (dexShards > 1) { if (multidexMode == MultidexMode.OFF) { ruleContext.throwWithRuleError(".dex sharding is only available in multidex mode"); } if (multidexMode == MultidexMode.MANUAL_MAIN_DEX) { ruleContext.throwWithRuleError(".dex sharding is not available in manual multidex mode"); } } Artifact mainDexList = ruleContext.getPrerequisiteArtifact("main_dex_list", Mode.TARGET); if ((mainDexList != null && multidexMode != MultidexMode.MANUAL_MAIN_DEX) || (mainDexList == null && multidexMode == MultidexMode.MANUAL_MAIN_DEX)) { ruleContext.throwWithRuleError( "Both \"main_dex_list\" and \"multidex='manual_main_dex'\" must be specified."); } // Always OFF if finalJarIsDerived ImmutableSet<AndroidBinaryType> incrementalDexing = getEffectiveIncrementalDexing(ruleContext, dexopts, !Objects.equals(binaryJar, proguardedJar)); Artifact inclusionFilterJar = isBinaryJarFiltered && Objects.equals(binaryJar, proguardedJar) ? binaryJar : null; if (multidexMode == MultidexMode.OFF) { // Single dex mode: generate classes.dex directly from the input jar. if (incrementalDexing.contains(AndroidBinaryType.MONODEX)) { Artifact classesDex = getDxArtifact(ruleContext, "classes.dex.zip"); Artifact jarToDex = getDxArtifact(ruleContext, "classes.jar"); createShuffleJarAction(ruleContext, true, (Artifact) null, ImmutableList.of(jarToDex), common, inclusionFilterJar, dexopts, androidSemantics, attributes, derivedJarFunction, (Artifact) null); createDexMergerAction(ruleContext, "off", jarToDex, classesDex, (Artifact) null, dexopts); return new DexingOutput(classesDex, binaryJar, ImmutableList.of(classesDex)); } else { // By *not* writing a zip we get dx to drop resources on the floor. Artifact classesDex = getDxArtifact(ruleContext, "classes.dex"); AndroidCommon.createDexAction(ruleContext, proguardedJar, classesDex, dexopts, /* multidex */ false, (Artifact) null); return new DexingOutput(classesDex, binaryJar, ImmutableList.of(classesDex)); } } else { // Multidex mode: generate classes.dex.zip, where the zip contains [classes.dex, // classes2.dex, ... classesN.dex]. if (multidexMode == MultidexMode.LEGACY) { // For legacy multidex, we need to generate a list for the dexer's --main-dex-list flag. mainDexList = createMainDexListAction(ruleContext, androidSemantics, proguardedJar, mainDexProguardSpec); } Artifact classesDex = getDxArtifact(ruleContext, "classes.dex.zip"); if (dexShards > 1) { List<Artifact> shards = new ArrayList<>(dexShards); for (int i = 1; i <= dexShards; i++) { shards.add(getDxArtifact(ruleContext, "shard" + i + ".jar")); } Artifact javaResourceJar = createShuffleJarAction(ruleContext, incrementalDexing.contains(AndroidBinaryType.MULTIDEX_SHARDED), /*proguardedJar*/ !Objects.equals(binaryJar, proguardedJar) ? proguardedJar : null, shards, common, inclusionFilterJar, dexopts, androidSemantics, attributes, derivedJarFunction, mainDexList); List<Artifact> shardDexes = new ArrayList<>(dexShards); for (int i = 1; i <= dexShards; i++) { Artifact shard = shards.get(i - 1); Artifact shardDex = getDxArtifact(ruleContext, "shard" + i + ".dex.zip"); shardDexes.add(shardDex); if (incrementalDexing.contains(AndroidBinaryType.MULTIDEX_SHARDED)) { // If there's a main dex list then the first shard contains exactly those files. // To work with devices that lack native multi-dex support we need to make sure that // the main dex list becomes one dex file if at all possible. // Note shard here (mostly) contains of .class.dex files from shuffled dex archives, // instead of being a conventional Jar file with .class files. String multidexStrategy = mainDexList != null && i == 1 ? "minimal" : "best_effort"; createDexMergerAction(ruleContext, multidexStrategy, shard, shardDex, (Artifact) null, dexopts); } else { AndroidCommon.createDexAction(ruleContext, shard, shardDex, dexopts, /* multidex */ true, (Artifact) null); } } CommandLine mergeCommandLine = CustomCommandLine.builder() .addBeforeEachExecPath("--input_zip", shardDexes).addExecPath("--output_zip", classesDex) .build(); ruleContext.registerAction(new SpawnAction.Builder().setMnemonic("MergeDexZips") .setProgressMessage("Merging dex shards for " + ruleContext.getLabel()) .setExecutable(ruleContext.getExecutablePrerequisite("$merge_dexzips", Mode.HOST)) .addInputs(shardDexes).addOutput(classesDex).setCommandLine(mergeCommandLine) .build(ruleContext)); if (incrementalDexing.contains(AndroidBinaryType.MULTIDEX_SHARDED)) { // Using the deploy jar for java resources gives better "bazel mobile-install" performance // with incremental dexing b/c bazel can create the "incremental" and "split resource" // APKs earlier (b/c these APKs don't depend on code being dexed here). This is also done // for other multidex modes. javaResourceJar = binaryJar; } return new DexingOutput(classesDex, javaResourceJar, shardDexes); } else { if (incrementalDexing.contains(AndroidBinaryType.MULTIDEX_UNSHARDED)) { Artifact jarToDex = AndroidBinary.getDxArtifact(ruleContext, "classes.jar"); createShuffleJarAction(ruleContext, true, (Artifact) null, ImmutableList.of(jarToDex), common, inclusionFilterJar, dexopts, androidSemantics, attributes, derivedJarFunction, (Artifact) null); createDexMergerAction(ruleContext, "minimal", jarToDex, classesDex, mainDexList, dexopts); } else { // Because the dexer also places resources into this zip, we also need to create a cleanup // action that removes all non-.dex files before staging for apk building. // Create an artifact for the intermediate zip output that includes non-.dex files. Artifact classesDexIntermediate = AndroidBinary.getDxArtifact(ruleContext, "intermediate_classes.dex.zip"); // Have the dexer generate the intermediate file and the "cleaner" action consume this to // generate the final archive with only .dex files. AndroidCommon.createDexAction(ruleContext, proguardedJar, classesDexIntermediate, dexopts, /* multidex */ true, mainDexList); createCleanDexZipAction(ruleContext, classesDexIntermediate, classesDex); } return new DexingOutput(classesDex, binaryJar, ImmutableList.of(classesDex)); } } }
From source file:com.facebook.buck.jvm.java.AbstractUnusedDependenciesFinder.java
private ImmutableSet<UnflavoredBuildTarget> findUnusedDependencies(ImmutableSet<Path> usedJars, Iterable<BuildTarget> targets) { BuildRuleResolver buildRuleResolver = getBuildRuleResolver(); SourcePathResolver sourcePathResolver = getSourcePathResolver(); ImmutableSet.Builder<UnflavoredBuildTarget> unusedDependencies = ImmutableSet.builder(); for (BuildRule dependency : buildRuleResolver.getAllRules(targets)) { SourcePath dependencyOutput = dependency.getSourcePathToOutput(); if (dependencyOutput == null) { continue; }/*w ww . j av a2 s . co m*/ Path dependencyOutputPath = sourcePathResolver.getAbsolutePath(dependencyOutput); if (!usedJars.contains(dependencyOutputPath)) { Optional<Path> abiJarPath = getAbiJarPath(sourcePathResolver, dependency); if (abiJarPath.isPresent() && usedJars.contains(abiJarPath.get())) { continue; } unusedDependencies.add(dependency.getBuildTarget().getUnflavoredBuildTarget()); } } return unusedDependencies.build(); }
From source file:dagger.internal.codegen.SubcomponentFactoryMethodValidator.java
private ImmutableSet<TypeElement> findMissingModules(ChildFactoryMethodEdge edge, BindingGraph graph) { ImmutableSet<TypeElement> factoryMethodParameters = subgraphFactoryMethodParameters(edge, graph); ComponentNode child = (ComponentNode) graph.network().incidentNodes(edge).target(); SetView<TypeElement> modulesOwnedByChild = ownedModules(child, graph); return graph.bindings().stream() // bindings owned by child .filter(binding -> binding.componentPath().equals(child.componentPath())) // that require a module instance .filter(binding -> binding.requiresModuleInstance()) .map(binding -> binding.contributingModule().get()).distinct() // module owned by child .filter(module -> modulesOwnedByChild.contains(module)) // module not in the method parameters .filter(module -> !factoryMethodParameters.contains(module)) // module doesn't have an accessible no-arg constructor .filter(moduleType -> !componentCanMakeNewInstances(moduleType)).collect(toImmutableSet()); }
From source file:com.facebook.buck.cli.BuckConfig.java
/** * Clients should use {@link #createArtifactCache(Optional, BuckEventBus)} unless it * is expected that the user has defined a {@code cassandra} cache, and that it should be used * exclusively./*from w w w . j a va2s .co m*/ */ @Nullable CassandraArtifactCache createCassandraArtifactCache(Optional<String> currentWifiSsid, BuckEventBus buckEventBus) { // cache.blacklisted_wifi_ssids ImmutableSet<String> blacklistedWifi = ImmutableSet.copyOf(Splitter.on(",").trimResults().omitEmptyStrings() .split(getValue("cache", "blacklisted_wifi_ssids").or(""))); if (currentWifiSsid.isPresent() && blacklistedWifi.contains(currentWifiSsid.get())) { // We're connected to a wifi hotspot that has been explicitly blacklisted from connecting to // Cassandra. return null; } // cache.cassandra_mode final boolean doStore = readCacheMode("cassandra_mode", DEFAULT_CASSANDRA_MODE); // cache.hosts String cacheHosts = getValue("cache", "hosts").or(""); // cache.port int port = Integer.parseInt(getValue("cache", "port").or(DEFAULT_CASSANDRA_PORT)); // cache.connection_timeout_seconds int timeoutSeconds = Integer .parseInt(getValue("cache", "connection_timeout_seconds").or(DEFAULT_CASSANDRA_TIMEOUT_SECONDS)); try { return new CassandraArtifactCache(cacheHosts, port, timeoutSeconds, doStore, buckEventBus); } catch (ConnectionException e) { buckEventBus.post(ThrowableLogEvent.create(e, "Cassandra cache connection failure.")); return null; } }
From source file:com.google.googlejavaformat.java.JavaInput.java
/** * Lex the input and build the list of toks. * * @param text the text to be lexed./*from ww w. j a v a 2 s.c o m*/ * @param stopTokens a set of tokens which should cause lexing to stop. If one of these is found, * the returned list will include tokens up to but not including that token. */ static ImmutableList<Tok> buildToks(String text, ImmutableSet<TokenKind> stopTokens) throws FormatterException { stopTokens = ImmutableSet.<TokenKind>builder().addAll(stopTokens).add(TokenKind.EOF).build(); Context context = new Context(); new JavacFileManager(context, true, UTF_8); DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>(); context.put(DiagnosticListener.class, diagnosticCollector); Log log = Log.instance(context); log.useSource(new SimpleJavaFileObject(URI.create("Source.java"), Kind.SOURCE) { @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return text; } }); DeferredDiagnosticHandler diagnostics = new DeferredDiagnosticHandler(log); ImmutableList<RawTok> rawToks = JavacTokens.getTokens(text, context, stopTokens); if (diagnostics.getDiagnostics().stream().anyMatch(d -> d.getKind() == Diagnostic.Kind.ERROR)) { return ImmutableList.of(new Tok(0, "", "", 0, 0, true, null)); // EOF } int kN = 0; List<Tok> toks = new ArrayList<>(); int charI = 0; int columnI = 0; for (RawTok t : rawToks) { if (stopTokens.contains(t.kind())) { break; } int charI0 = t.pos(); // Get string, possibly with Unicode escapes. String originalTokText = text.substring(charI0, t.endPos()); String tokText = t.kind() == TokenKind.STRINGLITERAL ? t.stringVal() // Unicode escapes removed. : originalTokText; char tokText0 = tokText.charAt(0); // The token's first character. final boolean isToken; // Is this tok a token? final boolean isNumbered; // Is this tok numbered? (tokens and comments) String extraNewline = null; // Extra newline at end? List<String> strings = new ArrayList<>(); if (Character.isWhitespace(tokText0)) { isToken = false; isNumbered = false; Iterator<String> it = Newlines.lineIterator(originalTokText); while (it.hasNext()) { String line = it.next(); String newline = Newlines.getLineEnding(line); if (newline != null) { String spaces = line.substring(0, line.length() - newline.length()); if (!spaces.isEmpty()) { strings.add(spaces); } strings.add(newline); } else if (!line.isEmpty()) { strings.add(line); } } } else if (tokText.startsWith("'") || tokText.startsWith("\"")) { isToken = true; isNumbered = true; strings.add(originalTokText); } else if (tokText.startsWith("//") || tokText.startsWith("/*")) { // For compatibility with an earlier lexer, the newline after a // comment is its own tok. if (tokText.startsWith("//") && (originalTokText.endsWith("\n") || originalTokText.endsWith("\r"))) { extraNewline = Newlines.getLineEnding(originalTokText); tokText = tokText.substring(0, tokText.length() - extraNewline.length()); originalTokText = originalTokText.substring(0, originalTokText.length() - extraNewline.length()); } isToken = false; isNumbered = true; strings.add(originalTokText); } else if (Character.isJavaIdentifierStart(tokText0) || Character.isDigit(tokText0) || (tokText0 == '.' && tokText.length() > 1 && Character.isDigit(tokText.charAt(1)))) { // Identifier, keyword, or numeric literal (a dot may begin a number, as in .2D). isToken = true; isNumbered = true; strings.add(tokText); } else { // Other tokens ("+" or "++" or ">>" are broken into one-character toks, because ">>" // cannot be lexed without syntactic knowledge. This implementation fails if the token // contains Unicode escapes. isToken = true; isNumbered = true; for (char c : tokText.toCharArray()) { strings.add(String.valueOf(c)); } } if (strings.size() == 1) { toks.add(new Tok(isNumbered ? kN++ : -1, originalTokText, tokText, charI, columnI, isToken, t.kind())); charI += originalTokText.length(); columnI = updateColumn(columnI, originalTokText); } else { if (strings.size() != 1 && !tokText.equals(originalTokText)) { throw new FormatterException( "Unicode escapes not allowed in whitespace or multi-character operators"); } for (String str : strings) { toks.add(new Tok(isNumbered ? kN++ : -1, str, str, charI, columnI, isToken, null)); charI += str.length(); columnI = updateColumn(columnI, originalTokText); } } if (extraNewline != null) { toks.add(new Tok(-1, extraNewline, extraNewline, charI, columnI, false, null)); columnI = 0; charI += extraNewline.length(); } } toks.add(new Tok(kN, "", "", charI, columnI, true, null)); // EOF tok. return ImmutableList.copyOf(toks); }
From source file:com.facebook.buck.features.python.PythonTestDescription.java
@Override public PythonTest createBuildRule(BuildRuleCreationContextWithTargetGraph context, BuildTarget buildTarget, BuildRuleParams params, PythonTestDescriptionArg args) { FlavorDomain<PythonPlatform> pythonPlatforms = toolchainProvider .getByName(PythonPlatformsProvider.DEFAULT_NAME, PythonPlatformsProvider.class) .getPythonPlatforms();/* ww w. jav a2 s .com*/ ActionGraphBuilder graphBuilder = context.getActionGraphBuilder(); PythonPlatform pythonPlatform = pythonPlatforms.getValue(buildTarget) .orElse(pythonPlatforms.getValue(args.getPlatform().<Flavor>map(InternalFlavor::of) .orElse(pythonPlatforms.getFlavors().iterator().next()))); CxxPlatform cxxPlatform = getCxxPlatform(buildTarget, args).resolve(graphBuilder); SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(graphBuilder); SourcePathResolver pathResolver = DefaultSourcePathResolver.from(ruleFinder); Path baseModule = PythonUtil.getBasePath(buildTarget, args.getBaseModule()); Optional<ImmutableMap<BuildTarget, Version>> selectedVersions = context.getTargetGraph().get(buildTarget) .getSelectedVersions(); ImmutableMap<Path, SourcePath> srcs = PythonUtil.getModules(buildTarget, graphBuilder, ruleFinder, pathResolver, pythonPlatform, cxxPlatform, "srcs", baseModule, args.getSrcs(), args.getPlatformSrcs(), args.getVersionedSrcs(), selectedVersions); ImmutableMap<Path, SourcePath> resources = PythonUtil.getModules(buildTarget, graphBuilder, ruleFinder, pathResolver, pythonPlatform, cxxPlatform, "resources", baseModule, args.getResources(), args.getPlatformResources(), args.getVersionedResources(), selectedVersions); // Convert the passed in module paths into test module names. ImmutableSet.Builder<String> testModulesBuilder = ImmutableSet.builder(); for (Path name : srcs.keySet()) { testModulesBuilder.add(PythonUtil.toModuleName(buildTarget, name.toString())); } ImmutableSet<String> testModules = testModulesBuilder.build(); ProjectFilesystem projectFilesystem = context.getProjectFilesystem(); // Construct a build rule to generate the test modules list source file and // add it to the build. BuildRule testModulesBuildRule = createTestModulesSourceBuildRule(buildTarget, projectFilesystem, getTestModulesListPath(buildTarget, projectFilesystem), testModules); graphBuilder.addToIndex(testModulesBuildRule); String mainModule; if (args.getMainModule().isPresent()) { mainModule = args.getMainModule().get(); } else { mainModule = PythonUtil.toModuleName(buildTarget, getTestMainName().toString()); } // Build up the list of everything going into the python test. PythonPackageComponents testComponents = PythonPackageComponents.of( ImmutableMap.<Path, SourcePath>builder() .put(getTestModulesListName(), testModulesBuildRule.getSourcePathToOutput()) .put(getTestMainName(), requireTestMain(buildTarget, projectFilesystem, graphBuilder)) .putAll(srcs).build(), resources, ImmutableMap.of(), ImmutableMultimap.of(), args.getZipSafe()); ImmutableList<BuildRule> deps = RichStream .from(PythonUtil.getDeps(pythonPlatform, cxxPlatform, args.getDeps(), args.getPlatformDeps())) .concat(args.getNeededCoverage().stream().map(NeededCoverageSpec::getBuildTarget)) .map(graphBuilder::getRule).collect(ImmutableList.toImmutableList()); CellPathResolver cellRoots = context.getCellPathResolver(); StringWithMacrosConverter macrosConverter = StringWithMacrosConverter.builder().setBuildTarget(buildTarget) .setCellPathResolver(cellRoots).setExpanders(PythonUtil.MACRO_EXPANDERS).build(); PythonPackageComponents allComponents = PythonUtil.getAllComponents(cellRoots, buildTarget, projectFilesystem, params, graphBuilder, ruleFinder, deps, testComponents, pythonPlatform, cxxBuckConfig, cxxPlatform, args.getLinkerFlags().stream().map(x -> macrosConverter.convert(x, graphBuilder)) .collect(ImmutableList.toImmutableList()), pythonBuckConfig.getNativeLinkStrategy(), args.getPreloadDeps()); // Build the PEX using a python binary rule with the minimum dependencies. buildTarget.assertUnflavored(); PythonBinary binary = binaryDescription.createPackageRule(buildTarget.withAppendedFlavors(BINARY_FLAVOR), projectFilesystem, params, graphBuilder, ruleFinder, pythonPlatform, cxxPlatform, mainModule, args.getExtension(), allComponents, args.getBuildArgs(), args.getPackageStyle().orElse(pythonBuckConfig.getPackageStyle()), PythonUtil.getPreloadNames(graphBuilder, cxxPlatform, args.getPreloadDeps())); graphBuilder.addToIndex(binary); ImmutableList.Builder<Pair<Float, ImmutableSet<Path>>> neededCoverageBuilder = ImmutableList.builder(); for (NeededCoverageSpec coverageSpec : args.getNeededCoverage()) { BuildRule buildRule = graphBuilder.getRule(coverageSpec.getBuildTarget()); if (deps.contains(buildRule) && buildRule instanceof PythonLibrary) { PythonLibrary pythonLibrary = (PythonLibrary) buildRule; ImmutableSortedSet<Path> paths; if (coverageSpec.getPathName().isPresent()) { Path path = coverageSpec.getBuildTarget().getBasePath() .resolve(coverageSpec.getPathName().get()); if (!pythonLibrary.getPythonPackageComponents(pythonPlatform, cxxPlatform, graphBuilder) .getModules().keySet().contains(path)) { throw new HumanReadableException( "%s: path %s specified in needed_coverage not found in target %s", buildTarget, path, buildRule.getBuildTarget()); } paths = ImmutableSortedSet.of(path); } else { paths = ImmutableSortedSet.copyOf( pythonLibrary.getPythonPackageComponents(pythonPlatform, cxxPlatform, graphBuilder) .getModules().keySet()); } neededCoverageBuilder .add(new Pair<>(coverageSpec.getNeededCoverageRatioPercentage() / 100.f, paths)); } else { throw new HumanReadableException( "%s: needed_coverage requires a python library dependency. Found %s instead", buildTarget, buildRule); } } Function<BuildRuleResolver, ImmutableMap<String, Arg>> testEnv = (ruleResolverInner) -> ImmutableMap .copyOf(Maps.transformValues(args.getEnv(), x -> macrosConverter.convert(x, graphBuilder))); // Additional CXX Targets used to generate CXX coverage. ImmutableSet<UnflavoredBuildTarget> additionalCoverageTargets = RichStream .from(args.getAdditionalCoverageTargets()).map(target -> target.getUnflavoredBuildTarget()) .collect(ImmutableSet.toImmutableSet()); ImmutableSortedSet<SourcePath> additionalCoverageSourcePaths = additionalCoverageTargets.isEmpty() ? ImmutableSortedSet.of() : binary.getRuntimeDeps(ruleFinder) .filter(target -> additionalCoverageTargets.contains(target.getUnflavoredBuildTarget())) .map(target -> DefaultBuildTargetSourcePath.of(target)) .collect(ImmutableSortedSet.toImmutableSortedSet(Ordering.natural())); // Generate and return the python test rule, which depends on the python binary rule above. return PythonTest.from(buildTarget, projectFilesystem, params, graphBuilder, testEnv, binary, args.getLabels(), neededCoverageBuilder.build(), additionalCoverageSourcePaths, args.getTestRuleTimeoutMs().map(Optional::of).orElse( cxxBuckConfig.getDelegate().getView(TestBuckConfig.class).getDefaultTestRuleTimeoutMs()), args.getContacts()); }