IntelliJ Add a Scala subproject in a nested directory - scala

I have a repo with multiple sub-projects, that looks like this:
my-project
├── .idea
├── backend
│ │── build.sbt
│ │── src
│ └── ... other Scala subproject files
├── client
│ │── package.json
│ │── webpack.config.js
│ └── ... other JS subproject files
├── worker
│ └── ... other Python subproject files
├── Makefile
└── docker-compose.yml
Using IntelliJ IDEA Ultimate, I want to have the whole repo opened in the same window, import ./backend as a "subproject", and be able to install all sbt dependencies. How can I do that?
If I open ./backend as a separate project, IntelliJ imports all correctly, defines a ton of libraries and modules from the build.sbt file, and also re-imports them if I change build.sbt.
But for the shared project it won't import anything. If I manually import an sbt project from ./backend in the Project Structure -> Modules, it switches to the root dir anyway and doesn't import libraries. I can get syntax highlighting and autocompletion for the main library and my own files, but the packages from build.sbt are missing.

You can create a dummy root sbt project in the root folder, creating a separate build.sbt there and using backend as a subproject:
lazy val backend = (project in file("backend"))

Related

Define subprojects in another file than build.sbt

I'm trying to define a multi-project build with a consequent number of subprojects:
.
├── build.sbt
├── project/
│ ├── dependencies.scala
│ ├── tasks.scala
│ └── settings.scala
├── lib_1/
│ └── src/
├── ...
└── lib_n/
└── src/
Those subprojects are currently defined in build.sbt:
val outputJarFolder = "/some/path/"
lazy val comonSettings = /* ... */
lazy val lib_1 = (project in file ("lib1")).settings(
name:="LibOne",
commonSettings,
libraryDependencies ++= Seq(scalaTest, jsonLib, scalaXML, commonsIo),
Compile/packageBin/artifactPath := file(outputJarFolder + "lib1.jar")
)
// ... more libs ...
lazy val lib_n = (project in file ("libn")).settings(
name:="LibLast",
commonSettings,
Compile/packageBin/artifactPath := file(outputJarFolder + "libn.jar")
)
.depensOn(lib_2, lib_12)
How can I define those subprojects in another file than build.sbt in order to "unclog" that file? I want to still be able to define them in their lexicographic order (so lazy is a must). I'm working with sbt version 1.2.8 and scala 2.10.
I've tried:
Putting the declaration of those lib_k variables in a scala file and importing it --> sbt says: "classes cannot be lazy".
Putting those declaration in an object (or in a class and instantiate it in build.sbt) --> sbt projects doesn't list any subproject.
sbt documentation mentions it, but doesn't emphasize too much (perhaps to avoid encouragement for too much variation in how builds are defined in the absence of a common convention):
The build definition is described in build.sbt (actually any files named *.sbt) in the project’s base directory.
So you can split your build.sbt file into several separate .sbt files in the root of the project with different names.
I also recommend reading documentation on Organizing the build.

In Python 3 (under Pydev) how to correctly write imports within packages

Similar questions have been asked a number of times, but none of the suggested solutions work (satisfactory) in my case.
I have a Python 3 project with a structure like so:
├── project1
│ ├── package
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ └── test1.py
│ │ ├── __init__.py
│ │ ├── module1.py
│ │ └── module2.py
│ └── setup.py
I have package listed as source folder in PYTHONPATH (in Eclipse).
Everything works fine inside the project, i.e.:
In tests\test1.py doing import module1 works
In module2.py both from module1 import foo or simply import module1 work
However, when I package my code and install it using pip I start getting ImportError.
If in project2 I try to import module2 or from module2 import foo I get an error on the import that module2 does from module1.
For the imports in project2 to work I need to change the import in module2 to be from package.module1 import foo or import package.module2. This makes project1 to throw import errors.
There are similar problems with test1.py.
I can in Eclipse add the folder of project1 to PYTHONPATH and that solves the runtime error, but I still see compilation errors in PyDev.
Is there any way to write the imports or define the PYTHONPATH so Python 3 will find the imported modules/methods in all cases?
I am emphasizing Python 3 because I have a project with the same structure (as far as I can tell) under Python 2 which works well with the imports defined as import .module1 (this throws an error for Python 3)
Ended up doing the following:
Changed all imports to full path, i.e. package.module[.method]
Added package to PYTHONPATH
Removed package.module folder from the PYTHONPATH
The first two changes are enough for the code to run properly.
The last bullet causes PyDev to stop displaying errors.

Import a C library without git

