Skip to content

Commit

Permalink
Introduce package_name() function to replace the magic PACKAGE_NAME c…
Browse files Browse the repository at this point in the history
…onstant.

Also, repository_name() replaces REPOSITORY_NAME.
In .bzl files, they are prefixed with "native.".

RELNOTES: None.
PiperOrigin-RevId: 155102221
  • Loading branch information
laurentlb authored and damienmg committed May 4, 2017
1 parent 54c3cbe commit ba51cda
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,47 @@ static Runtime.NoneType callExportsFiles(Object srcs, Object visibilityO, Object
return Runtime.NONE;
}

@SkylarkSignature(
name = "package_name",
objectType = SkylarkNativeModule.class,
returnType = String.class,
doc =
"The name of the package being evaluated. "
+ "For example, in the BUILD file <code>some/package/BUILD</code>, its value "
+ "will be <code>some/package</code>. "
+ "If the BUILD file calls a function defined in a .bzl file, "
+ "<code>package_name()</code> will match the caller BUILD file package. "
+ "This function is equivalent to the deprecated variable <code>PACKAGE_NAME</code>.",
parameters = {},
useEnvironment = true
)
private static final BuiltinFunction packageNameFunction =
new BuiltinFunction("package_name") {
public String invoke(Environment env) throws EvalException {
return (String) env.lookup("PACKAGE_NAME");
}
};

@SkylarkSignature(
name = "repository_name",
objectType = SkylarkNativeModule.class,
returnType = String.class,
doc =
"The name of the repository the rule or build extension is called from. "
+ "For example, in packages that are called into existence by the WORKSPACE stanza "
+ "<code>local_repository(name='local', path=...)</code> it will be set to "
+ "<code>@local</code>. In packages in the main repository, it will be empty. This "
+ "function is equivalent to the deprecated variable <code>REPOSITORY_NAME</code>.",
parameters = {},
useEnvironment = true
)
private static final BuiltinFunction repositoryNameFunction =
new BuiltinFunction("repository_name") {
public String invoke(Environment env) throws EvalException, ConversionException {
return (String) env.lookup("REPOSITORY_NAME");
}
};

/**
* Returns a function-value implementing "licenses" in the specified package
* context.
Expand Down Expand Up @@ -1601,6 +1642,8 @@ private void buildPkgEnv(
.setup("exports_files", newExportsFilesFunction.apply())
.setup("package_group", newPackageGroupFunction.apply())
.setup("package", newPackageFunction(packageArguments))
.setup("package_name", packageNameFunction)
.setup("repository_name", repositoryNameFunction)
.setup("environment_group", newEnvironmentGroupFunction.apply(context));

for (String ruleClass : ruleFactory.getRuleClassNames()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.syntax.Type.ConversionException;

/** A class for the Skylark native module. */
/**
* A class for the Skylark native module. TODO(laurentlb): Some definitions are duplicated from
* PackageFactory.
*/
@SkylarkModule(
name = "native",
namespace = true,
Expand Down Expand Up @@ -195,6 +198,47 @@ public Runtime.NoneType invoke(SkylarkList srcs, Object visibility, Object licen
}
};

@SkylarkSignature(
name = "package_name",
objectType = SkylarkNativeModule.class,
returnType = String.class,
doc =
"The name of the package being evaluated. "
+ "For example, in the BUILD file <code>some/package/BUILD</code>, its value "
+ "will be <code>some/package</code>. "
+ "If the BUILD file calls a function defined in a .bzl file, "
+ "<code>package_name()</code> will match the caller BUILD file package. "
+ "This function is equivalent to the deprecated variable <code>PACKAGE_NAME</code>.",
parameters = {},
useEnvironment = true
)
private static final BuiltinFunction packageName =
new BuiltinFunction("package_name") {
public String invoke(Environment env) throws EvalException, ConversionException {
return (String) env.lookup("PACKAGE_NAME");
}
};

@SkylarkSignature(
name = "repository_name",
objectType = SkylarkNativeModule.class,
returnType = String.class,
doc =
"The name of the repository the rule or build extension is called from. "
+ "For example, in packages that are called into existence by the WORKSPACE stanza "
+ "<code>local_repository(name='local', path=...)</code> it will be set to "
+ "<code>@local</code>. In packages in the main repository, it will be empty. This "
+ "function is equivalent to the deprecated variable <code>REPOSITORY_NAME</code>.",
parameters = {},
useEnvironment = true
)
private static final BuiltinFunction repositoryName =
new BuiltinFunction("repository_name") {
public String invoke(Environment env) throws EvalException, ConversionException {
return (String) env.lookup("REPOSITORY_NAME");
}
};

public static final SkylarkNativeModule NATIVE_MODULE = new SkylarkNativeModule();

static {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,18 @@ public void testPackageConstant() throws Exception {
assertSame(1, Sets.newHashSet(pkg.getTargets(Rule.class)).size());
}

@Test
public void testPackageNameFunction() throws Exception {
Path buildFile = scratch.file("/pina/BUILD", "cc_library(name=package_name() + '-colada')");

Package pkg = packages.createPackage("pina", buildFile);
events.assertNoWarningsOrErrors();
assertFalse(pkg.containsErrors());
assertNotNull(pkg.getRule("pina-colada"));
assertFalse(pkg.getRule("pina-colada").containsErrors());
assertSame(1, Sets.newHashSet(pkg.getTargets(Rule.class)).size());
}

@Test
public void testPackageConstantInExternalRepository() throws Exception {
Path buildFile =
Expand All @@ -264,6 +276,19 @@ public void testPackageConstantInExternalRepository() throws Exception {
assertThat(AggregatingAttributeMapper.of(c).get("cmd", Type.STRING)).isEqualTo("@a b");
}

@Test
public void testPackageFunctionInExternalRepository() throws Exception {
Path buildFile =
scratch.file(
"/external/a/b/BUILD",
"genrule(name='c', srcs=[], outs=['o'], cmd=repository_name() + ' ' + package_name())");
Package pkg =
packages.createPackage(
PackageIdentifier.create("@a", PathFragment.create("b")), buildFile, events.reporter());
Rule c = pkg.getRule("c");
assertThat(AggregatingAttributeMapper.of(c).get("cmd", Type.STRING)).isEqualTo("@a b");
}

@Test
public void testMultipleDuplicateRuleName() throws Exception {
events.setFailFast(false);
Expand Down

0 comments on commit ba51cda

Please sign in to comment.