Skip to content

Commit

Permalink
python: allow setting default python home via parameter
Browse files Browse the repository at this point in the history
Summary:
Generally, users write python binaries/tests which either work with
python2 or python3.  This diff allows pinning python rules to a default
python platform via a `python_platform` parameter.

Test Plan:
- added tests
- loaded docs locally in browser
  • Loading branch information
andrewjcg authored and sdwilsh committed Oct 2, 2015
1 parent efaf4a5 commit 65b7ac1
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 169 deletions.
11 changes: 11 additions & 0 deletions docs/__python_common.soy
Expand Up @@ -63,3 +63,14 @@
{/param}
{/call}
{/template}

/***/
{template .platform_arg}
{call buck.arg}
{param name : 'platform' /}
{param default : 'None' /}
{param desc}
The name of the Python platform to build against by default (as defined in the `python#name` section of `.buckconfig`).
{/param}
{/call}
{/template}
23 changes: 23 additions & 0 deletions docs/rule/python_binary.soy
Expand Up @@ -46,6 +46,8 @@ from all transitive {call buck.python_library /} dependencies.
{/param}
{/call}

{call python_common.platform_arg /}

{call buck.arg}
{param name: 'deps' /}
{param default : '[]' /}
Expand Down Expand Up @@ -74,6 +76,27 @@ python_library(
srcs = glob(['*.py'], excludes = ['tailer.py']),
)
</pre>{/literal}
<p>
Here is an example of using the `platform` parameter to select the "py2"
Python platform as defined in `.buckconfig`:
</p>
{literal}<pre class="prettyprint lang-ini">
; .buckconfig
[python#py2]
interpreter = /usr/bin/python2.7
</pre>{/literal}

{literal}<pre class="prettyprint lang-py">
# BUCK
python_binary(
name = 'bin',
platform = 'py2',
deps = [
':bar',
],
)
</pre>{/literal}

{/param}

{/call} // close buck.rule
Expand Down
16 changes: 16 additions & 0 deletions docs/rule/python_test.soy
Expand Up @@ -37,6 +37,8 @@ files that contain tests to run via the <a href="https://docs.python.org/2/libra

{call python_common.base_module_arg /}

{call python_common.platform_arg /}

{call buck.arg}
{param name: 'env' /}
{{param default : '{}' /}}
Expand Down Expand Up @@ -143,6 +145,20 @@ python_test(
],
)
</pre>{/literal}
<p>
Here is an example of using the `platform` parameter to select the "py2"
Python platform as defined in `.buckconfig` above:
</p>
{literal}<pre class="prettyprint lang-py">
# BUCK
python_test(
name = 'bin',
platform = 'py2',
srcs = [
'foo.py',
],
)
</pre>{/literal}
{/param}

{/call} // close buck.rule
Expand Down
9 changes: 9 additions & 0 deletions src/com/facebook/buck/model/Flavor.java
Expand Up @@ -16,6 +16,7 @@

package com.facebook.buck.model;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;

import org.immutables.value.Value;
Expand All @@ -27,6 +28,14 @@ public abstract class Flavor implements Comparable<Flavor> {

private static final Pattern INVALID_FLAVOR_CHARACTERS = Pattern.compile("[^-a-zA-Z0-9_\\.]");

public static final Function<String, Flavor> TO_FLAVOR =
new Function<String, Flavor>() {
@Override
public Flavor apply(String input) {
return ImmutableFlavor.of(input);
}
};

public static String replaceInvalidCharacters(String name) {
return INVALID_FLAVOR_CHARACTERS.matcher(name).replaceAll("_");
}
Expand Down
8 changes: 8 additions & 0 deletions src/com/facebook/buck/python/PythonBinary.java
Expand Up @@ -24,19 +24,27 @@

public abstract class PythonBinary extends AbstractBuildRule implements BinaryBuildRule {

private final PythonPlatform pythonPlatform;
private final String mainModule;
private final PythonPackageComponents components;

public PythonBinary(
BuildRuleParams buildRuleParams,
SourcePathResolver resolver,
PythonPlatform pythonPlatform,
String mainModule,
PythonPackageComponents components) {
super(buildRuleParams, resolver);
this.pythonPlatform = pythonPlatform;
this.mainModule = mainModule;
this.components = components;
}

@VisibleForTesting
protected PythonPlatform getPythonPlatform() {
return pythonPlatform;
}

@VisibleForTesting
protected String getMainModule() {
return mainModule;
Expand Down
9 changes: 8 additions & 1 deletion src/com/facebook/buck/python/PythonBinaryDescription.java
Expand Up @@ -22,6 +22,7 @@
import com.facebook.buck.log.Logger;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargets;
import com.facebook.buck.model.Flavor;
import com.facebook.buck.model.FlavorDomain;
import com.facebook.buck.model.FlavorDomainException;
import com.facebook.buck.model.ImmutableFlavor;
Expand Down Expand Up @@ -232,6 +233,7 @@ private PythonInPlaceBinary createInPlaceBinaryRule(
return new PythonInPlaceBinary(
params,
pathResolver,
pythonPlatform,
script,
linkTree,
mainModule,
Expand Down Expand Up @@ -269,6 +271,7 @@ protected PythonBinary createPackageRule(
Suppliers.ofInstance(componentDeps),
Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of())),
pathResolver,
pythonPlatform,
pythonBuckConfig.getPexTool(resolver),
buildArgs,
pythonBuckConfig.getPathToPexExecuter(),
Expand Down Expand Up @@ -302,7 +305,10 @@ public <A extends Arg> PythonBinary createBuildRule(
try {
pythonPlatform = pythonPlatforms
.getValue(params.getBuildTarget().getFlavors())
.or(pythonPlatforms.getValues().asList().get(0));
.or(pythonPlatforms.getValue(
args.platform
.transform(Flavor.TO_FLAVOR)
.or(pythonPlatforms.getFlavors().iterator().next())));
} catch (FlavorDomainException e) {
throw new HumanReadableException("%s: %s", params.getBuildTarget(), e.getMessage());
}
Expand Down Expand Up @@ -377,6 +383,7 @@ public static class Arg {
public Optional<String> baseModule;
public Optional<Boolean> zipSafe;
public Optional<ImmutableList<String>> buildArgs;
public Optional<String> platform;
}

}
3 changes: 2 additions & 1 deletion src/com/facebook/buck/python/PythonInPlaceBinary.java
Expand Up @@ -56,12 +56,13 @@ public class PythonInPlaceBinary extends PythonBinary implements HasRuntimeDeps
public PythonInPlaceBinary(
BuildRuleParams params,
SourcePathResolver resolver,
PythonPlatform pythonPlatform,
WriteFile script,
SymlinkTree linkTree,
String mainModule,
PythonPackageComponents components,
Path python) {
super(params, resolver, mainModule, components);
super(params, resolver, pythonPlatform, mainModule, components);
this.script = script;
this.linkTree = linkTree;
this.components = components;
Expand Down
3 changes: 2 additions & 1 deletion src/com/facebook/buck/python/PythonPackagedBinary.java
Expand Up @@ -62,6 +62,7 @@ public class PythonPackagedBinary extends PythonBinary implements HasRuntimeDeps
protected PythonPackagedBinary(
BuildRuleParams params,
SourcePathResolver resolver,
PythonPlatform pythonPlatform,
Tool builder,
ImmutableList<String> buildArgs,
Path pathToPexExecuter,
Expand All @@ -70,7 +71,7 @@ protected PythonPackagedBinary(
String mainModule,
PythonPackageComponents components,
ImmutableSortedSet<BuildRule> runtimeDeps) {
super(params, resolver, mainModule, components);
super(params, resolver, pythonPlatform, mainModule, components);
this.builder = builder;
this.buildArgs = buildArgs;
this.pathToPexExecuter = pathToPexExecuter;
Expand Down
6 changes: 5 additions & 1 deletion src/com/facebook/buck/python/PythonTestDescription.java
Expand Up @@ -171,7 +171,10 @@ public <A extends Arg> PythonTest createBuildRule(
try {
pythonPlatform = pythonPlatforms
.getValue(params.getBuildTarget().getFlavors())
.or(pythonPlatforms.getValues().asList().get(0));
.or(pythonPlatforms.getValue(
args.platform
.transform(Flavor.TO_FLAVOR)
.or(pythonPlatforms.getFlavors().iterator().next())));
} catch (FlavorDomainException e) {
throw new HumanReadableException("%s: %s", params.getBuildTarget(), e.getMessage());
}
Expand Down Expand Up @@ -326,6 +329,7 @@ public static class Arg extends PythonLibraryDescription.Arg implements HasSourc
public Optional<ImmutableSet<String>> contacts;
public Optional<ImmutableSet<Label>> labels;
public Optional<ImmutableSortedSet<BuildTarget>> sourceUnderTest;
public Optional<String> platform;

public Optional<ImmutableList<String>> buildArgs;

Expand Down
8 changes: 8 additions & 0 deletions test/com/facebook/buck/cxx/CxxPlatformUtils.java
Expand Up @@ -16,8 +16,10 @@

package com.facebook.buck.cxx;

import com.facebook.buck.model.FlavorDomain;
import com.facebook.buck.model.ImmutableFlavor;
import com.facebook.buck.rules.HashedFileTool;
import com.google.common.collect.ImmutableMap;

import java.nio.file.Paths;

Expand All @@ -41,4 +43,10 @@ private CxxPlatformUtils() {}
.setDebugPathSanitizer(CxxPlatforms.DEFAULT_DEBUG_PATH_SANITIZER)
.build();

public static final FlavorDomain<CxxPlatform> DEFAULT_PLATFORMS =
new FlavorDomain<>(
"C/C++ Platform",
ImmutableMap.of(
DEFAULT_PLATFORM.getFlavor(), DEFAULT_PLATFORM));

}
30 changes: 21 additions & 9 deletions test/com/facebook/buck/python/PythonBinaryBuilder.java
Expand Up @@ -23,14 +23,14 @@
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.FlavorDomain;
import com.facebook.buck.rules.AbstractNodeBuilder;
import com.facebook.buck.rules.SourcePath;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;

public class PythonBinaryBuilder extends AbstractNodeBuilder<PythonBinaryDescription.Arg> {

private PythonBinaryBuilder(
public PythonBinaryBuilder(
BuildTarget target,
PythonBuckConfig pythonBuckConfig,
FlavorDomain<PythonPlatform> pythonPlatforms,
Expand All @@ -45,26 +45,33 @@ private PythonBinaryBuilder(
target);
}

public static PythonBinaryBuilder create(BuildTarget target) {
public static PythonBinaryBuilder create(
BuildTarget target,
FlavorDomain<PythonPlatform> pythonPlatforms) {
PythonBuckConfig pythonBuckConfig =
new PythonBuckConfig(new FakeBuckConfig(), new ExecutableFinder());
return new PythonBinaryBuilder(
target,
pythonBuckConfig,
PythonTestUtils.PYTHON_PLATFORMS,
pythonPlatforms,
CxxPlatformUtils.DEFAULT_PLATFORM,
new FlavorDomain<>(
"C/C++ Platform",
ImmutableMap.of(
CxxPlatformUtils.DEFAULT_PLATFORM.getFlavor(),
CxxPlatformUtils.DEFAULT_PLATFORM)));
CxxPlatformUtils.DEFAULT_PLATFORMS);
}

public static PythonBinaryBuilder create(BuildTarget target) {
return create(target, PythonTestUtils.PYTHON_PLATFORMS);
}

public PythonBinaryBuilder setMainModule(String mainModule) {
arg.mainModule = Optional.of(mainModule);
return this;
}

public PythonBinaryBuilder setMain(SourcePath main) {
arg.main = Optional.of(main);
return this;
}

public PythonBinaryBuilder setBaseModule(String baseModule) {
arg.baseModule = Optional.of(baseModule);
return this;
Expand All @@ -85,4 +92,9 @@ public PythonBinaryBuilder setDeps(ImmutableSortedSet<BuildTarget> deps) {
return this;
}

public PythonBinaryBuilder setPlatform(String platform) {
arg.platform = Optional.of(platform);
return this;
}

}

0 comments on commit 65b7ac1

Please sign in to comment.