Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Bug fix to handle export dependencies file path correctly.

### Version 0.53.3
* Add configuration cleanCacheDir to conditionally delete the cache directory or
* Add configuration cleanCacheDir to conditionally delete the cache directory or
just the existing dependency rules files

### Version 0.54.0
Expand All @@ -27,3 +27,16 @@

### Version 0.54.4
* Added support for using Android Lint 31.3+

### Version 0.54.5
* Added `labelsMap` configuration to `externalDependencies` block for adding custom labels to prebuilt dependency rules
* Migrated Robolectric's deprecated code to recommended alternatives:
- Added `:libraries:robolectric-base` to Gradle modules
- Added missing jUnit dependency to robolectric-base
- Replaced deprecated `getAppManifest()` with `getManifestFactory()` and created `BuckManifestFactory`
* Updated GitHub Actions workflows:
- Updated runner image to `ubuntu-24.04` (ubuntu-20.04 is deprecated)
- Updated `actions/checkout` to v4
- Updated `actions/setup-java` to v4 with temurin distribution
- Removed rxPermissions and XLog dependencies
- Updated to Python 3.8
16 changes: 15 additions & 1 deletion Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,20 @@ okbuck {
experimental {
transform = true
}

externalDependencies {
cache = "3rdparty/jvm"
cleanCacheDir = true
labelsMap = [
"com.example:library:1.0.0": [
"category=utility",
"license=apache-2.0"
],
"junit:junit:4.13.2": [
"category=testing",
"test_framework=true"
]
]
}
}