Is there a way to include a C library in a Swift project without creating a git repository? That seems to be the only way explained on the Package manager documentation. Starting a git repo just to include some C headers that are already on my computer seems unwieldy.
I tried using a module.map file in a module, just like for any pure Swift module, and the C module imports fine, but contains no symbols.
This is what my project looks like:
Project
├── Package.swift
└── Sources
├── Project
│   └── main.swift
├── The_C_module_i_want
│   ├── module.modulemap
│   └── Package.swift (empty, else it won’t compile)
└── Some_Swift_module
└── taylor.swift
The top level Package.swift looks like
import PackageDescription
let package = Package(name: "Project",
targets : [
Target(name: "Project",
dependencies: ["Some_Swift_module",
"The_C_module_i_want"]),
Target(name: "Some_Swift_module"),
Target(name: "The_C_module_i_want")
]
)
and the module map looks like this:
module The_C_module_i_want {
header "/usr/local/include/The_C_library/the_c_library.h"
export *
link ...
link ...
...
}

SBT: Exclude resource subdirectory

I've been using Gradle for most of my Scala projects, but I want to evaluate the suitability of SBT as a replacement. One of the things I've done in Gradle is to exclude a certain resource directory from the final build (for example, using CoffeeScript to write JavaScript files that will be included as final resources).
In Gradle, I'd do this by:
sourceSets {
main {
resources {
exclude 'com/example/export/dev' // exclude development resources
}
}
}
And this would exclude the resource package com.example.export.dev package from the final build.
How would I do the same in SBT? I've tried
unmanagedResourceDirectories in Compile -= (resourceDirectory in Compile).value / "com/example/export/dev"
but that doesn't do a thing (I understand why, but that doesn't really help). And the documentation on the SBT web site only talks about excluding file patterns (at Classpaths, sources, and resources).
As a more descriptive image, say we have the following resource directory structure:
com
\---example
\---export
\---dev
\---something
In the final output, I want:
com
\---example
\---export
\---something
The way to think in SBT is a bit different and I know it can be hard at first.
In your example, you need to modify the task that generate the resource files (or the task that selects the folders to look for resource files).
Here is an example of how I can select only the resource files that start with character 'a'.
(unmanagedResources in Compile) := (unmanagedResources in Compile).value.filter(_.getName.startsWith("a"))
Similarly if you want to modify the entire directory of the resource files you can do that like this:
(unmanagedResourceDirectories in Compile) := (unmanagedResourceDirectories in Compile).value.filter(_.getName.startsWith("a"))
Obviously my filters here are just and example, you can have any complex pattern that Scala supports.
The nice thing about SBT is that it's interactive. So you can check the result of your task by simply typing these at the REPL of your project:
> show compile:unmanagedResources
> show compile: unmanagedResourceDirectories
To check all the dependencies to the task do this from the REPL:
> inspect tree compile:unmanagedResources
Assumption:
SBT knows where to find all resources using the standard maven build directory layout. The above solution assumes that all resources are under the /resources directory. You can then access them from your Scala code using getClass.getResource("/folderInsideResources/file.txt").
Here is a sample directory layout for a mixed Java/Scala project with resources:
.
├── main
│   ├── java
│   │   └── com
│   │   └── a
│   │   └── b
│   │   └── Hello.java
│   ├── resources
│   │   ├── a.tx
│   │   └── b.tx
│   └── scala
│   └── com
│   └── a
│   └── b
│   └── ScalaHello.scala
└── test
├── resources
└── scala
└── com
└── a
└── b
└── ScalaHello.scala
To access the resource file just use:
getClass.getResource("/a.txt")
getClass.getResource("/b.txt")
From https://github.com/sbt/sbt-jshint/issues/14:
excludeFilter in unmanagedResources := {
val public = ((resourceDirectory in Compile).value / "com" / "example" / "export" / "dev").getCanonicalPath
new SimpleFileFilter(_.getCanonicalPath startsWith public)
}

How to access scala project file from project module

I have created a project foo_proj with Intellij (using SBT template) and added a module test_mod to it. The abbreviated directory looks like this
foo_proj
├── src
│   └── main
│   └── scala-2.11
│   └── proj_obj.scala
└── test_mod
└── src
└── tmod.scala
The contents of proj_obj.scala are:
package com.base.proj
object proj_obj {
}
If would like to be able to import this object (proj_obj) into the module file tmod.scala, but when I try import com.base.proj, it can't find it.
I am new to Scala, so if I want to use stuff from the project src directory in other project modules, how else should I be structuring things? Or is this an Intellij IDEA configuration that I need to set?
Edit
The contents of the generated build.sbt are
name := "test_proj"
version := "1.0"
scalaVersion := "2.11.6"
to enable "submodules" (aka multiproject), all you need to do is add the following to your build.sbt file (or use a scala file under project dir):
lazy val root = project in file(".")
lazy val testModule = project in file("test_mod") dependsOn(root)
also, you should change test_mod dir structure.
either drop the src dir and put all your sources under the test_mod dir,
or use the sbt convention: src/main/scala or src/test/scala.