softprops / coffeescripted-sbt

pour some coffee for scala
MIT License
55 stars 5 forks source link

Issue with multi-project build #17

Closed jeffmay closed 11 years ago

jeffmay commented 11 years ago

I asked this as a question on StackOverflow, but I figured I would file an issue here to save you time, and give you another issue for your lonely 3 ticket queue!

http://stackoverflow.com/questions/17289043/use-coffeescripted-sbt-to-compile-coffeescript-in-multi-project-build

Much appreciated for all your work on this!

softprops commented 11 years ago

I appreciate you writing up the steps to reproduce. Ill check this out tonight. I can add a scripted test for this. I can explain some things based on an initial look of your build and questions. show in sbt inspects the output of a given task. The coffee task produces a list of compiled files to add to the target output dir. The empty array buffer you see in the output indicates no files were applicable. The No such setting/task is an error reported by sbt when you type in a setting or task into the project prompt and its not defined in scope. This makes sense as it looks like you've only mixed in the setting into your web module so its not visible to your root project. I'm not sure how your root project is defined but that could be a clue. I'll follow up on this tonight.

jeffmay commented 11 years ago

Yea, the No such setting/task part makes sense to me. I don't need coffee script on the api or root module. The root module is just more of a cli for common sbt tasks that aggregates the other projects.

import coffeescript.Plugin.coffeeSettings
import sbt._

object RootModule extends BaseModule {

  val moduleName = "root"

  val location = "."

  val moduleVersion = "0.1"

  val libraries = Seq()

  lazy val project = baseProject

  def settings = coffeeSettings

  override def baseProject = play.Project(moduleName, moduleVersion, libraries, file(location), moduleSettings)
    .aggregate(
      ApiModule.project
    )

}

BaseModule isn't really adding anything here, it just defines the contract for module name, version, etc and adds settings to the Default.settings.

import sbt._
import Keys._

trait BaseModule {
  def moduleName: String
  def location: String

  lazy val moduleSettings = baseSettings ++ settings

  def settings: Seq[Project.Setting[_]]

  lazy val baseSettings =
    MyDefaults.settings ++
    Seq (
      name := moduleName
    ) ++ Seq (
      libraryDependencies ++= libraries
    )

  def libraries: Seq[ModuleID]

  def baseProject = Project(
    id = moduleName,
    base = file(location),
    settings = moduleSettings
  )

  def project: Project

}

I'm not really familiar with how SBT treats multiple projects, but I pretty much copied the angular-seed-play activator project as a sub module and added this plugin. I notice however that in one of them I see:

~/angular-seed-play $ play run
[info] Loading project definition from /Users/jeffmay/angular-seed-play/project
[info] Set current project to angular-seed-play (in build file:/Users/jeffmay/angular-seed-play/)

--- (Running the application from SBT, auto-reloading is enabled) ---

[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

And in my project after I convert my RootModule to have a play.Project (as well as the WebModule project):

~/code/myproject $ play '~web/run'
[info] Loading project definition from /Users/jeffmay/code/righttrack/project
[info] Set current project to root (in build file:/Users/jeffmay/code/righttrack/)
[info] Running play.core.server.NettyServer
Play server process ID is 38597
[info] play - Application started (Prod)
[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

This is a separate issue but it might be related.

In the angular seed play project, any changes to the public directory causes the server to update the resources automatically. This is what I ultimately want to happen when I change a javascript file. That way, I can have either cake building automatically and Play updating the server, or I can have sbt coffee know when any coffee files are updated and trigger a rerun.

I am going to try rebuilding this thing with just a single Play project and see what happens. Thanks for looking into this.

softprops commented 11 years ago

Np. Again, I don't have a scripted test for this but I'm pretty sure the task scope is the problem. I'll do this tonight.

I also noticed this in your root project definition

.aggregate(
      ApiModule.project
    )

This will aggregate tasks to the api module but not the web module, what happens if you also aggregate tasks to the web module?

jeffmay commented 11 years ago

Okay, your suggestion fixed my other issue, but I still don't see anything happen when I run the "coffee" task.

Here is my project:

https://github.com/jeffmay/angular-play-multimodule-seed

softprops commented 11 years ago

Here you go. https://gist.github.com/softprops/5864480

a few notes:

1) coffee is configurable in both it's input and output. You were configuring the output directory. resourceManaged is where sbt copies generated resources ( .js files in the case of coffeescript ). Coffee has defines its own target. You can see this in the console with show coffee::resource-managed. For input sources ( i.e. .coffee files ). use source-directory. You can see what the default is with show coffee::source-directory ( note you can tab complete these any any other settings in sbts console )

2) This is an sbt thing ( not coffeescripted-sbt specific ). When you specify settings, sbt evaluates them in order. The way you had the coffee output directory configured it would have been overrided when you added coffeescriptSettings after. First append coffeesriptSettings ( which provides defaults ). Then redefine settings you want to override

3) There is something special to note here though in your use case in that its a play project ( I'm assuming! ) . It looks like play mangles your settings before they are applied when you use play project, most likely to set up a class path its framework expects ( another reason I hate frameworks! ). Anyway, the issue is that even if you override the sourceDirectory for coffee. Say sourceDirectory for coffee ( see the diff for examples ), Play will rewrite this path to be prefixed with app. I'm not sure if thats a common play thing but I find it a little annoying. To get play to "play nice" here you can just to show coffee::source-directory to find where play forces you to put things and make sure its there. In this case angular-play-multimodule-seed/web/app/coffee That is most likely the fix here.

[web] $ show coffee
[info] ArrayBuffer(/Users/dougtangren/Desktop/tests/angular-play-multimodule-seed/web/target/scala-2.10/resource_managed/main/js/app.js, /Users/dougtangren/Desktop/tests/angular-play-multimodule-seed/web/target/scala-2.10/resource_managed/main/js/controllers.js, /Users/dougtangren/Desktop/tests/angular-play-multimodule-seed/web/target/scala-2.10/resource_managed/main/js/directives.js, /Users/dougtangren/Desktop/tests/angular-play-multimodule-seed/web/target/scala-2.10/resource_managed/main/js/filters.js, /Users/dougtangren/Desktop/tests/angular-play-multimodule-seed/web/target/scala-2.10/resource_managed/main/js/services.js)
[success] Total time: 0 s, completed Jun 25, 2013 11:25:26 PM

[web] $ show coffee::source-directory
[info] /Users/dougtangren/Desktop/tests/angular-play-multimodule-seed/web/app/coffee

[web] $ show coffee::resource-managed
[info] /Users/dougtangren/Desktop/tests/angular-play-multimodule-seed/web/target/scala-2.10/resource_managed/main/js

If that helps you may want to link back here from your stack overflow post for anyone that finds that post, this answer may be useful.

jeffmay commented 11 years ago

This was very useful. Thanks for helping out an SBT n00b.

I figured out how to get the javascipt to compile to the recommended public/js directory for angular. I'll link this to the stack overflow question.

Thanks again!

jeffmay commented 11 years ago

Updated http://stackoverflow.com/questions/17289043/use-coffeescripted-sbt-to-compile-coffeescript-in-multi-project-build

softprops commented 11 years ago

anytime!