Expand All @@ -85,6 +95,10 @@ please read the [Exopackage wiki](https://github.com/uber/okbuck/wiki/Exopackage
+ `extraBuckOpts` provides a hook to add additional configuration options for buck [android_binary](https://buckbuild.com/rule/android_binary.html) rules
+ `wrapper` is used to configure creation of the buck wrapper script.
- `repo` - The git url of any custom buck fork. Default is none.
+ `externalDependencies` block configures external dependency resolution and generation:
+ - `cache` - Specifies the folder where external dependency rules are generated. Default is `.okbuck/ext`
+ - `cleanCacheDir` - Whether to delete the cache directory before generating dependency rules. Default is `true`
+ - `labelsMap` - Map of dependency coordinates to labels for prebuilt rules. Keys are Maven coordinates in format `"groupId:artifactId:version"`, values are lists of arbitrary strings. An example usecase could be to tag all test dependencies to easily be able to query them.
+ The keys used to configure various options can be for
- All buildTypes and flavors i.e `app`
- All buildTypes of a particular flavor i.e 'appDemo'
Expand Down
11 changes: 11 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,17 @@ okbuck {
"autoValueGson",
"autoValueParcel",
]
// Example: Add labels for specific dependencies
labelsMap = [
"com.example:library:1.0.0": [
"category=utility",
"license=apache-2.0"
],
"junit:junit:4.13.2": [
"category=testing",
"test_framework=true"
]
]
}

dependencies {
Expand Down
3 changes: 3 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ dependencies {
annotationProcessor deps.apt.autoValue
annotationProcessor deps.build.nullaway

testAnnotationProcessor deps.build.nullaway

errorprone deps.build.erroproneCompiler
errorproneJavac deps.build.errorproneJavac

Expand All @@ -60,6 +62,7 @@ dependencies {
implementation deps.external.gson

testImplementation deps.test.junit
testImplementation deps.test.mockito
}

rocker {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,39 @@
import com.uber.okbuck.template.core.Rule;
import com.uber.okbuck.template.java.Prebuilt;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

public class PrebuiltRuleComposer extends JvmBuckRuleComposer {

private PrebuiltRuleComposer() {}

// Visibile for testing
static ImmutableSet<String> getLabels(OExternalDependency dependency, @Nullable Map<String, List<String>> labelsMap) {
List<String> labels = (labelsMap == null)
? Collections.emptyList()
: labelsMap.getOrDefault(dependency.getMavenCoordsForValidation(), Collections.emptyList());

return labels == null ? ImmutableSet.of() : ImmutableSet.copyOf(labels);
}

/**
* @param dependencies External Dependencies whose rule needs to be created
* @return List of rules
*/
@SuppressWarnings("NullAway")
public static List<Rule> compose(
Collection<OExternalDependency> dependencies, HashMap<String, String> shaSum256) {
return compose(dependencies, shaSum256, null);
}

public static List<Rule> compose(
Collection<OExternalDependency> dependencies, HashMap<String, String> shaSum256, Map<String, List<String>> labelsMap) {
return dependencies
.stream()
.peek(
Expand Down Expand Up @@ -58,6 +76,8 @@ public static List<Rule> compose(
rule.sourcesSha256(sourcesSha256);
});

rule.labels(getLabels(dependency, labelsMap));

rule.ruleType(RuleType.PREBUILT.getBuckName())
.deps(external(dependency.getDeps()))
.name(dependency.getTargetName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,11 @@ private void processDependencies(

ImmutableList.Builder<Rule> rulesBuilder = ImmutableList.builder();
rulesBuilder.addAll(LocalPrebuiltRuleComposer.compose(localPrebuiltDependencies.build()));

Map<String, List<String>> labelsMap = externalDependenciesExtension.getLabelsMap();

rulesBuilder.addAll(
PrebuiltRuleComposer.compose(prebuiltDependencies.build(), sha256Cache));
PrebuiltRuleComposer.compose(prebuiltDependencies.build(), sha256Cache, labelsMap));
rulesBuilder.addAll(
HttpFileRuleComposer.compose(httpFileDependencies.build(), sha256Cache));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ public class ExternalDependenciesExtension {
/** Set the path to the sha256sum caches of external dependency artifacts */
@Input private String sha256Cache = OkBuckGradlePlugin.DEFAULT_OKBUCK_SHA256;

/** Map of dependency coordinates to labels for prebuilt rules */
@Input private Map<String, List<String>> labelsMap = new HashMap<>();

@Nullable private Set<VersionlessDependency> allowAllVersionsSet;

public ExternalDependenciesExtension() {}
Expand Down Expand Up @@ -183,4 +186,8 @@ public String getSha256Cache() {
public boolean shouldCleanCacheDir() {
return cleanCacheDir;
}

public Map<String, List<String>> getLabelsMap() {
return labelsMap;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def @(okbuckPrebuiltRule)(
deps = None,
enable_jetifier = False,
first_level = False,
testonly = False):
testonly = False,
labels = None):
if deps == None:
deps = []

Expand Down Expand Up @@ -64,6 +65,7 @@ def @(okbuckPrebuiltRule)(
deps = deps,
visibility = visibility,
enable_jetifier = enable_jetifier,
labels = labels,
)
elif prebuilt_type == "jar":
@(prebuiltJarRule)(
Expand All @@ -74,6 +76,7 @@ def @(okbuckPrebuiltRule)(
deps = deps,
visibility = visibility,
enable_jetifier = enable_jetifier,
labels = labels,
)
else:
fail("okbuck_prebuilt not supported for type {}".format(prebuilt_type))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ boolean firstLevel,
}
@if (firstLevel) {
first_level = True,
}
@if (valid(labels)) {
labels = [
@for (label : sorted(labels)) {
"@label",
}
],
}
maven_coords = "@mavenCoords",
sha256 = "@sha256",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package com.uber.okbuck.composer.java;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.uber.okbuck.core.dependency.OExternalDependency;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;

public class PrebuiltRuleComposerTest {

@Test
public void getLabels_withValidLabelsMap_returnsLabels() {
// Arrange
OExternalDependency dependency = mock(OExternalDependency.class);
Map<String, List<String>> labelsMap = new HashMap<>();
List<String> expectedLabels = new ArrayList<>();
expectedLabels.add("test_label=value1,value2");
labelsMap.put("com.example:test-artifact:1.0.0", expectedLabels);

when(dependency.getMavenCoordsForValidation()).thenReturn("com.example:test-artifact:1.0.0");

// Act
Set<String> result = PrebuiltRuleComposer.getLabels(dependency, labelsMap);

// Assert
assertNotNull(result);
assertEquals(expectedLabels.size(), result.size());
assertTrue(result.contains("test_label=value1,value2"));
}

@Test
public void getLabels_withNullLabelsMap_returnsEmptySet() {
// Arrange
OExternalDependency dependency = mock(OExternalDependency.class);

// Act
Set<String> result = PrebuiltRuleComposer.getLabels(dependency, null);

// Assert
assertNotNull(result);
assertTrue(result.isEmpty());
}

@Test
public void getLabels_withEmptyLabelsMap_returnsEmptySet() {
// Arrange
OExternalDependency dependency = mock(OExternalDependency.class);
Map<String, List<String>> emptyLabelsMap = new HashMap<>();

// Act
Set<String> result = PrebuiltRuleComposer.getLabels(dependency, emptyLabelsMap);

// Assert
assertNotNull(result);
assertTrue(result.isEmpty());
}

@Test
public void getLabels_withMissingKey_returnsEmptySet() {
// Arrange
OExternalDependency dependency = mock(OExternalDependency.class);
Map<String, List<String>> labelsMap = new HashMap<>();
List<String> labels = new ArrayList<>();
labels.add("other_label=other_value");
labelsMap.put("com.other:other-artifact:2.0.0", labels);

when(dependency.getMavenCoordsForValidation()).thenReturn("com.example:test-artifact:1.0.0");

// Act
Set<String> result = PrebuiltRuleComposer.getLabels(dependency, labelsMap);

// Assert
assertNotNull(result);
assertTrue(result.isEmpty());
}

@Test
public void getLabels_withNullValue_returnsEmptySet() {
// Arrange
OExternalDependency dependency = mock(OExternalDependency.class);
Map<String, List<String>> labelsMap = new HashMap<>();
labelsMap.put("com.example:test-artifact:1.0.0", null);

when(dependency.getMavenCoordsForValidation()).thenReturn("com.example:test-artifact:1.0.0");

// Act
Set<String> result = PrebuiltRuleComposer.getLabels(dependency, labelsMap);

// Assert
assertNotNull(result);
assertTrue(result.isEmpty());
}

@Test
public void getLabels_withEmptyValue_returnsEmptySet() {
// Arrange
OExternalDependency dependency = mock(OExternalDependency.class);
Map<String, List<String>> labelsMap = new HashMap<>();
labelsMap.put("com.example:test-artifact:1.0.0", new ArrayList<>());

when(dependency.getMavenCoordsForValidation()).thenReturn("com.example:test-artifact:1.0.0");

// Act
Set<String> result = PrebuiltRuleComposer.getLabels(dependency, labelsMap);

// Assert
assertNotNull(result);
assertTrue(result.isEmpty());
}
}