Skip to content

Multiple scala version builds within the same bazel run #962

@smparkes

Description

@smparkes

PRs

There are a number of PRs in flight. Because they interact, they're sometimes based on one another so a diff against master will show all changes up to that point. That means it's probably easiest to review from in order.

Core PRs: these are cleanup/refactoring PRs for core that are blockers for multiscala

Multiscala PRs: these actually implement multiscala support. They generally require the PRs above.

tl;dr

I'm creating a new issue for this.

Many exist and I'm happy to close this in favor of another but there are (see below) so many with some amount of overlap and various comment history, personally I prefer to start with a clean slate.

I'm actively working on this.

I'd like to get buy-in early that we want to do this and on my current approach. If there is buy-in, I'd like to get feedback as I go. There are lots of choices and I'd love to get feedback/reviews early so
there's not a lot of rework.

If there's not sufficient consensus, I'm happy to close this (we don't need yet another issue) and I'll do the work independently.

Requirements:

  • Build/test targets against multiple versions of scala in the same bazel invocation
  • Minimal user overhead/incompatibility if they are using a single scala version
  • Maintain current API compatibility
  • Opt-in until stable

Stretch goals:

  • Don't require users to enumerate, manually or with starlark, targets, e.g., one scala_library call will, by default, build (suffixed) targets (optional alias for default scala version)
  • Some support for 2.13, e.g., support version-specific source code variants

Key implementation choices

  • Use configured toolchains rather than label dependencies
  • Shared configuration available at loading phase via a repository constructed via a repository rule

Dev Approach:

  • Small, incremental PRs including the fewest changes as long as possible. None break tests.

Example:

  • Will be in unstable/multiscala/private/example

Related Issues

It's hoped that these issues are likely to be addressed, completely or in majority, in this work.

#14: Support different versions of scala
#80: Cross building
#147: repeating downloads of scala library
#173: How to make rules_scala use scala-2.10?
#250: enable_dependency_analyzer attr is a feature toggle that needs to be removed at an opportune time
#252: use new inliner flag in 2.12.3
#263: Reasonable scala
#275: scalatest 3.x.x support?
#302: 'io_bazel_rules_scala/dependency/thrift/scrooge_core' not declared in package 'external'
#393: Project with multiple scala versions
#400: create a scala_test toolchain
#401: create a specs2 toolchain
#402: create a scrooge toolchain
#403: create a scala protobuf toolchain
#432: Insulate toolchain options from breaking rules_scala bootstrap code
#546: scala_maven_import_external and scala_version
#679: Dependency checkers do not detect scala macro dependencies
#703: Default Scala version should be 2.12 (instead of 2.11)
#713: Upstream toolchain fixes mean we can remove some crud around the scalac provider
#768: no matching toolchains found for types @io_bazel_rules_scala//scala_proto:toolchain_type
#809: Support Scala 2.13
#940: Tracking issue- move from deps to toolchains

Status

I've done a good portion of this work once but wasn't happy with the result. Among other things, it wasn't sufficiently "opt-in". I'm planning on taking a more incremental approach and focus on making all the extensions opt-in to start. Also want to get feedback on choices early on.

FAQ

Why not wait/use bazel platforms/toolchains/transisions?

The fundamental toolchain work is entirely usable. There may be some issues with toolchain resolution but they can be worked around.

The bazel concepts that potentially overlap with this are platforms and transitions. There are at least af few broad issues: time, fit and functionality.

Time: That work is not complete and looks to be pretty early, still. It's been on the roadmap for a while but there are lots of open issues. For example, AFAICT, they haven't resolved how file paths are going to be handled. I suspect this work is going to take a fair amount of time and my team can't wait. The current approach should not conflict with any of that work. Migration to that work when it's complete remains to be clarified (next).

Fit: It's not really possible to judge how that work is going to fit this use case since so much is yet to be defined. Most of the relevant work in that effort is around different target platforms but scala versions are not exactly different target platforms: from a bazel perspective, our platform is the jvm, not the scala runtime. I haven't seen any examples extending platforms in bazel that match the scala use case.

Functionality: it's not actually clear how we would use this support for scala versions. Transitions in bazel are applied at the rule level, so it's unclear how we would use them when we generally want to vary the version on the target level. It's not clear how to map the scala pattern of version suffixes in artifact names would work with the work going on in bazel.

rules_jvm_external?

This is obviously debatable. We use rules_jvm_external extensively, including artifact pinning. This has been very useful in tracking common dependence versions and noting conflicts. I'm sort of hoping we can standardize on this but I'm not sure what open issues may exist.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions