How to specify the main class (in the root directory) for Mill to run? - scala

I am new to the sbt and mill, and I am practicing to use both tool to build the chisel (scala project). View this github repo as a reference, I am wondering to know how to write the mill-version build.sh in that repo.
Here is my directory structure
─ chisel-template (root directory / projects directory)
├── build.sc
├── build.sh
├── src
| └─main
| └─scala
| └─lab1
| └─Mux2.scala
└── _temphelper.scala
What the build.sh do is preparing a boilerplate as main function in the root directory to make compile and run process much easier, and it's sbt version. I'm curious that why sbt can detect the main function (_temphelper.Elaborate) even it's not in the src/main directory. And when I change to use Mill, Mill can't detect the _temphelper.scala at all, unless I move the file to root/src/main. Is there settings that can make Mill do what sbt can do?
I'm not sure whether this issue is related to...
altering the sourceDirectories in sbt and chiselMoudule.sources in Mill. Any advice is welcome.
modify the millSourcePath to realize my request.
My quetions is What setting should I do to make mill can detect the main class that be in the root directory?

This is because sbt is including any Scala files it finds in the project root directory as sources files, unless told otherwise.
In contrast, Mill will only use the source files found under whatever directories are specified with sources. As a consequence, you may want to add the project root directory as source directory, but I strongly advice to do not so.
Best is to move the _temphelper.scala file either to one of the source directories or create a new dedicated directory, move the file there and add this directory to the sources like this:
object chiselModule extends CrossSbtModule // ...
{
def sources = T.sources {
super.sources() ++ Seq(PathRef(T.workspace / "your" / "new" / "directory"))
}
}

Related

Best practices for Scala physical directory structure [duplicate]

