sbt / sbt

sbt, the interactive build tool
https://scala-sbt.org
Apache License 2.0
4.79k stars 935 forks source link

read-only def projects: Seq[Project] or scopefilter available in build.sbt #3030

Open eed3si9n opened 7 years ago

eed3si9n commented 7 years ago

steps

  1. Migrate from Build.scala

problem

There's no way to aggregate all projects automatically.

expectation

Either read-only def projects or let me use ScopeFilter.

dwijnand commented 7 years ago

Cross-linking: @Duhemm tried to implement this in #2183.

eed3si9n commented 7 years ago

Here's a workaround.

project/Root.scala

import sbt._

object Root {
  def rootProject: Project = Project("root", file("."), aggregate = nonRoots)

  def nonRoots: List[ProjectReference] =
    projectsFix filter {
      case LocalProject(p) => p != "root"
      case _               => false
    }

  def projectsFix: List[ProjectReference] =
    ReflectUtilities.allVals[Project](this).values.toList map { p =>
      p: ProjectReference
    }
}

usage

import Root._

lazy val root = rootProject
  .settings(
    organization in ThisBuild := "com.example",
    scalaVersion in ThisBuild := "2.12.1",
    version      in ThisBuild := "0.1.0-SNAPSHOT",
    name := "root_name"
  )

lazy val app1 = (project in file("app1"))
  .settings(
    name := "app1"
  )

lazy val app2 = (project in file("app2"))
  .settings(
    name := "app2"
  )
jvican commented 7 years ago

I would suggest to add a new optional parameter to project called root and force users to do root = true from now on to any project that is supposed to be a root. I think we could have a better solution than exposing yet another project constructor called rootProject :wink:.

Then, I would hide completely those utils to get the projects reflectively, and even cache them. It does not seem a cheap operation.

dwijnand commented 7 years ago

More cross-linking (:D) there's a feature request from @cunei for explicit indication of which project is the root/default project: https://github.com/sbt/sbt/issues/2789.