Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Add python_library -> py_library bp2build support

Bug: 196091681
Test: bp2build/python_library_conversion_test.go
Test: build/bazel/ci/mixed_{libc,droid}.sh
Change-Id: Ice87d75533c97fd9c139dc59de09a039e2713a01
parent 7c16dabf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ bootstrap_go_package {
        "performance_test.go",
        "prebuilt_etc_conversion_test.go",
        "python_binary_conversion_test.go",
        "python_library_conversion_test.go",
        "sh_conversion_test.go",
        "testing.go",
    ],
+134 −0
Original line number Diff line number Diff line
package bp2build

import (
	"testing"

	"android/soong/python"
)

func TestPythonLibrarySimple(t *testing.T) {
	runBp2BuildTestCaseSimple(t, bp2buildTestCase{
		description:                        "simple python_library converts to a native py_library",
		moduleTypeUnderTest:                "python_library",
		moduleTypeUnderTestFactory:         python.PythonLibraryFactory,
		moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build,
		filesystem: map[string]string{
			"a.py":           "",
			"b/c.py":         "",
			"b/d.py":         "",
			"b/e.py":         "",
			"files/data.txt": "",
		},
		blueprint: `python_library {
    name: "foo",
    srcs: ["**/*.py"],
    exclude_srcs: ["b/e.py"],
    data: ["files/data.txt",],
    bazel_module: { bp2build_available: true },
}
`,
		expectedBazelTargets: []string{`py_library(
    name = "foo",
    data = ["files/data.txt"],
    srcs = [
        "a.py",
        "b/c.py",
        "b/d.py",
    ],
    srcs_version = "PY3",
)`,
		},
	})
}

func TestPythonLibraryPy2(t *testing.T) {
	runBp2BuildTestCaseSimple(t, bp2buildTestCase{
		description:                        "py2 python_library",
		moduleTypeUnderTest:                "python_library",
		moduleTypeUnderTestFactory:         python.PythonLibraryFactory,
		moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build,
		blueprint: `python_library {
    name: "foo",
    srcs: ["a.py"],
    version: {
        py2: {
            enabled: true,
        },
        py3: {
            enabled: false,
        },
    },

    bazel_module: { bp2build_available: true },
}
`,
		expectedBazelTargets: []string{`py_library(
    name = "foo",
    srcs = ["a.py"],
    srcs_version = "PY2",
)`,
		},
	})
}

func TestPythonLibraryPy3(t *testing.T) {
	runBp2BuildTestCaseSimple(t, bp2buildTestCase{
		description:                        "py3 python_library",
		moduleTypeUnderTest:                "python_library",
		moduleTypeUnderTestFactory:         python.PythonLibraryFactory,
		moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build,
		blueprint: `python_library {
    name: "foo",
    srcs: ["a.py"],
    version: {
        py2: {
            enabled: false,
        },
        py3: {
            enabled: true,
        },
    },

    bazel_module: { bp2build_available: true },
}
`,
		expectedBazelTargets: []string{
			`py_library(
    name = "foo",
    srcs = ["a.py"],
    srcs_version = "PY3",
)`,
		},
	})
}

func TestPythonLibraryPyBoth(t *testing.T) {
	runBp2BuildTestCaseSimple(t, bp2buildTestCase{
		description:                        "py3 python_library",
		moduleTypeUnderTest:                "python_library",
		moduleTypeUnderTestFactory:         python.PythonLibraryFactory,
		moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build,
		blueprint: `python_library {
    name: "foo",
    srcs: ["a.py"],
    version: {
        py2: {
            enabled: true,
        },
        py3: {
            enabled: true,
        },
    },

    bazel_module: { bp2build_available: true },
}
`,
		expectedBazelTargets: []string{
			// srcs_version is PY2ANDPY3 by default.
			`py_library(
    name = "foo",
    srcs = ["a.py"],
)`,
		},
	})
}
+60 −0
Original line number Diff line number Diff line
@@ -17,11 +17,16 @@ package python
// This file contains the module types for building Python library.

import (
	"fmt"

	"android/soong/android"
	"android/soong/bazel"
	"github.com/google/blueprint/proptools"
)

func init() {
	registerPythonLibraryComponents(android.InitRegistrationContext)
	android.RegisterBp2BuildMutator("python_library", PythonLibraryBp2Build)
}

func registerPythonLibraryComponents(ctx android.RegistrationContext) {
@@ -35,8 +40,63 @@ func PythonLibraryHostFactory() android.Module {
	return module.init()
}

type bazelPythonLibraryAttributes struct {
	Srcs         bazel.LabelListAttribute
	Data         bazel.LabelListAttribute
	Srcs_version string
}

func PythonLibraryBp2Build(ctx android.TopDownMutatorContext) {
	m, ok := ctx.Module().(*Module)
	if !ok || !m.ConvertWithBp2build(ctx) {
		return
	}

	// a Module can be something other than a python_library
	if ctx.ModuleType() != "python_library" {
		return
	}

	// TODO(b/182306917): this doesn't fully handle all nested props versioned
	// by the python version, which would have been handled by the version split
	// mutator. This is sufficient for very simple python_library modules under
	// Bionic.
	py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, true)
	py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false)
	var python_version string
	if py2Enabled && !py3Enabled {
		python_version = "PY2"
	} else if !py2Enabled && py3Enabled {
		python_version = "PY3"
	} else if !py2Enabled && !py3Enabled {
		panic(fmt.Errorf(
			"error for '%s' module: bp2build's python_library converter doesn't understand having "+
				"neither py2 nor py3 enabled", m.Name()))
	} else {
		// do nothing, since python_version defaults to PY2ANDPY3
	}

	srcs := android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
	data := android.BazelLabelForModuleSrc(ctx, m.properties.Data)

	attrs := &bazelPythonLibraryAttributes{
		Srcs:         bazel.MakeLabelListAttribute(srcs),
		Data:         bazel.MakeLabelListAttribute(data),
		Srcs_version: python_version,
	}

	props := bazel.BazelTargetModuleProperties{
		// Use the native py_library rule.
		Rule_class: "py_library",
	}

	ctx.CreateBazelTargetModule(m.Name(), props, attrs)
}

func PythonLibraryFactory() android.Module {
	module := newModule(android.HostAndDeviceSupported, android.MultilibBoth)

	android.InitBazelModule(module)

	return module.init()
}