I am learning Scala now and I want to write some silly little app like a console Twitter client, or whatever. The question is, how to structure application on disk and logically. I know python, and there I would just create some files with classes and then import them in the main module like import util.ssh or from tweets import Retweet (strongly hoping you wouldn't mind that names, they are just for reference). But how should I do this stuff using Scala? Also, I have not much experience with JVM and Java, so I am a complete newbie here.
I'm going to disagree with Jens, here, though not all that much.
Project Layout
My own suggestion is that you model your efforts on Maven's standard directory layout.
Previous versions of SBT (before SBT 0.9.x) would create it automatically for you:
dcs#ayanami:~$ mkdir myproject
dcs#ayanami:~$ cd myproject
dcs#ayanami:~/myproject$ sbt
Project does not exist, create new project? (y/N/s) y
Name: myproject
Organization: org.dcsobral
Version [1.0]:
Scala version [2.7.7]: 2.8.1
sbt version [0.7.4]:
Getting Scala 2.7.7 ...
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (9911kB/134ms)
Getting org.scala-tools.sbt sbt_2.7.7 0.7.4 ...
:: retrieving :: org.scala-tools.sbt#boot-app
confs: [default]
15 artifacts copied, 0 already retrieved (4096kB/91ms)
[success] Successfully initialized directory structure.
Getting Scala 2.8.1 ...
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (15118kB/160ms)
[info] Building project myproject 1.0 against Scala 2.8.1
[info] using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7
> quit
[info]
[info] Total session time: 8 s, completed May 6, 2011 12:31:43 PM
[success] Build completed successfully.
dcs#ayanami:~/myproject$ find . -type d -print
.
./project
./project/boot
./project/boot/scala-2.7.7
./project/boot/scala-2.7.7/lib
./project/boot/scala-2.7.7/org.scala-tools.sbt
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4/compiler-interface-bin_2.7.7.final
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4/compiler-interface-src
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4/compiler-interface-bin_2.8.0.RC2
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4/xsbti
./project/boot/scala-2.8.1
./project/boot/scala-2.8.1/lib
./target
./lib
./src
./src/main
./src/main/resources
./src/main/scala
./src/test
./src/test/resources
./src/test/scala
So you'll put your source files inside myproject/src/main/scala, for the main program, or myproject/src/test/scala, for the tests.
Since that doesn't work anymore, there are some alternatives:
giter8 and sbt.g8
Install giter8, clone ymasory's sbt.g8 template and adapt it to your necessities, and use that. See below, for example, this use of unmodified ymasory's sbt.g8 template. I think this is one of the best alternatives to starting new projects when you have a good notion of what you want in all your projects.
$ g8 ymasory/sbt
project_license_url [http://www.gnu.org/licenses/gpl-3.0.txt]:
name [myproj]:
project_group_id [com.example]:
developer_email [john.doe#example.com]:
developer_full_name [John Doe]:
project_license_name [GPLv3]:
github_username [johndoe]:
Template applied in ./myproj
$ tree myproj
myproj
├── build.sbt
├── LICENSE
├── project
│   ├── build.properties
│   ├── build.scala
│   └── plugins.sbt
├── README.md
├── sbt
└── src
└── main
└── scala
└── Main.scala
4 directories, 8 files
np plugin
Use softprops's np plugin for sbt. In the example below, the plugin is configured on ~/.sbt/plugins/build.sbt, and its settings on ~/.sbt/np.sbt, with standard sbt script. If you use paulp's sbt-extras, you'd need to install these things under the right Scala version subdirectory in ~/.sbt, as it uses separate configurations for each Scala version. In practice, this is the one I use most often.
$ mkdir myproj; cd myproj
$ sbt 'np name:myproj org:com.example'
[info] Loading global plugins from /home/dcsobral/.sbt/plugins
[warn] Multiple resolvers having different access mechanism configured with same name 'sbt-plugin-releases'. To avoid conflict, Remove duplicate project resolvers (`resolvers`) or rename publishing resolver (`publishTo`).
[info] Set current project to default-c642a2 (in build file:/home/dcsobral/myproj/)
[info] Generated build file
[info] Generated source directories
[success] Total time: 0 s, completed Apr 12, 2013 12:08:31 PM
$ tree
.
├── build.sbt
├── src
│   ├── main
│   │   ├── resources
│   │   └── scala
│   └── test
│   ├── resources
│   └── scala
└── target
└── streams
└── compile
└── np
└── $global
└── out
12 directories, 2 files
mkdir
You could simply create it with mkdir:
$ mkdir -p myproj/src/{main,test}/{resource,scala,java}
$ tree myproj
myproj
└── src
├── main
│   ├── java
│   ├── resource
│   └── scala
└── test
├── java
├── resource
└── scala
9 directories, 0 files
Source Layout
Now, about the source layout. Jens recommends following Java style. Well, the Java directory layout is a requirement -- in Java. Scala does not have the same requirement, so you have the option of following it or not.
If you do follow it, assuming the base package is org.dcsobral.myproject, then source code for that package would be put inside myproject/src/main/scala/org/dcsobral/myproject/, and so on for sub-packages.
Two common ways of diverging from that standard are:
Omitting the base package directory, and only creating subdirectories for the sub-packages.
For instance, let's say I have the packages org.dcsobral.myproject.model, org.dcsobral.myproject.view and org.dcsobral.myproject.controller, then the directories would be myproject/src/main/scala/model, myproject/src/main/scala/view and myproject/src/main/scala/controller.
Putting everything together. In this case, all source files would be inside myproject/src/main/scala. This is good enough for small projects. In fact, if you have no sub-projects, it is the same as above.
And this deals with directory layout.
File Names
Next, let's talk about files. In Java, the practice is separating each class in its own file, whose name will follow the name of the class. This is good enough in Scala too, but you have to pay attention to some exceptions.
First, Scala has object, which Java does not have. A class and object of the same name are considered companions, which has some practical implications, but only if they are in the same file. So, place companion classes and objects in the same file.
Second, Scala has a concept known as sealed class (or trait), which limits subclasses (or implementing objects) to those declared in the same file. This is mostly done to create algebraic data types with pattern matching with exhaustiveness check. For example:
sealed abstract class Tree
case class Node(left: Tree, right: Tree) extends Tree
case class Leaf(n: Int) extends Tree
scala> def isLeaf(t: Tree) = t match {
| case Leaf(n: Int) => println("Leaf "+n)
| }
<console>:11: warning: match is not exhaustive!
missing combination Node
def isLeaf(t: Tree) = t match {
^
isLeaf: (t: Tree)Unit
If Tree was not sealed, then anyone could extend it, making it impossible for the compiler to know whether the match was exhaustive or not. Anyway, sealed classes go together in the same file.
Another naming convention is to name the files containing a package object (for that package) package.scala.
Importing Stuff
The most basic rule is that stuff in the same package see each other. So, put everything in the same package, and you don't need to concern yourself with what sees what.
But Scala also have relative references and imports. This requires a bit of an explanation. Say I have the following declarations at the top of my file:
package org.dcsobral.myproject
package model
Everything following will be put in the package org.dcsobral.myproject.model. Also, not only everything inside that package will be visible, but everything inside org.dcsobral.myproject will be visible as well. If I just declared package org.dcsobral.myproject.model instead, then org.dcsobral.myproject would not be visible.
The rule is pretty simple, but it can confuse people a bit at first. The reason for this rule is relative imports. Consider now the following statement in that file:
import view._
This import may be relative -- all imports can be relative unless you prefix it with _root_.. It can refer to the following packages: org.dcsobral.myproject.model.view, org.dcsobral.myproject.view, scala.view and java.lang.view. It could also refer to an object named view inside scala.Predef. Or it could be an absolute import refering to a package named view.
If more than one such package exists, it will pick one according to some precedence rules. If you needed to import something else, you can turn the import into an absolute one.
This import makes everything inside the view package (wherever it is) visible in its scope. If it happens inside a class, and object or a def, then the visibility will be restricted to that. It imports everything because of the ._, which is a wildcard.
An alternative might look like this:
package org.dcsobral.myproject.model
import org.dcsobral.myproject.view
import org.dcsobral.myproject.controller
In that case, the packages view and controller would be visible, but you'd have to name them explicitly when using them:
def post(view: view.User): Node =
Or you could use further relative imports:
import view.User
The import statement also enable you to rename stuff, or import everything but something. Refer to relevant documentation about it for more details.
So, I hope this answer all your questions.
Scala supports and encourages the package structure of Java /JVM and pretty much the same recommendation apply:
mirror the package structure in the directory structure. This isn't necessary in Scala, but it helps to find your way around
use your inverse domain as a package prefix. For me that means everything starts with de.schauderhaft. Use something that makes sense for you, if you don't have you own domain
only put top level classes in one file if they are small and closely related. Otherwise stick with one class/object per file. Exceptions: companion objects go in the same file as the class. Implementations of a sealed class go into the same file.
if you app grows you might want to have something like layers and modules and mirror those in the package structure, so you might have a package structure like this: <domain>.<module>.<layer>.<optional subpackage>.
don't have cyclic dependencies on a package, module or layer level

What should be in the Cargo.toml file at the root of the workspace so that Visual Studio Code supports all features?

Visual Studio Code says:
A Cargo.toml file must be at the root of the workspace in order to
support all features
However I did not find what should be in Cargo.toml file located in the workspace root. Is it common for all project subdirectories?
I have read the chapter Hello, Cargo! of the documentation, but it only speaks about the Cargo.toml files within the project directory.
By experimenting, I have found out that the file with only one line [workspace] makes the VS Code note go away, but now every time I set up a new project it nags me about the fact that this project is not mentioned in the members array within this "workspace" Cargo.toml
Visual Studio Code directory structure is as follows
workspace
|
---> project1
|
---> project2
the cargo new project3 generates Cargo.toml within newly created project3 directory, but Visual Studio Code expects another Cargo.toml within the workspace directory itself.
This is covered in chapter 14 of the book, section 3. The Cargo.toml at the root of a Cargo workspace should explicitly contain its member projects in the members property. Note that this is exactly what the IDE was advising you to do.
[workspace]
members = [
"project1",
"project2",
]
Quoting:
Next, in the add directory, we create the Cargo.toml file that will configure the entire workspace. This file won’t have a [package] section or the metadata we’ve seen in other Cargo.toml files. Instead, it will start with a [workspace] section that will allow us to add members to the workspace by specifying the path to our binary crate; in this case, that path is adder:
Filename: Cargo.toml
[workspace]
members = [
"adder",
]
Next, we’ll create the adder binary crate by running cargo new within the add directory:
$ cargo new --bin adder
Created binary (application) adder project
At this point, we can build the workspace by running cargo build. The files in your add directory should look like this:
├── Cargo.lock
├── Cargo.toml
├── adder
│ ├── Cargo.toml
│ └── src
│ └── main.rs
└── target
Another example of this in the wild is serde (Cargo.toml).
The Cargo documentation provides additional details on the members field, including that path dependencies are included automatically.
The root crate of a workspace, indicated by the presence of [workspace] in its manifest, is responsible for defining the entire workspace. All path dependencies residing in the workspace directory become members. You can add additional packages to the workspace by listing them in the members key. Note that members of the workspaces listed explicitly will also have their path dependencies included in the workspace. [...]
In this case, no path dependencies nor members were stated in the root Cargo project, leading to the sub-directories not being regarded as workspace members.
As a workaround, I was able to create a top-level Cargo.toml with the following content:
[workspace]
members = [
"./*/src/..",
]
With this, I can create new projects under the workspace without explicitly updating the top-level Cargo.html.
As a note, the more obvious globs like "*", "./*" and "*/" do not work because the resulting matches must be directories with Cargo.toml files, and these globs match more than that (including "./target/", for example). The path I came up with results in the right subset (at least in the basic, typical case).

scala sbt-launch.jar - multiple projects ihe same directory?

I'm sure this is simple, but I haven't figured it out yet...
I've installed sbt-launch.jar and a shell script to execute it (named sbt).
How do I put multiple projects in the same directory?
When I run sbt the directories project and target get created and populated, and the current project is default-XXXXX. The compile command picks up source files in the top-level directory and jar files in the top-level 'lib' directory.
How do I add another project under the same directory? Every time I run sbt in an empty directory it creates a 20+ MB project directory.
Note 1: when I run sbt I an not getting asked "Create new project?" or any other questions.
Note 2: I am using sbt-launch.jar from this url: http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-tools.sbt/sbt-launch/0.10.1/sbt-launch.jar
and I'm following the instructions at: http://code.google.com/p/simple-build-tool/wiki/Setup
Found the answer (for sbt 0.10.1):
Create the file project/Build.scala that looks like this:
import sbt._
object MyBuild extends Build
{
lazy val root = Project("root", file("."))
lazy val sub1: Project = Project("proj1", file("dir1"));
lazy val sub2 = Project("proj2", file("dir2"))
}
This creates three projects 'root' (in the top-level directory), 'proj1' (in the sub-directory 'dir1') and 'proj2' (in the sub-directory 'dir2')
For more info, see https://github.com/harrah/xsbt/wiki/Full-Configuration

Scala application structure

I am learning Scala now and I want to write some silly little app like a console Twitter client, or whatever. The question is, how to structure application on disk and logically. I know python, and there I would just create some files with classes and then import them in the main module like import util.ssh or from tweets import Retweet (strongly hoping you wouldn't mind that names, they are just for reference). But how should I do this stuff using Scala? Also, I have not much experience with JVM and Java, so I am a complete newbie here.
I'm going to disagree with Jens, here, though not all that much.
Project Layout
My own suggestion is that you model your efforts on Maven's standard directory layout.
Previous versions of SBT (before SBT 0.9.x) would create it automatically for you:
dcs#ayanami:~$ mkdir myproject
dcs#ayanami:~$ cd myproject
dcs#ayanami:~/myproject$ sbt
Project does not exist, create new project? (y/N/s) y
Name: myproject
Organization: org.dcsobral
Version [1.0]:
Scala version [2.7.7]: 2.8.1
sbt version [0.7.4]:
Getting Scala 2.7.7 ...
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (9911kB/134ms)
Getting org.scala-tools.sbt sbt_2.7.7 0.7.4 ...
:: retrieving :: org.scala-tools.sbt#boot-app
confs: [default]
15 artifacts copied, 0 already retrieved (4096kB/91ms)
[success] Successfully initialized directory structure.
Getting Scala 2.8.1 ...
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (15118kB/160ms)
[info] Building project myproject 1.0 against Scala 2.8.1
[info] using sbt.DefaultProject with sbt 0.7.4 and Scala 2.7.7
> quit
[info]
[info] Total session time: 8 s, completed May 6, 2011 12:31:43 PM
[success] Build completed successfully.
dcs#ayanami:~/myproject$ find . -type d -print
.
./project
./project/boot
./project/boot/scala-2.7.7
./project/boot/scala-2.7.7/lib
./project/boot/scala-2.7.7/org.scala-tools.sbt
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4/compiler-interface-bin_2.7.7.final
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4/compiler-interface-src
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4/compiler-interface-bin_2.8.0.RC2
./project/boot/scala-2.7.7/org.scala-tools.sbt/sbt/0.7.4/xsbti
./project/boot/scala-2.8.1
./project/boot/scala-2.8.1/lib
./target
./lib
./src
./src/main
./src/main/resources
./src/main/scala
./src/test
./src/test/resources
./src/test/scala
So you'll put your source files inside myproject/src/main/scala, for the main program, or myproject/src/test/scala, for the tests.
Since that doesn't work anymore, there are some alternatives:
giter8 and sbt.g8
Install giter8, clone ymasory's sbt.g8 template and adapt it to your necessities, and use that. See below, for example, this use of unmodified ymasory's sbt.g8 template. I think this is one of the best alternatives to starting new projects when you have a good notion of what you want in all your projects.
$ g8 ymasory/sbt
project_license_url [http://www.gnu.org/licenses/gpl-3.0.txt]:
name [myproj]:
project_group_id [com.example]:
developer_email [john.doe#example.com]:
developer_full_name [John Doe]:
project_license_name [GPLv3]:
github_username [johndoe]:
Template applied in ./myproj
$ tree myproj
myproj
├── build.sbt
├── LICENSE
├── project
│   ├── build.properties
│   ├── build.scala
│   └── plugins.sbt
├── README.md
├── sbt
└── src
└── main
└── scala
└── Main.scala
4 directories, 8 files
np plugin
Use softprops's np plugin for sbt. In the example below, the plugin is configured on ~/.sbt/plugins/build.sbt, and its settings on ~/.sbt/np.sbt, with standard sbt script. If you use paulp's sbt-extras, you'd need to install these things under the right Scala version subdirectory in ~/.sbt, as it uses separate configurations for each Scala version. In practice, this is the one I use most often.
$ mkdir myproj; cd myproj
$ sbt 'np name:myproj org:com.example'
[info] Loading global plugins from /home/dcsobral/.sbt/plugins
[warn] Multiple resolvers having different access mechanism configured with same name 'sbt-plugin-releases'. To avoid conflict, Remove duplicate project resolvers (`resolvers`) or rename publishing resolver (`publishTo`).
[info] Set current project to default-c642a2 (in build file:/home/dcsobral/myproj/)
[info] Generated build file
[info] Generated source directories
[success] Total time: 0 s, completed Apr 12, 2013 12:08:31 PM
$ tree
.
├── build.sbt
├── src
│   ├── main
│   │   ├── resources
│   │   └── scala
│   └── test
│   ├── resources
│   └── scala
└── target
└── streams
└── compile
└── np
└── $global
└── out
12 directories, 2 files
mkdir
You could simply create it with mkdir:
$ mkdir -p myproj/src/{main,test}/{resource,scala,java}
$ tree myproj
myproj
└── src
├── main
│   ├── java
│   ├── resource
│   └── scala
└── test
├── java
├── resource
└── scala
9 directories, 0 files
Source Layout
Now, about the source layout. Jens recommends following Java style. Well, the Java directory layout is a requirement -- in Java. Scala does not have the same requirement, so you have the option of following it or not.
If you do follow it, assuming the base package is org.dcsobral.myproject, then source code for that package would be put inside myproject/src/main/scala/org/dcsobral/myproject/, and so on for sub-packages.
Two common ways of diverging from that standard are:
Omitting the base package directory, and only creating subdirectories for the sub-packages.
For instance, let's say I have the packages org.dcsobral.myproject.model, org.dcsobral.myproject.view and org.dcsobral.myproject.controller, then the directories would be myproject/src/main/scala/model, myproject/src/main/scala/view and myproject/src/main/scala/controller.
Putting everything together. In this case, all source files would be inside myproject/src/main/scala. This is good enough for small projects. In fact, if you have no sub-projects, it is the same as above.
And this deals with directory layout.
File Names
Next, let's talk about files. In Java, the practice is separating each class in its own file, whose name will follow the name of the class. This is good enough in Scala too, but you have to pay attention to some exceptions.
First, Scala has object, which Java does not have. A class and object of the same name are considered companions, which has some practical implications, but only if they are in the same file. So, place companion classes and objects in the same file.
Second, Scala has a concept known as sealed class (or trait), which limits subclasses (or implementing objects) to those declared in the same file. This is mostly done to create algebraic data types with pattern matching with exhaustiveness check. For example:
sealed abstract class Tree
case class Node(left: Tree, right: Tree) extends Tree
case class Leaf(n: Int) extends Tree
scala> def isLeaf(t: Tree) = t match {
| case Leaf(n: Int) => println("Leaf "+n)
| }
<console>:11: warning: match is not exhaustive!
missing combination Node
def isLeaf(t: Tree) = t match {
^
isLeaf: (t: Tree)Unit
If Tree was not sealed, then anyone could extend it, making it impossible for the compiler to know whether the match was exhaustive or not. Anyway, sealed classes go together in the same file.
Another naming convention is to name the files containing a package object (for that package) package.scala.
Importing Stuff
The most basic rule is that stuff in the same package see each other. So, put everything in the same package, and you don't need to concern yourself with what sees what.
But Scala also have relative references and imports. This requires a bit of an explanation. Say I have the following declarations at the top of my file:
package org.dcsobral.myproject
package model
Everything following will be put in the package org.dcsobral.myproject.model. Also, not only everything inside that package will be visible, but everything inside org.dcsobral.myproject will be visible as well. If I just declared package org.dcsobral.myproject.model instead, then org.dcsobral.myproject would not be visible.
The rule is pretty simple, but it can confuse people a bit at first. The reason for this rule is relative imports. Consider now the following statement in that file:
import view._
This import may be relative -- all imports can be relative unless you prefix it with _root_.. It can refer to the following packages: org.dcsobral.myproject.model.view, org.dcsobral.myproject.view, scala.view and java.lang.view. It could also refer to an object named view inside scala.Predef. Or it could be an absolute import refering to a package named view.
If more than one such package exists, it will pick one according to some precedence rules. If you needed to import something else, you can turn the import into an absolute one.
This import makes everything inside the view package (wherever it is) visible in its scope. If it happens inside a class, and object or a def, then the visibility will be restricted to that. It imports everything because of the ._, which is a wildcard.
An alternative might look like this:
package org.dcsobral.myproject.model
import org.dcsobral.myproject.view
import org.dcsobral.myproject.controller
In that case, the packages view and controller would be visible, but you'd have to name them explicitly when using them:
def post(view: view.User): Node =
Or you could use further relative imports:
import view.User
The import statement also enable you to rename stuff, or import everything but something. Refer to relevant documentation about it for more details.
So, I hope this answer all your questions.
Scala supports and encourages the package structure of Java /JVM and pretty much the same recommendation apply:
mirror the package structure in the directory structure. This isn't necessary in Scala, but it helps to find your way around
use your inverse domain as a package prefix. For me that means everything starts with de.schauderhaft. Use something that makes sense for you, if you don't have you own domain
only put top level classes in one file if they are small and closely related. Otherwise stick with one class/object per file. Exceptions: companion objects go in the same file as the class. Implementations of a sealed class go into the same file.
if you app grows you might want to have something like layers and modules and mirror those in the package structure, so you might have a package structure like this: <domain>.<module>.<layer>.<optional subpackage>.
don't have cyclic dependencies on a package, module or layer level

Copy sources files into target directory with SBT

I recently decided to use SBT to build an existing project.
In this project I have some .glsl files within the scala packages which I need to copy during the compilation phase.
The project is structured like this :
- myapp.opengl
- Shader.scala
- myapp.opengl.shaders
- vertex_shader.glsl
- fragment_shader.glsl
Is this file structure correct for SBT or do I need to put the .glsl files into an other directory. And do you know a clean way to copy these files into the target folder ?
I would prefer not putting these files into the resources directory since they are (non-compiled) sources files
Thanks
I would not recommend putting those files into src/main/scala as they do not belong there. If you want to keep them separate from your resource files, you can put them in a custom path, e.g. src/main/glsl and add the following lines to your project definition to have them copied into output directory:
val shaderSourcePath = "src"/"main"/"glsl"
// use shaderSourcePath as root path, so directory structure is
// correctly preserved (relative to the source path)
def shaderSources = (shaderSourcePath ##) ** "*.glsl"
override def mainResources = super.mainResources +++ shaderSources