Giter Site home page Giter Site logo

tindzk / seed Goto Github PK

View Code? Open in Web Editor NEW
236.0 11.0 13.0 510 KB

Build tool for Scala projects

Home Page: https://tindzk.github.io/seed/

License: Apache License 2.0

Dockerfile 0.52% Shell 0.18% Scala 97.48% Java 1.62% HTML 0.20%
scala scala-native scalajs build-tool cross-platform bloop idea

seed's Introduction

Seed

Gitter Build Status

Seed is a user-friendly, fast and flexible build tool for Scala projects. Builds are specified in a single TOML file. Seed then handles the dependency resolution, and generates project configurations for the build server Bloop and for the IDE IntelliJ.

Seed's primary focus is to provide a better user experience for defining and managing Scala builds. The TOML format was chosen as a lightweight alternative to a Scala-based DSL. The CLI is equipped with colour support and human-readable messages. A wizard allows to quickly create a new project configuration. There are also commands to package modules and to check for version updates.

Seed was designed with large and modular projects in mind. Modules can reside in external directories and can be imported into the project scope. Thus, there is no need to publish any artefacts with SNAPSHOT versions. Furthermore, Seed can create an aggregate IDEA project that contains the project modules including the imported ones, such that there is no need to have multiple IDEA instances running.

The IDEA project is generated in one pass together with the Bloop project. Afterwards, the project can be opened in IDEA right away and is ready to work with. There is no waiting time since the dependencies have already been resolved by Seed and IDEA's build tool integration (sbt/Gradle/Maven) is being completely bypassed. This also allows to work around some bugs IDEA is riddled with.

Further speed improvements in the build pipeline are gained by using a build server for compilation. Seed delegates this responsibility to Bloop which has demonstrated a better performance over traditional Scala build tools. Only one Bloop server instance needs to be running in the background and the communication with the process takes place with one-shot CLI commands, so the memory consumption is considerably lower when working on multiple projects. Bloop also does not suffer from any out-of-memory problems as other build tools.

Another important feature is cross-platform support. Seed targets all Scala platforms (JVM, JavaScript and LLVM) without the need for plug-ins. Cross-platform builds are first-order citizens which is reflected in the design of the configuration format. The same applies to alternative Scala compilers such as Typelevel Scala.

Customisation is of importance which is why Seed has few defaults. You have to define a directory structure for your own needs. This is especially useful given Seed's cross-platform nature where you may want to share code between different platforms or use custom Scala versions for certain platforms.

Finally, Seed can be used in CI setups. For this, a Docker image is provided which reduces the burden of setting up all system dependencies correctly that are needed for cross-platform builds.

Demo

In the following screencast, we create a minimal Typelevel Scala project for the JVM, JavaScript and native:

asciicast

Installation

You can either install Seed via Coursier or use a self-contained Docker image.

Coursier

The following prerequisites are needed:

  • JVM
  • Coursier: Coursier is a tool for fetching Maven and Ivy dependencies. It can also launch JAR entry points and create executable launchers.
  • Bloop: Bloop serves the function of compiling your projects. The latest version should work since Bloop configurations strive for backward compatibility. If you encounter any problems, you can always install the version Seed is targeting which is indicated in seed version.
  • JavaScript: Node.js needs to be installed if you want to run the project or its tests.
  • LLVM: For Scala Native projects to link, LLVM needs to be installed. Please refer to the Scala Native documentation for more information.

You can create a launcher as follows:

# Use latest released version
version=$(curl https://api.github.com/repos/tindzk/seed/tags | jq -r '.[0].name')

# Use pre-release version
version=$(curl https://api.bintray.com/packages/tindzk/maven/seed | jq -r '.latest_version')

coursier bootstrap \
    -r bintray:tindzk/maven \
    tindzk:seed_2.12:$version \
    -f -o seed

Alternatively, you can use Coursier's launch command to run Seed directly:

coursier bootstrap \
    -r bintray:tindzk/maven \
    tindzk:seed_2.12:$version -- \
    help

Docker

A self-contained Docker image based on Alpine Linux is provided for all Seed versions. You can pull it from the public Docker Hub registry:

$ docker pull tindzk/seed:$version

It contains a compatible Bloop version and all dependencies needed for cross-platform builds (JVM, Node, Clang/LLVM). You can use the image to build your projects. For example, the toml-scala project could be built as follows:

$ docker run -it tindzk/seed:$version /bin/sh
apk add git
git clone https://github.com/sparsetech/toml-scala.git
cd toml-scala
seed bloop
bloop test toml-js toml-jvm

This Docker image can be used in CI setups. Here is a Drone CI configuration for the same project.

Getting Started

In a previous section, you already saw Seed's project creation wizard (init). To illustrate the build format, we will now create a project manually. A complete Scala Native project can be defined in only five lines of TOML:

[module.demo.native]
root               = "."
scalaVersion       = "2.11.11"
scalaNativeVersion = "0.3.7"
sources            = ["src/"]

This build defines a Scala Native module with the name demo. Save the content to build.toml. Then, create the file src/Main.scala containing:

object Main extends App {
  println("Hello World")
}

Now, you can generate the Bloop and IDEA configurations as follows:

$ seed all

This downloads all dependencies to $HOME/.coursier and creates projects for IDEA in .idea/ and for Bloop in .bloop/. Instead of all, you could have also specified bloop or idea in order to only generate the respective configuration.

The final step is to compile and run your program:

$ seed run demo

This compiles the module to build/ and runs it.

Features

  • Succinct build specifications
    • Written in TOML
    • There is only one single configuration file
    • Intuitive syntax without cryptic operators (scalaDeps and javaDeps, instead of %%%, %% and %)
    • Ability to include other projects rather than publishing dependencies
  • Cross-platform modules are first-order citizens with support for all three Scala targets
    • JVM
    • JavaScript
    • Native
  • Alternative compilers like Typelevel Scala are fully supported
    • No manual patching of dependencies required
  • Fast dependency resolution via Coursier
    • Once a configuration has been generated, the dependencies do not need to be resolved a second time
    • The user does not need an Internet connection if the dependencies are already locally available
  • Shorter compilation times
    • Leverages external Bloop build server that is optimised for compilation speed
    • Optional compilation to tmpfs for in-memory builds
  • IDE project generation for IntelliJ IDEA
    • Avoids overhead of sbt/Gradle/Maven projects
    • Better integration of cross-platform projects
  • Custom build targets to run external commands or main classes
    • Generate code
    • Build non-Scala artefacts
  • Organised file structure
    • There is only one build folder per project (as opposed to target folders for every module in sbt)
    • Custom project source structures are easily configured, e.g. src/ and test/ instead of the more lengthy src/{main,test}/scala/
  • Can be used alongside other build tools (e.g. sbt)
    • Default paths were chosen not to conflict in any way
  • Can be used in CIs like Drone using pre-built Docker image
  • UX
    • True colour output
    • User-friendly messages
    • Unicode characters
    • Progress bars
  • Project creation wizard
  • Generate module documentation
  • Publish artefacts to Bintray
    • Read version from Git repository
  • Package modules
    • Copy over dependencies
  • Server mode
    • Expose a WebSocket server
    • Clients can trigger compilation and linking of modules
    • Clients can subscribe to build events
  • Check for dependency updates
    • Choose library versions separately for each platform to avoid incompatibilities
  • Simple design
    • No distinction between managed/unmanaged/generated sources
    • No ability to define tasks
    • No plug-in infrastructure
    • Tiny code base

Build Configuration

The TOML file format is used for all configuration files. A language extension was enabled to allow line breaks in inline tables.

The default build file is named build.toml. You can specify a custom path with the --build parameter. A build file corresponds to a project which can contain multiple modules.

This section explains the components of build configurations and provides examples you can use in your own build files.

Project

Project-wide settings are defined in the optional [project] section and are inherited by all modules defined in the same file:

[project]
scalaVersion       = "2.12.4-bin-typelevel-4"       # Mandatory; Scala version to be used by all modules
scalaJsVersion     = "0.6.23"                       # Optional; only needed for JavaScript compilation
scalaNativeVersion = "0.3.7"                        # Optional; only needed for native compilation
scalaOrganisation  = "org.typelevel"                # Optional; defaults to `org.scala-lang`
scalaOptions       = ["-Yliteral-types"]            # Optional; empty by default
testFrameworks     = ["minitest.runner.Framework"]  # Entry points for test frameworks
                                                    # Explained in section "Test module" below

All of these settings can be overridden by modules.

Module

A module groups source paths and related settings into a compilation unit. The basic syntax of a module as follows:

[module.myModule]
targets = ["jvm", "js"]
root    = "src"
sources = ["src"]

This defines a cross-compiled module with a JVM and JavaScript target. For every module, a list of source paths has to be specified. The source paths can be files and directories. You also have to define a root path (root setting) if you would like to generate an IntelliJ project.

Since Seed is platform-agnostic, every module needs to specify a target platform. This is either achieved with the targets setting or by including the platform in the module header definition:

[module.myModule2.jvm]
sources = ["src"]

[module.myModule2.js]
sources = ["src"]

These two definitions are called platform-specific modules. Both modules are equivalent to myModule.

A module can have an optional test module:

# Cross-compiled
# Inherits all settings from base module (e.g. root, targets and sources)
[module.myModule.test]
sources = ["test"]

# Platform-specific
[module.myModule2.test.jvm]
sources = ["test"]

For any module, the following options are available:

[module.myModule]
scalaVersion       = ""  # Must be set on every module
scalaJsVersion     = ""  # Only used if module has JavaScript target
scalaNativeVersion = ""  # Only used if module has native target
scalaOptions       = []  # Empty by default
scalaOrganisation  = ""  # Defaults to `org.scala-lang`
testFrameworks     = []  # Only used by test module
root               = ""  # Module root path for IntelliJ
sources            = []  # List of source directories and files
scalaDeps          = []  # Module-specific Scala dependencies
compilerDeps       = []  # Compiler plug-ins (specified in the same format as scalaDeps)
moduleDeps         = []  # Module dependencies
mainClass          = ""  # Optional entry point; needed for running/packaging module
targets            = []  # Platform targets

Unless overridden in the module, the settings are inherited from the [project] section.

Cross-platform module

A cross-platform module is a module that has one or multiple targets. The target platforms your code can be compiled to is only limited by the language features and libraries your code makes use of. Not all libraries and Scala features are available during JavaScript and native compilation. For most code, cross-platform support will be as simple as adding another target. For other projects, you will have to factor out platform-specific logic into a submodule (see next section).

[module.myModule]
root    = "jvm"
sources = ["src"]
targets = ["js"]

When you generate the Bloop configuration with seed bloop, this will create myModule as there is only one platform. You can compile it using bloop compile myModule. We can specify multiple targets:

[module.myModule]
# ...
targets = ["js", "jvm", "native"]

This is equivalent to defining a separate module for each platform.

In the Bloop configuration, this corresponds to an aggregate module myModule as well as three modules with the platform appended to each. You can compile them with bloop compile myModule-<target> whereas <target> is one of js, jvm and native.

Returning to our initial example from the "Getting Started" section, we can change it as follows to make it compile for JVM and native:

# Instead of `[module.demo.native]`
[module.demo]
root               = "."
scalaVersion       = "2.11.11"
scalaNativeVersion = "0.3.7"
sources            = ["src/"]
targets            = ["jvm", "native"]  # This line was added

Platform-specific module

A platform-specific module inherits all settings from its parent and extends them:

[module.myModule]
root    = "shared"
sources = ["shared/src"]
targets = ["jvm", "js"]

[module.myModule.jvm]
root      = "jvm"
sources   = ["jvm/src"]
resources = ["jvm/res"]

[module.myModule.js]
root      = "js"
sources   = ["js/src"]
scalaDeps = [["org.scala-js", "scalajs-dom", "0.9.5"]]

Here, we use a cross-platform module in conjunction with two platform-specific modules. This is useful if you have code that should be shared across multiple platforms, and if certain platforms have additional functionality or provide a specific implementation for a feature.

In the base module, the source path is src which we extend in the JVM- and JavaScript-specific modules with platform-specific sources, i.e. jvm/src and js/src. For example, the command bloop compile myProject-jvm would compile all sources from the base module and additionally include files from jvm/src.

It is possible to set a custom Scala version for modules. This is needed when a platform does not support the latest Scala version yet, as is the case with Scala Native. You can globally set the version to 2.12 which will be then used by JavaScript and JVM, but the Scala Native module will use 2.11:

[project]
scalaVersion = "2.12.8"

[module.myModule.native]
scalaVersion = "2.11.11"

JVM

The available JVM options are:

[module.myModule.jvm]
javaDeps  = []  # Java dependencies
resources = []  # List of resource paths

JavaScript

The available JavaScript options are:

[module.myModule.js]
jsdom          = false  # Import the jsdom library in the generated.
                        # JavaScript file. Must be installed via
                        # yarn/npm. Useful for test cases that rely
                        # on DOM operations.
emitSourceMaps = true   # Emit source maps
moduleKind     = "default"  # Options: default, commonjs
output         = "myModule.js"  # Path to generated file
                                # Default: <module name>.js

Native

The available native options are:

[module.myModule.native]
gc              = "immix"  # Garbage collector. Options: none, immix or boehm
targetTriple    = ""       # See https://clang.llvm.org/docs/CrossCompilation.html#target-triple
clang           = "/usr/bin/clang"
clangpp         = "/usr/bin/clang++"
compilerOptions = []       # Options passed to Clang during compilation
linkerOptions   = []       # Options passed to Clang during linking
linkStubs       = false    # Link or ignore @stub definitions
output          = "myModule.run"  # Path to generated file
                                  # Default: <module name>.js

Dependencies

In all modules, you can specify scalaDeps which will be resolved to the corresponding artefacts for each target platform:

[module.myModule]
root      = "shared"
sources   = ["shared/src"]
targets   = ["js", "jvm"]
scalaDeps = [
  ["io.circe", "circe-parser", "0.9.3"]
]

This dependency can be only resolved if circe-parser is available for Scala.js and JVM. If a dependency is not available for a platform, you can move it to a platform-specific module:

[module.myModule.jvm]
scalaDeps = [
  ["org.scalaj", "scalaj-http", "2.4.1"]
]

On scalaDeps, you can specify a fourth parameter for the version tag. The version tag is the actual difference between a Java and Scala dependency.

The Scala naming conventions stipulate that a suffix be added to the artefact name. Thus, scalaj-http becomes scalaj-http_2.12.

The previous example could be rewritten as:

scalaDeps = [
  ["org.scalaj", "scalaj-http", "2.4.1", "platformBinary"]
]

The default is platformBinary which will suit most libraries. However, some libraries target a specific compiler version or share one artefact with all platforms.

The available options are:

  • binary: Binary Scala version (e.g. 2.12). This behaves like full if the Scala version is a pre-release (e.g. 2.12.8-M3)
  • full: Full Scala version (e.g. 2.11.11)
  • platformBinary: Platform name including the binary Scala version (native0.3_2.11)

scalaDeps only works with Scala artefacts. For all other artefacts, you can use javaDeps:

[module.myModule.jvm]
javaDeps = [
  ["com.zaxxer"        , "nuprocess"       , "1.2.3"],
  ["org.apache.commons", "commons-compress", "1.17" ]
]

Note that the javaDeps setting is only available on JVM projects.

Test module

To run tests on a certain module, you can add a test module for it:

[module.myModule.test]
sources   = ["shared/test"]
targets   = ["js", "jvm"]
scalaDeps = [
  ["org.scalatest", "scalatest", "3.0.5"]
]

This module is cross-platform and the tests are shared by the two targets.

You can also define a platform-specific test module:

[module.myModule.test.js]
sources = ["js/test"]

If you add a test framework, make sure that testFrameworks in project contains its qualified class name. Common test frameworks are:

  • ScalaTest: org.scalatest.tools.Framework
  • ScalaCheck: org.scalacheck.ScalaCheckFramework
  • MiniTest: minitest.runner.Framework
  • µTest: utest.runner.Framework
  • MUnit: munit.Framework

In Bloop, you can run the test suites as follows: bloop test myModule which is short for bloop test myModule-test. The latter depends on myModule-js-test and myModule-jvm-test.

Test modules inherit settings from their parents. Therefore, root does not need to be set again. IntelliJ will aggregate sources and tests under the same root.

Module dependencies

Modules can depend on other modules. An example is a full-stack web application with a shared cross-compiled core:

[module.core]
sources = ["core/src"]
targets = ["js", "jvm"]

[module.webapp.js]
moduleDeps = ["core"]
sources    = ["frontend/src"]

[module.server.jvm]
moduleDeps = ["core"]
sources    = ["server/src"]

Setting moduleDeps to core, gives webapp and server access to its compiled sources.

moduleDeps can refer to any modules available in the scope as long as the target platforms match.

bloop compile webapp triggers the compilation of core-js whereas bloop compile server would compile core-jvm.

Custom build targets

You can specify custom targets on a module, for example to build artefacts (HTML, CSS) or to generate code that dependent modules will compile. A target can run shell commands and main classes.

As an example, we could generate CSS artefacts from SCSS using Gulp. The corresponding entry for spawning the Gulp process would look as follows:

[module.template.target.scss]
root    = "scss"
command = "yarn run gulp"

Since we specified root, it will also generate a IDEA module named template-scss. We could build the target explicitly with seed build template:scss, or simply seed build template. If the module template has regular Scala targets, the latter would compile their sources too along with all custom targets.

Note that you will have to either use seed build or seed link since Bloop commands are not aware of your build targets.

When you depend on a module in moduleDeps, all of its targets are inherited. Any module that transitively depends on template, will run the target command when building.

The current working directory is the path to the module's build file. The environment variable BUILD_PATH will point to the build path of the root project. You can access it in the command itself:

[module.template.target.fonts]
root    = "fonts"
command = "cp -Rv fonts $BUILD_PATH"

By default, the process execution is asynchronous. If you need the process to complete first before continuing with the compilation process, you can override the await setting which is set to false by default:

[module.template.target.gen-scala]
await   = true
command = "..."

If your command has support for a watch mode, you can additionally specify a watchCommand:

[module.template.target.scss]
root         = "scss"
command      = "yarn run gulp"
watchCommand = "yarn run gulp default watch"

The watch command is used when the user specifies --watch:

  • seed build template:scss --watch
  • seed link template:scss --watch

If --watch is not provided, Seed will spawn the command instead. Note that the watchCommand ignores await and is always run asynchronously.

Besides spawning commands, you can run any main class defined in the project. For example, to generate a JavaScript file, you could define:

[module.layouts.target.js-bundle]
root = "layouts"

class = { module = "keyboard:jvm", main = "keyboard.Bundle" }

# or shorter:
# class = ["keyboard:jvm", "keyboard.Bundle"]

In addition to BUILD_PATH, we also set the environment variable MODULE_PATH when running classes. The module path is the root path of the Seed project which contains the referenced module. This environment variable is not set for commands since their current working directory will point to the module path.

It is possible for multiple modules to share a code generator. To access the source paths of all modules that depend on a generator, access the environment variable MODULE_SOURCE_PATHS. Its value uses the system path separator character (java.io.File.pathSeparatorChar).

For examples of using code generation, please refer to these links:

Compiler plug-ins

Scala plug-ins can be included with the compilerDeps setting. It behaves similar to scalaDeps, but adds the -Xplugin parameter to the Scala compiler. compilerDeps is available on the project as well as module level:

[project]
compilerDeps = [
  ["org.scalameta", "semanticdb-scalac", "4.2.0", "full"]
]

[module.macros.js]
compilerDeps = [
  ["org.scalamacros", "paradise", "2.1.1", "full"]
]

Note that project-level plug-ins are inherited by all modules defined in the project file. When module a depends on module b which defines compiler plug-ins, these are inherited by a. Thus, in order to avoid duplication, shared compiler dependencies can be defined on base projects and modules.

In the example above, module.macros.js inherits the SemanticDB plug-in from the project and adds a separate dependency for the Macro Paradise plug-in.

For a complete cross-compiled Macro Paradise example, please refer to this project.

Project dependencies

External builds can be imported into the scope by using the import setting at the root level. It can point to a build file, or its parent directory in which case it will attempt to load <path>/build.toml. From the imported file, Seed will only make its modules accessible. Other project-level settings are being ignored. Multiple projects can be imported as import is a list.

Since all modules are imported into the scope, they can be depended on by local modules:

import = ["foo"]  # Imports `foo/build.toml`

[project]
# ...

[module.bar.jvm]
moduleDeps = ["fooCore"]  # Assuming that the foo project contains a module named fooCore

As with regular modules, for each of the imported ones a Bloop file is created. Then, as part of the current build, Bloop will resolve the external project dependencies and compile their sources locally. This is to avoid any binary incompatibilities that could arise if the referenced project used different platform versions or compiler settings.

Note that project dependencies are inherited transitively.

Paths

Directory structure

Seed does not impose any default file structure. Other build tools use the default src/main/scala which is unnecessarily verbose and insufficient as soon as cross-platform modules are involved. Therefore, it is entirely up to the user to set a custom structure for the project in Seed.

For projects with only one module, Scala files could be stored in src/ and tests in test/. This change would look as follows:

[module.app]
root    = "."  # This allows IntelliJ to aggregate the source and test module
sources = ["src"]

[module.app.test]
sources = ["test"]

If your project relies on generated Scala/Java files, you can simply add their paths to the sources list.

Resolvers

The default resolvers are as following:

[resolvers]
maven = ["https://repo1.maven.org/maven2"]
ivy   = []

To add an Ivy resolver, the URL must be wrapped in a list:

[resolvers]
ivy = [
  ["https://repo.typesafe.com/typesafe/ivy-releases"]
]

The reason for this is that the Ivy pattern may be omitted. It is short for:

[resolvers]
ivy = [
  {
    url     = "https://repo.typesafe.com/typesafe/ivy-releases",
    pattern = "[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]"
  }
]

Package

When publishing artefacts, a Maven POM file is created. To configure its contents, define a package section:

[package]
# Project name (`name` field)
# name = "example"
name = ""

# Package organisation (`groupId` field)
# organisation = "com.smith"
organisation = ""

# List of developers (ID, name, e-mail)
# developers = [{ id = "joesmith", name = "Joe Smith", email = "[email protected]" }]
# developers = [["joesmith", "Joe Smith", "[email protected]"]]
developers = []

# Project URL
url = ""

# List of project licences
# Available values:
# gpl:2.0, gpl:3.0, lgpl:2.1, lgpl:3.0, cddl:1.0, cddl+gpl, apache:2.0, bsd:2,
# bsd:3, mit, epl:1.0, ecl:1.0, mpl:2.0
# licences = ["apache:2.0"]
licences = []

# Source code information
# `developerConnection` is optional and if omitted, has the same value as `connection`
#scm = {
#  url = "https://github.com/joesmith/example",
#  connection = "scm:git:[email protected]:joesmith/joesmith.git",
#  developerConnection = "scm:git:[email protected]:joesmith/joesmith.git"
#}
scm = { url = "", connection = "", developerConnection = "" }

# Publish sources
# Alternatively, use --skip-sources to override this setting
sources = true

# Generate and publish documentation
# Alternatively, use --skip-docs to override this setting
docs = true

Sample configurations

You can take some inspiration from the following projects:

If you have any Seed configurations you deem worth sharing, please feel free to add them to this list!

Seed configuration

Seed has a global configuration file which is stored in ~/.config/seed.toml.

tmpfs

By default, all modules are compiled to the build/ directory within the project folder.

On Linux, you can compile your entire project in memory to improve speed and reduce disk wear out. This feature was modelled after sbt-tmpfs.

You can enable it for your builds with the --tmpfs flag, or use a global setting:

[build]
tmpfs = true

This setting is also honoured by the generated IntelliJ project.

Artefact resolution

The following global settings are available for artefact resolution:

[resolution]
# Do not show the downloaded artefacts
# Useful to shorten logs in CI pipelines
silent = false

# Ivy path
# Can be also set with --ivy-path
ivyPath = "/home/user/.ivy2/local"

# Artefact cache path
# Can be also set with --cache-path
cachePath = "/home/user/.cache/coursier/v1"

# Fetch JavaDoc and source artefacts for all library dependencies. Then,
# populate the resolution section in Bloop. This setting is only needed if you
# use Bloop with IDEs, e.g. Metals or IntelliJ.
# See also https://scalacenter.github.io/bloop/docs/build-tools/sbt#download-dependencies-sources
#
# If you generate an IDEA project, these artefacts will always be downloaded.
optionalArtefacts = false

The default values are indicated.

CLI settings

In the cli section, you can find output-related configuration settings:

[cli]
# Log level
# Possible values: debug, warn, info, error, silent
level = "debug"

# Use Unicode characters to indicate log levels
unicode = true

# Show progress bars when compiling modules
progress = true

The default values are indicated.

Publishing settings

# Bintray repository credentials
[repository.bintray]
user   = ""
apiKey = ""

If you maintain your configuration files in a public Git repository, it is advisable to move the Bintray section to a separate untracked file (e.g. seed-credentials.toml) and import it from the main configuration:

import = ["seed-credentials.toml"]

Git

.gitignore

For a Seed project, .gitignore only needs to contain these four directories:

/.idea/
/.bloop/
/.metals/

/build/

Dependencies

If another build uses Seed and Git for versioning, there is no need for publishing SNAPSHOT dependencies. Instead, Git modules would be a simpler solution. All dependencies could be fetched in a subfolder of the current project.

$ cat .gitmodules
[submodule "otherProject"]
  path = otherProject
  url = https://github.com/org/otherProject.git

Then, use the following command to fetch the dependencies:

$ git submodule update --init --recursive

Finally, this project can be embedded using the include setting in Seed.

This approach is easier to manage in CI setups as Git modules track a specific commit, whereby the builds are reproducible. Git modules also work with transitive dependencies (--recursive).

Usage

Seed delegates the compilation phase to an external tool. Bloop is an intuitive build server that runs on the same machine as a background service. Its architectural design allows for shorter compilation cycles and lower overall memory consumption when working on multiple projects at the same time.

Building, linking and running

After having created a Bloop project with seed bloop, you can compile, link and run modules directly from Seed:

  • seed build <module> This will compile all platform modules
  • seed link <module> This will link all platform modules which support linking (JavaScript and Native)
  • seed run <module> This will run a compatible platform module (JVM, JavaScript and Native)

You can select a specific platform:

  • seed build <module>:js This will compile only the JavaScript module
  • seed link <module>:js This will link only the JavaScript module
  • seed run <module>:js This will run only the JavaScript module

If you defined a custom build target, you can use the same syntax to build it:

  • seed build <module>:<target>

If you run Seed in server mode, you can connect to your remote Seed instance using the --connect parameter:

  • seed build --connect <module> Trigger compilation on remote Seed instance
  • seed link --connect <module> Trigger linking on remote Seed instance
  • seed run --connect <module> Trigger running on remote Seed instance

Also, run seed --help to acquaint yourself with all the available commands.

As Seed creates a regular Bloop project, the official Bloop CLI can be used as well:

bloop compile <module>      # Compile module
bloop run <module>          # Run main class
bloop run <module> --watch  # Watch for source changes, recompile and restart
bloop test <module>         # Run test cases

For more detailed information, please refer to the official Bloop user guide.

Server mode

You can run Seed in server mode. By default, it will listen to JSON commands on the WebSocket server localhost:8275. It supports several commands:

  • Linking modules
  • Publishing build status events

You could use the server as a message bus. You can trigger a link from the IDE or the command line. At the same time, there can be multiple event listeners subscribing to build status events. This is useful if you develop a Scala.js application and want to reload the website in the browser after each build.

This can be achieved in three steps:

  1. Run seed server in the background
  2. If you use IntelliJ, configure "Run/Debug Configuration":
  • Create template from "Bash"
    • Script: /home/user/bin/seed
    • Interpreter path: /bin/sh
    • Program arguments: link --connect <module>
    • Working directory: <project path>
  1. In your Scala.js application, run this code upon start-up:
/** Subscribe to build notifications. Whenever any module was linked, evaluate
  * `onLinked`.
  */
def watch(onLinked: => Unit): Unit = {
  val client = new WebSocket("ws://localhost:8275")
  client.onopen = _ =>
    client.send(JSON.stringify(new js.Object { val command = "buildEvents" }))
  client.onmessage = message => {
    val event =
      JSON.parse(message.data.asInstanceOf[String]).event.asInstanceOf[String]
    if (event == "linked") onLinked
  }
}

watch(dom.window.location.reload())

Press Shift-F10 in IntelliJ to trigger the build. Bloop's output is forwarded and shown in the same window. Once the linking is done, the page in the browser will reload.

IntelliJ IDEA

Seed has the ability to generate IDEA configurations. It copes better with cross-platform projects than IDEA's sbt support. It has the additional benefit of being faster and having a lower memory consumption since no sbt instance needs to be spawned.

If you are replacing an existing sbt project or creating a new IDEA project with Seed, make sure IDEA is not started and the project loaded. Otherwise, refreshing IDEA projects is as simple as running seed idea. IntelliJ will pick up the changes immediately and does not need to be restarted.

When you generate a configuration for IDEA, Seed will also fetch Javadoc and source files as part of the dependency resolution.

A common problem with imported cross-platform projects in IntelliJ is that tests cannot be run and code highlighting for shared modules does not work. Seed works around these bugs by setting up the dependencies correctly (from <module>-jvm to <module> and vice-versa). Although IDEA will show an error in the settings because it detected a circular dependency, but code highlighting and compilation will still work fine.

The Seed integration also supports compilation to tmpfs which does not suffer from this bug.

File structure and root path

While Bloop does not impose any limitations on how you structure your project files, IDEA does. For a Seed project to be valid in IDEA, a module's source and test files must have a common ancestor. If you have the directories <module>/src/main/scala and <module>/src/test/scala, <module>/ would be their common ancestor. By contrast, this structure is not supported by IDEA: src/<module> and test/<module>.

The common ancestor is the module's root path. It needs to be set manually for each module using the root option.

[module.myModule]
root    = "myModule/"
sources = ["myModule/src/main/scala"]

Here, the root path was chosen to be myModule/ since this folder may also contain other non-source files.

Project dependencies

If you embed external projects using import, all external modules will be made part of the same IDEA project. This has the advantage that only one IDEA instance needs to be opened. As IDEA does not group those modules by subproject, it is advisable to use a prefix all module names from external projects.

This allows to run tests from different projects and make changes that span beyond project boundaries as well as the ability to use IDEA's refactoring tools.

JavaScript/native support

IDEA does not support starting JavaScript/native projects or running their tests. However, other features such as syntax highlighting or refactoring work fine.

There are two related issues tracking the testing problems: issue SCL-8972 and issue 743.

As a workaround, you can open a terminal within IntelliJ and use Bloop, for example: bloop test <module>-js

Generate documentation

Seed can generate an HTML documentation for your modules with the doc command:

seed doc example:jvm example:js

The functionality is based on Scaladoc. For each specified module, it uses the corresponding Scala compiler. Scaladoc bypasses Bloop and performs a separate non-incremental compilation pass.

Packaging

In order to distribute your project, you may want to package the compiled sources. The approach chosen in Seed is to bundle them as a JAR file.

To build and package the module demo, use the following command:

seed package demo

The default output path is dist/.

If the JAR file is supposed to have an entry point, make sure to specify mainClass on the module in your build file. Also, note that at the moment, only JVM modules can be packaged.

The library dependencies can be optionally bundled as separate files in the dist/ folder, with the class path of the JAR file correctly set up. This allows you to have a self-contained version of your project for distribution. You can do so by specifying the --libs parameter:

seed package demo --libs

If the module demo has a main class, you can run your program as follows:

java -jar dist/demo.jar

Uber JARs

The approach of bundling dependencies as external files (commonly called Uber JARs or fat JARs) over to including them in the JAR has several advantages which are outlined here.

In short, merging external JARs is non-trivial and oftentimes requires the intervention of the developer. For example, sbt-assembly needs custom Scala code to resolve conflicts.

Also, Uber JARs are large in size and it becomes difficult to share dependencies across different build versions and other projects on the client side.

Finally, for clients it becomes harder to obtain a list of dependencies and their licences used in the application.

Updating

There is a command to check for version updates. It attempts to find suitable versions such that there are no incompatibilities between artefacts. For instance, for specific platforms a different version of a library may be required. You can run the command as follows:

seed update

If you would like to use pre-release versions, you can also pass in this parameter:

seed update --pre-releases

Publishing

Seed can publish modules to Maven-style Bintray repositories. First, populate the build file's package section. Then run the following command:

seed publish --version=1.0 bintray:joesmith/maven/releases demo:js demo:jvm

The credentials must be configured in the global Seed configuration:

[repository.bintray]
user   = "joesmith"
apiKey = "<API key>"

Alternatively, Seed reads the environment variables BINTRAY_USER and BINTRAY_API_KEY.

Seed publishes sources and generates the documentation, which slows down the publishing process. If any of these artefacts are unneeded, you can permanently change the behaviour via package.sources and package.docs in the build file, or temporarily by passing --skip-sources and --skip-docs to the CLI.

Finally, to depend on the published library in another project, add the Bintray resolver there:

[resolvers]
maven = ["https://repo1.maven.org/maven2", "https://dl.bintray.com/joesmith/maven"]

The --version parameter is optional. By default, Seed reads the version number from the Git repository via git describe --tags. This allows publishing artefacts for every single commit as part of CI executions.

Performance

On average, Bloop project generation and compilation are roughly 3x faster in Seed compared to sbt in non-interactive mode. Seed's startup is 10x faster than sbt's.

Hyperfine 1.5.0 was used for the benchmarks. All tests ran on a Hetzner CX21 (cpuinfo) under Docker. The test project was toml-scala. You can find the benchmark specification here in order to reproduce the results.

Startup time

Seed ran 10.56 ± 1.75 times faster than sbt.

Command Mean [s] Min…Max [s]
sbt exit 16.795 ± 0.995 15.230…18.097
seed help 1.591 ± 0.247 1.099…1.879

Generating Bloop configuration

Seed ran 2.95 ± 0.26 times faster than sbt.

Command Mean [s] Min…Max [s]
sbt bloopInstall 18.540 ± 1.135 16.923…19.986
seed bloop 6.286 ± 0.404 5.848…7.028

Compiling project

Bloop ran 3.45 ± 4.08 times faster than sbt.

Command Mean [s] Min…Max [s]
sbt "; clean; compile" 61.720 ± 8.480 56.895…85.524
bloop clean --propagate --cascade && 17.894 ± 21.018 9.193…77.436
bloop compile toml-js toml-jvm toml-native

This benchmark tested the compilation speed of JVM and JavaScript for Scala 2.12 and native for Scala 2.11.

Limitations

Plug-ins

Seed does not offer any capability for writing plug-ins. If you would like to react to build events, you could use Seed in the server mode. To model the equivalent of sbt's tasks in Seed, you can define a separate module with custom build targets.

If some settings of the build are dynamic, you could write a script to generate TOML files from a template. A use case would be to cross-compile your modules for different Scala versions. Cross-compilation between Scala versions may require code changes. It is thinkable to have the build.toml point to the latest supported Scala version and have scripts that downgrade the sources, e.g. using a tool like scalafix.

Publishing

At the moment, artefacts can only be published to Bintray. Sonatype support is planned for future versions.

Design Goals

The three overarching design goals were usability, simplicity and speed. The objective for Seed is to offer a narrow, but well-designed feature set that covers most common use cases for library and application development. This means leaving out features such as plug-ins, shell, tasks and code execution that would have a high footprint on the design.

On the other hand, Seed takes in features that improve a developer's workflow and would require external plug-ins otherwise. For example, the creation of initial projects or checking of updates are not essential features for a build tool, but improve the user experience and reduce time. Such features also take less work to implement than maintaining a plug-in infrastructure.

Seed was designed from the ground up to be cross-platform. Furthermore, Seed does not impose much structure on your project, a folder structure or a certain way of handling modules (mono repositories vs. Git modules vs. published artefacts).

Contributing

Every new feature should fit into the architecture outlined in the design goals. Particular care should be given to the UI and documentation.

The output could use colours and bold/italic/underlined text. Also, components such as tables or trees may improve user experience. The user should not see any Scala errors, but instead human-readable error messages. As an example, invalid settings in the TOML are recognised and pointed out with a trace:

[info] Loading project ./build.toml...
[error] The TOML file could not be parsed
[error] Message: String expected, Num(42) provided
[error] Trace: module → targets

Development

sbt takes the Git commit (git describe --tags) as the Seed version. This version can be overridden by creating a SEED file in the root folder.

To run all test cases, the Scaladoc bridges must be published locally for the current Seed version:

$ sbt
scaladoc211/publishLocal
scaladoc212/publishLocal
scaladoc213/publishLocal
test

Credits

Seed achieves its simplicity by delegating much of the heavy lifting to external tools and libraries, notably Bloop and Coursier. The decision of using TOML for configuration and the build schema are influenced by Cargo.

Licence

Seed is licenced under the terms of the Apache v2.0 licence.

seed's People

Contributors

hejfelix avatar megri avatar nafg avatar tindzk avatar vascorsd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

seed's Issues

Question: How to specify compiler version in scalaDeps?

I tried the following but it didn't work.

scalaDeps = [["org.wvlet.airframe", "airframe", "20.2.1", "2.12"]]

➜  ideal git:(master) ✗ ./seed bloop
ⓘ Loading project build.toml...
✗ The build file build.toml is malformed
  Message: Invalid version tag provided
  Trace: module → ideal → scalaDeps → #1 → #4
➜  ideal git:(master) ✗

Boxed error when ./seed bloop

Boxed error when ./seed bloop

Exception in thread "main" java.util.concurrent.ExecutionException: Boxed Error
	at scala.concurrent.impl.Promise$.resolver(Promise.scala:87)
	at scala.concurrent.impl.Promise$.scala$concurrent$impl$Promise$$resolveTry(Promise.scala:79)
	at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:284)
	at scala.concurrent.Promise.complete(Promise.scala:53)
	at scala.concurrent.Promise.complete$(Promise.scala:52)
	at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:187)
	at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33)
	at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.AssertionError: assertion failed: Attempts to download https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.6.7.3/jackson-databind-2.6.7.3-sources.jar twice in parallel
	at scala.Predef$.assert(Predef.scala:223)
	at coursier.cache.loggers.RefreshLogger$UpdateDisplayRunnable.newEntry(RefreshLogger.scala:82)
	at coursier.cache.loggers.RefreshLogger.downloadingArtifact(RefreshLogger.scala:227)
	at coursier.cache.FileCache.$anonfun$download$25(FileCache.scala:422)
	at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:659)
	at scala.util.Success.$anonfun$map$1(Try.scala:255)
	at scala.util.Success.map(Try.scala:213)
	at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
	at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33)
	... 5 more

Cannot install via Coursier

Attempting to install seed via Coursier yields an error with the following output:

> cs install seed
https://repo1.maven.org/maven2/io/get-coursier/apps/maven-metadata.xml
  No new update since 2021-05-14 02:42:19
Exception in thread "main" java.lang.Exception: coursier.install.AppArtifacts$ScalaDependenciesNotFound: Can't find a scala version suffix for tindzk::seed:latest.stable (likely a non existing module or version)
	at coursier.install.AppDescriptor.artifacts(AppDescriptor.scala:66)
	at coursier.install.InstallDir.update$1(InstallDir.scala:259)
	at coursier.install.InstallDir.$anonfun$createOrUpdate$21(InstallDir.scala:385)
	at coursier.install.InstallDir.$anonfun$createOrUpdate$21$adapted(InstallDir.scala:384)
	at coursier.install.Updatable$.get$1(Updatable.scala:55)
	at coursier.install.Updatable$.$anonfun$writing$1(Updatable.scala:96)
	at coursier.cache.CacheLocks$.loop$1(CacheLocks.scala:72)
	at coursier.cache.CacheLocks$.withLockOr(CacheLocks.scala:98)
	at coursier.install.Updatable$.writing(Updatable.scala:96)
	at coursier.install.InstallDir.createOrUpdate(InstallDir.scala:384)
	at coursier.install.InstallDir.createOrUpdate(InstallDir.scala:87)
	at coursier.cli.install.Install$.$anonfun$run$7(Install.scala:108)
	at coursier.cli.install.Install$.$anonfun$run$7$adapted(Install.scala:95)
	at scala.collection.immutable.List.foreach(List.scala:431)
	at coursier.cli.install.Install$.run(Install.scala:95)
	at coursier.cli.Coursier$.$anonfun$runA$2(Coursier.scala:151)
	at coursier.cli.Coursier$.$anonfun$runA$2$adapted(Coursier.scala:139)
	at coursier.cli.CommandAppPreA.run(CommandAppPreA.scala:22)
	at caseapp.core.app.CommandAppWithPreCommand.$anonfun$main$5(CommandAppWithPreCommand.scala:99)
	at caseapp.core.app.CommandAppWithPreCommand.$anonfun$main$5$adapted(CommandAppWithPreCommand.scala:99)
	at scala.util.Either.fold(Either.scala:191)
	at caseapp.core.app.CommandAppWithPreCommand.$anonfun$main$3(CommandAppWithPreCommand.scala:99)
	at caseapp.core.app.CommandAppWithPreCommand.$anonfun$main$3$adapted(CommandAppWithPreCommand.scala:85)
	at scala.Option.foreach(Option.scala:407)
	at caseapp.core.app.CommandAppWithPreCommand.main(CommandAppWithPreCommand.scala:85)
	at coursier.cli.Coursier$.main(Coursier.scala:104)
	at coursier.cli.Coursier.main(Coursier.scala)
Caused by: coursier.install.AppArtifacts$ScalaDependenciesNotFound: Can't find a scala version suffix for tindzk::seed:latest.stable (likely a non existing module or version)
	at coursier.install.AppDescriptor.$anonfun$processDependencies$9(AppDescriptor.scala:184)
	at scala.Option.toRight(Option.scala:485)
	at coursier.install.AppDescriptor.processDependencies(AppDescriptor.scala:184)
	at coursier.install.AppDescriptor.artifacts(AppDescriptor.scala:64)
	... 26 more

Running on macOS Catalina 10.15.7 (19H1030), using OpenJDK Runtime Environment (Zulu 8.52.0.23-CA-macosx) (build 1.8.0_282-b08) and Coursier 2.0.13.

Move to Own GitHub Org

This will help the perception that this is more than an individual project and might help adaptation.

Make seed a Bloop BSP client

Currently, seed communicates with bloop via the Bloop CLI and then parses the output from Bloop (from what I've gathered in a cursory look at the implementation). This approach works, but it's less than ideal because:

  1. It's not the recommended option to integrate with Bloop. BSP is recommended and we have good tools to start the server, connect to it and give users an input/output stream they can use to communicate with the server.
  2. It depends on specific output from Bloop, specifically for diagnostics.
  3. It misses on some important information that seed might want to know about. For example, concrete progress notifications when compiling a target.
  4. CLI invocations currently have a build-level block so you cannot run the CLI more than twice (not a problem if only one seed instance is used).

With the tooling and libraries coming in the next Bloop version, integrating to Bloop via BSP will be greatly simplified. I believe that after that release it's a good moment to make the jump from the CLI to the BSP integration.

What are your thoughts on this @tindzk ?

Seed idea, IntelliJ Ultimate 2020.3 not able to open the project

I run seed idea then try to open with IntelliJ Ultimate 2020.3 and then the screen flashes and it closes, it just cannot open, on windows 10. hmm I guess there could be many causes for this including the Scala plugin

I'm using seed version
? Seed v0.1.7 for Bloop v1.3.2+ and Coursier v1.1.0-M14-4

Cannot import java bom file

https://search.maven.org/artifact/software.amazon.awssdk/bom/2.10.65/pom

[module.ideal.jvm]
root = "jvm"
sources = ["jvm/src"]
scalaDeps = [["com.github.seratch", "awscala", "0.8.+"],
              ["org.wvlet.airframe", "airframe", "20.2.1"]]
javaDeps = [["software.amazon.awssdk", "pom", "2.10.65"]]

Gives error for javaDeps = [["software.amazon.awssdk", "pom", "2.10.65"]]

Exception in thread "main" coursier.error.ResolutionError$CantDownloadModule: Error downloading software.amazon.awssdk:pom:2.10.65
  not found: /Users/philip/.ivy2/local/software.amazon.awssdk/pom/2.10.65/ivys/ivy.xml
  not found: https://repo1.maven.org/maven2/software/amazon/awssdk/pom/2.10.65/pom-2.10.65.pom
	at coursier.Resolve$.$anonfun$validate$1(Resolve.scala:359)
	at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238)
	at scala.collection.Iterator.foreach(Iterator.scala:941)
	at scala.collection.Iterator.foreach$(Iterator.scala:941)
	at scala.collection.AbstractIterator.foreach(Iterator.scala:1429)
	at scala.collection.IterableLike.foreach(IterableLike.scala:74)
	at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
	at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
	at scala.collection.TraversableLike.map(TraversableLike.scala:238)
	at scala.collection.TraversableLike.map$(TraversableLike.scala:231)
	at scala.collection.AbstractTraversable.map(Traversable.scala:108)
	at coursier.Resolve$.validate(Resolve.scala:357)
	at coursier.Resolve.validate0$1(Resolve.scala:139)
	at coursier.Resolve.$anonfun$ioWithConflicts0$4(Resolve.scala:183)
	at coursier.util.Task$.$anonfun$flatMap$2(Task.scala:11)
	at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:307)
	at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:41)
	at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
	at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Dog Food Seed

Move the repos at least under the author's control to use Seed. I see some of the repos the author contributes to like those in https://github.com/sparsetech does not use it yet.

This would mean one will hit issues 1st hand and this will get improved.

Also perhaps this will mean there would mean more committed to maintain and improve it also, which would help adaptation.

How this will be a truly great build system not only for Scala but for Java, other JVM languages and even native and other languages.

Seed idea does not bring across the resources directory

[module.what.jvm]
...
resources = ["jvm/resources"]

After running seed idea, then opening it in IntelliJ I would like the resources to be on the classpath. The module in IntelliJ should have the resources directory set. Then if I want to run from IntelliJ it will pickup the resources directory.

What I do now to work-around this problem is that I open the project in IntelliJ and go to the module and set the resources directory in the UI. I do this as I like to run from IntelliJ using the debugger.

Also seed run seems to not take into the resources directory.

seed run mymodule:jvm

Separation of Build File Format Through a Documented Interface

Can a documented interface be added separating the build file format from the back end processing?

This way the file format can parser can be easily swapped out and new ones added to support more formats.

Also, make the configuration format pluggable for easy additions.

Also one can use seed as an embedded script using a DSL or program without using a particular configuration file.

This will give the most flexibility.

Bug: platform-specific modules do not generate -Xplugin: bloop definitions

Excerpt from #15 (comment)

We can add a test case derived from example-paradise to reproduce the faulty behaviour:

--- a/test/example-paradise/build.toml
+++ b/test/example-paradise/build.toml
@@ -9,6 +9,13 @@ scalaOptions   = ["-encoding", "UTF-8", "-unchecked", "-deprecation", "-Xfuture"
 root    = "macros"
 sources = ["macros"]
 targets = ["jvm", "js"]
+
+[module.macros.jvm]
+compilerDeps = [
+  ["org.scalamacros", "paradise", "2.1.1", "full"]
+]
+
+[module.macros.js]
 compilerDeps = [
   ["org.scalamacros", "paradise", "2.1.1", "full"]
 ]

How to install compiler plugin and full cross-version Scala dependencies?

Hi, congratulations on the release and great job with the seed UX and documentation. I was able to get up and running in seconds. I have two questions:

  • How do I add a compiler plugin? For example, what is the equivalent of addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full) in sbt? A workaround is to manually download the jar and update scalaOptions
scalaOptions = [
  "-encoding",
  "UTF-8",
  "-unchecked",
  "-deprecation",
  "-Xfuture",
+  "-Xplugin:/Users/olafurpg/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scalamacros/paradise_2.12.8/2.1.1/paradise_2.12.8-2.1.1.jar"
]
  • How do I add Scala dependencies that are cross-versioned against the full Scala compiler version? A workaround is to update javaDeps like this
+ javaDeps = [
+   ["org.scalameta", "interactive_2.12.8", "4.1.0"]
+ ]

Intermittent exception: `java.net.SocketException: Bad file descriptor`

When I run seed commands, they all seem to run and complete just fine but about every once in a while I get the following exception at the end of the command's execution:

Jun 22, 2020 6:44:04 PM org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor run
SEVERE: java.net.SocketException: Bad file descriptor
org.eclipse.lsp4j.jsonrpc.JsonRpcException: java.net.SocketException: Bad file descriptor
	at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:120)
	at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:99)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.net.SocketException: Bad file descriptor
	at org.newsclub.net.unix.NativeUnixSocket.read(Native Method)
	at org.newsclub.net.unix.AFUNIXSocketImpl$AFUNIXInputStream.read(AFUNIXSocketImpl.java:312)
	at org.newsclub.net.unix.AFUNIXSocketImpl$AFUNIXInputStream.read(AFUNIXSocketImpl.java:319)
	at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:79)
	... 6 more

I'm running on macOS 10.15.5

Support generating {sbt,mill,gradle,Maven} builds

Imagine I was to use seed to teach Scala to beginners. I'd pick seed because it's so simple that I can explain how to declare a module and add a dependency in less than a paragraph. It imposes almost no overhead when teaching Scala to a crowd of developers inexperienced with the Scala build tool ecosystem and allows them to focus on what's important: learning the language.

However, a big drawback of doing this is that they would have learned to use a build tool that's perhaps really simple for future use cases and doesn't have major adoption in the community. I believe this is an important point.

To address that concern, I suggest seed can use generate valid build files out of its build schema. Given its simplicity, seeds format is a subset of the project settings in all the other build tools and making that generation is relatively straight-forward.

I'd suggest supporting sbt and mill at the beginning and then adding support for Gradle/Maven if there's demand. The great thing about this is that people can get started with seed but if they need unsupported features such as packaging/releasing they can generate a valid sbt/mill build out of it and continue with their lives.

JVM resources are not copied into jar

tl;dr

Files in the resource directory are not being copied into the built jar file.

the sordid details

I've set up a project that mimics a sbt/maven layout (src/main/scala, src/main/resources, etc). The source for the project is at https://github.com/hohonuuli/demoseed. In this project there is a resource file at src/main/resources/logback.xml. My module is configured like so:

[module.demoseed.jvm]
root = "."
resources = [
  "src/main/resources"
]
sources = [
  "src/main/scala",
  "src/main/java"
]
scalaDeps = [
  ["io.circe", "circe-core", "0.13.0"]
]

I ran the following:

seed all
seed package demoseed --libs

Everything compiles just fine, but I can't find the logback.xml file from resources in the built jar. e.g.

❯ jar -tvf build/dist/demoseed.jar
   702 Mon Jun 22 17:39:16 PDT 2020 META-INF/MANIFEST.MF
     0 Mon Jun 22 17:39:14 PDT 2020 demoseed/
   925 Mon Jun 22 17:39:14 PDT 2020 demoseed/Main$.class
   301 Mon Jun 22 17:39:14 PDT 2020 demoseed/Foo.class
   635 Mon Jun 22 17:39:14 PDT 2020 demoseed/Main.class

At this point, I can't tell if this is a bug in seed or if I've missed some configuration. Any help is appreciated. (BTW, seed is pretty cool!)

Question: Are seeds modules also Java 9 Modules?

Java 9 modules place certain information into a JAR to express this new module standard, does seed automatically output Java 9 module JARS? Or is the module concept only between the projects themselves involved in builds?

YAML support?

I really like Seed (although I can't use it without #18), however I'm not sure I can use it with TOML. Especially with #18 and #19 the configuration forms a deep tree, and especially with many modules (which the README says it's designed for) it can be very wide too. TOML is nice for some things but I can't see it scaling well for me.

As an example, GitLab CI uses TOML for configuring the runner binary, but YAML for defining a project's various jobs and their configuration, and I think they both make sense. The former is basically a few sections of flat config, with a bit of nesting. The latter is a much more complicated tree of settings. You can have many jobs, each of which can have many settings, each of which might itself need to be defined with sub-properties.

I admit the TOML generated by seed init overwhelmed me more than it might have, because some of what it generated may have been unnecessary.

I found something online to convert TOML to YAML and was much happier with the result. So what I started doing is using yaml2toml (on Ubuntu, sudo snap install marshal) to translate my config for seed. Specifically, I ran echo seedbuild.yml | entr -rs "yaml2toml --preserve-key-order seedbuild.yml build.toml && seed bloop && bloop compile -w (bloop projects)" (this will run the part in quotes whenever seedbuild.yml changes via my shell, Fish).

I didn't get all that far in converting my decently-sized sbt project to seed (I stopped mainly due to #18), but here is how the two ways of defining it compare:

TOML
[project]
scalaVersion = "2.12.8"
scalaJsVersion = "0.6.28"
scalaOptions = ["-encoding", "UTF-8", "-unchecked", "-deprecation", "-Xfuture"]
testFrameworks = ["minitest.runner.Framework"]

[resolvers]
maven = ["https://repo1.maven.org/maven2", "https://jcenter.bintray.com", "https://jitpack.io"]

[module]

[module.sharedCommon]
root = "shared_common"
targets = ["jvm", "js"]
sources = ["shared_common/src/main/scala"]
compilerDeps = [["org.scalamacros", "paradise", "2.1.1", "full"]]
scalaDeps = [["cc.co.scala-reactive", "reactive-routing", "0.6.4"], ["com.github.cornerman.sloth", "sloth", "34b09cdccb"], ["com.github.julien-truffaut", "monocle-macro", "1.5.1-cats"], ["com.github.krzemin", "octopus", "0.3.3"], ["com.lihaoyi", "sourcecode", "0.1.7"], ["io.circe", "circe-core", "0.11.1"], ["io.circe", "circe-generic", "0.11.1"], ["io.circe", "circe-parser", "0.11.1"], ["io.github.nafg", "slick-additions-entity", "0.9.1.1"]]

[module.sharedCommon.test]
sources = ["shared_common/src/test/scala"]
scalaDeps = [["io.monix", "minitest", "2.5.0"]]

[module.volunteerShared]
root = "volunteer_shared"
targets = ["jvm", "js"]
sources = ["notes_shared/src/main/scala"]
moduleDeps = ["sharedCommon"]

[module.notesShared]
root = "notes_shared"
targets = ["jvm", "js"]
sources = ["notes_shared/src/main/scala"]
moduleDeps = ["volunteerShared"]

[module.doctorsShared]
root = "doctors_shared"
targets = ["jvm", "js"]
sources = ["doctors_shared/src/main/scala"]
moduleDeps = ["sharedCommon", "notesShared"]

[module.util]
root = "util"
targets = ["jvm"]
sources = ["util/src/main/scala"]
moduleDeps = ["volunteerShared"]
scalaDeps = [["net.liftweb", "lift-util", "3.3.0"], ["org.scala-lang.modules", "scala-xml", "1.2.0"]]

[module.modelsCommon]
root = "models_common"
targets = ["jvm"]
sources = ["models_common/src/main/scala"]
moduleDeps = ["volunteerShared"]
javaDeps = [["org.flywaydb", "flyway-core", "5.2.4"]]
scalaDeps = [["com.github.tminglei", "slick-pg", "0.17.3"], ["com.github.tminglei", "slick-pg_circe-json", "0.17.3"], ["io.github.nafg", "slick-additions", "0.9.1.1"], ["net.liftweb", "lift-util", "3.3.0"]]

[module.jsCommon]
root = "js_common"
targets = ["js"]
sources = ["js_common/src/main/scala"]
moduleDeps = ["sharedCommon"]
scalaOptions = ["-P:scalajs:sjsDefinedByDefault"]
scalaDeps = [["com.github.japgolly.scalajs-react", "ext-monocle-cats", "1.4.2"], ["io.github.nafg.css-dsl", "bootstrap3", "0.4.0"], ["io.github.nafg.scalajs-facades", "react-select_2-1-2", "0.6.0"], ["io.github.nafg.scalajs-react-util", "core", "0.7.0"]]
YAML
project:
  scalaVersion: 2.12.8
  scalaJsVersion: 0.6.28
  scalaOptions:
    - '-encoding'
    - UTF-8
    - '-unchecked'
    - '-deprecation'
    - '-Xfuture'
  testFrameworks:
    - minitest.runner.Framework


resolvers:
  maven:
    - https://repo1.maven.org/maven2
    - https://jcenter.bintray.com
    - https://jitpack.io


module:

# SHARED MODULES

  sharedCommon:
    root: shared_common
    targets: [jvm, js]
    sources: [shared_common/src/main/scala]
    compilerDeps:
      - ["org.scalamacros",            "paradise",               "2.1.1", "full"]
    scalaDeps:
      - ["cc.co.scala-reactive",       "reactive-routing",       "0.6.4"]
      - ["com.github.cornerman.sloth", "sloth",                  "34b09cdccb"]
      - ["com.github.julien-truffaut", "monocle-macro",          "1.5.1-cats"]
      - ["com.github.krzemin",         "octopus",                "0.3.3"]
      - ["com.lihaoyi",                "sourcecode",             "0.1.7"]
      - ["io.circe",                   "circe-core",             "0.11.1"]
      - ["io.circe",                   "circe-generic",          "0.11.1"]
      - ["io.circe",                   "circe-parser",           "0.11.1"]
      - ["io.github.nafg",             "slick-additions-entity", "0.9.1.1"]
    test:
      sources: [shared_common/src/test/scala]
      scalaDeps:
        - ["io.monix", "minitest", "2.5.0"]

  volunteerShared:
    root: volunteer_shared
    targets: [jvm, js]
    sources: [notes_shared/src/main/scala]
    moduleDeps: [sharedCommon]

  notesShared:
    root: notes_shared
    targets: [jvm, js]
    sources: [notes_shared/src/main/scala]
    moduleDeps: [volunteerShared]

  doctorsShared:
    root: doctors_shared
    targets: [jvm, js]
    sources: [doctors_shared/src/main/scala]
    moduleDeps: [sharedCommon, notesShared]

# JVM MODULES

  util:
    root: util
    targets: [jvm]
    sources: [util/src/main/scala]
    moduleDeps: [volunteerShared]
    scalaDeps:
      - ["net.liftweb",            "lift-util", "3.3.0"]
      - ["org.scala-lang.modules", "scala-xml", "1.2.0"]

  modelsCommon:
    root: models_common
    targets: [jvm]
    sources: [models_common/src/main/scala]
    moduleDeps: [volunteerShared]
    javaDeps:
      - ["org.flywaydb",        "flyway-core",          "5.2.4"]
    scalaDeps:
      - ["com.github.tminglei", "slick-pg",            "0.17.3"]
      - ["com.github.tminglei", "slick-pg_circe-json", "0.17.3"]
      - ["io.github.nafg",      "slick-additions",     "0.9.1.1"]
      - ["net.liftweb",         "lift-util",           "3.3.0"]

# JS MODULES

  jsCommon:
    root: js_common
    targets: [js]
    sources: [js_common/src/main/scala]
    moduleDeps: [sharedCommon]
    scalaOptions: ["-P:scalajs:sjsDefinedByDefault"]
    scalaDeps:
      - ["com.github.japgolly.scalajs-react", "ext-monocle-cats",   "1.4.2"]
      - ["io.github.nafg.css-dsl",            "bootstrap3",         "0.4.0"]
      - ["io.github.nafg.scalajs-facades",    "react-select_2-1-2", "0.6.0"]
      - ["io.github.nafg.scalajs-react-util", "core",               "0.7.0"]

Module-level build settings

Various build settings such as the resolvers, compiler versions (Scala, Scala.js, Scala Native), compiler flags and test frameworks are defined only on the project level.

  • Define these settings on seed.model.Module too
  • When importing projects, copy over the new settings as done in #17
  • parseBuildToml should return Either[Codec.Error, Map[String, Build.Module]]
  • Access build settings from modules instead of seed.model.Build
  • Update README

See also #15 (comment).

Build a webpage

In the Scala community, it's more than common to see a nice markdown->html microsite for nice libraries/tools. Since the README is so fleshed out, it would make sense as a first step to just produce a site from that markdown?

It would definitely attract more attention.

Quarkus integration

I would like integration with Quarkus https://quarkus.io/

Quarkus allows for fast reload of classes and a whole lot of features I would like seed to exhibit. I suspect this issue maybe closed as this could be a separate github project, but I like to ask first. It may not be desired by your project. I like some of the declarative features of Quarkus.

Cannot run javascript target using seed run ideal:js on Apple MAC OSX

Apple Mac OSX

using seed run ideal:js

ⓘ Generated JavaScript file '/Users/philip/home/projects/ideal/build/ideal.js'
✗ Feb 14, 2020 3:08:15 PM com.zaxxer.nuprocess.osx.OsxProcess start
✗ WARNING: Exception thrown from handler
✗ java.lang.RuntimeException: Invocation of posix_spawn() failed, return code: 2, last error: 0
✗ 	at com.zaxxer.nuprocess.internal.BasePosixProcess.checkReturnCode(BasePosixProcess.java:639)
✗ 	at com.zaxxer.nuprocess.osx.OsxProcess.start(OsxProcess.java:85)
✗ 	at com.zaxxer.nuprocess.osx.OsxProcessFactory.createProcess(OsxProcessFactory.java:34)
✗ 	at com.zaxxer.nuprocess.NuProcessBuilder.start(NuProcessBuilder.java:266)
✗ 	at bloop.exec.Forker$.$anonfun$run$6(Forker.scala:185)
✗ 	at monix.eval.internal.TaskRunLoop$.monix$eval$internal$TaskRunLoop$$loop$1(TaskRunLoop.scala:187)
✗ 	at monix.eval.internal.TaskRunLoop$RestartCallback$1.onSuccess(TaskRunLoop.scala:119)
✗ 	at monix.eval.Task$.$anonfun$forkedUnit$2(Task.scala:1463)
✗ 	at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
✗ 	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
✗ 	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
✗ 	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
✗ 	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
↪ [BSP] shutdown request received: build/shutdown
↪ BSP server cancelled, closing socket...
↪ Process terminated successfully
➜  ideal

Missing jar after running `seed bloop`

I was using seed today for a small project with lihaoyi/cask. The server is actually unable to be run due to the following exception:

ⓘ Exception in thread "main" java.lang.IllegalArgumentException: XNIO001001: No XNIO provider found
ⓘ 	at org.xnio.Xnio.doGetInstance(Xnio.java:270)
ⓘ 	at org.xnio.Xnio.getInstance(Xnio.java:187)
ⓘ 	at io.undertow.Undertow.start(Undertow.java:117)
ⓘ 	at cask.main.Main.main(Main.scala:57)
ⓘ 	at core.MinimalApplication.main(Main.scala)

Looking at the dependencies of cask I see both xnio-api and xnio-nio:

❯ cs resolve com.lihaoyi:cask_2.13:0.6.7
com.lihaoyi:cask-util_2.13:0.6.7:default
com.lihaoyi:cask_2.13:0.6.7:default
com.lihaoyi:castor_2.13:0.1.3:default
com.lihaoyi:fansi_2.13:0.2.9:default
com.lihaoyi:geny_2.13:0.6.0:default
com.lihaoyi:pprint_2.13:0.5.9:default
com.lihaoyi:sourcecode_2.13:0.2.1:default
com.lihaoyi:ujson_2.13:1.1.0:default
com.lihaoyi:upack_2.13:1.1.0:default
com.lihaoyi:upickle-core_2.13:1.1.0:default
com.lihaoyi:upickle-implicits_2.13:1.1.0:default
com.lihaoyi:upickle_2.13:1.1.0:default
io.undertow:undertow-core:2.0.13.Final:default
org.java-websocket:Java-WebSocket:1.4.0:default
org.jboss.logging:jboss-logging:3.3.2.Final:default
org.jboss.xnio:xnio-api:3.3.8.Final:default
org.jboss.xnio:xnio-nio:3.3.8.Final:default
org.scala-lang:scala-library:2.13.2:default
org.scala-lang:scala-reflect:2.13.2:default
org.scala-lang.modules:scala-collection-compat_2.13:2.1.4:default
org.slf4j:slf4j-api:1.7.25:default

Running bloopInstall with either sbt or Mill end up having both of these listed in the project.classpath in the .bloop/<module>.json file. However, after running seed bloop, xnio-nio seems to be missing and not on the classpath causing the exception up above. So I'm not really sure what is happening, but it looks like it's just being excluded for some reason when it probably shouldn't be.

Support TOML build in VS Code

I think it'd be lovely if we could support code completions and diagnostics in VS Code. These are features that are typically supported out-of-the-box for JSON configuration files, but I also think we should go a little bit further than that and support coursier dependency completions: https://twitter.com/alxarchambault/status/1123878375884578816 This feature alone would make the use of seed for beginners a very enjoyable experience.

I think there's a case to consider switching from TOML to JSON if we want to ship editor support sooner and have a more lightweight implementation. VS Code supports JSONc (JSON with comments) and provides completions/red squigglies when a JSON schema is provided. I have no opinion here, I think JSON would be more amenable and intuitive to users (especifically those coming from build tools such as npm and the like), but TOML is also nice.

Compile to GraalVM native image

I'd like to have seed compiled to native. We're already doing this in some of the projects in Bloop (for example, the next version of the CLI will be a Scala library compiled to native) and I think it would be really exciting if this project was native, which implies less resource usage and snappier UX.

Here's the list of current dependencies:

libraryDependencies ++= Seq(
  "com.lihaoyi"           %% "fansi"          % "0.2.7",
  "io.get-coursier"       %% "coursier"       % bloopCoursierVersion,
  "io.get-coursier"       %% "coursier-cache" % bloopCoursierVersion,
  "tech.sparse"           %% "toml-scala"     % "0.2.0",
  "tech.sparse"           %% "pine"           % "0.1.4",
  "ch.epfl.scala"         %% "bloop-config"   % bloopVersion,
  "com.joefkelley"        %% "argyle"         % "1.0.0",
  "org.scalaj"            %% "scalaj-http"    % "2.4.2",
  "dev.zio"               %% "zio"            % "1.0.0-RC10-1",
  "io.circe"              %% "circe-core"     % "0.11.1",
  "commons-io"            % "commons-io"      % "2.6",
  "com.zaxxer"            % "nuprocess"       % "1.2.4",
  "org.java-websocket"    % "Java-WebSocket"  % "1.4.0",
  "org.slf4j"             % "slf4j-simple"    % "2.0.0-alpha0",
  "io.monix"              %% "minitest"       % "2.5.0" % "test",
  scalaOrganization.value % "scala-reflect"   % scalaVersion.value
)

It looks like there are quite a lot of them and I'm not sure if they are GraalVM friendly. But compiling to native should in theory work for any dependency that doesn't depend on JNA. For example, nuprocess should probably be replaced by https://github.com/zeroturnaround/zt-exec.

This is not a blocker, but I think it would be cool 😄

Fix tests

I can't run all tests without getting errors. Seems like some path confusion. For instance, I get

- Normalise paths *** FAILED ***
  received /private/tmp/build != expected /tmp/build (IdeaSpec.scala:27)

but also a bunch of fails like this one:

- Generate and compile meta modules *** FAILED ***
  Throwable
    seed.cli.util.Exit$.error(Exit.scala:8)
    seed.process.ProcessHelper$.$anonfun$runCommmand$5(ProcessHelper.scala:101)
    seed.process.ProcessHandler.onExit(ProcessHelper.scala:30)
    com.zaxxer.nuprocess.internal.BasePosixProcess.onExit(BasePosixProcess.java:310)
    com.zaxxer.nuprocess.osx.ProcessKqueue.processEvent(ProcessKqueue.java:314)
    com.zaxxer.nuprocess.osx.ProcessKqueue.process(ProcessKqueue.java:224)
    com.zaxxer.nuprocess.internal.BaseEventProcessor.run(BaseEventProcessor.java:78)
    java.lang.Thread.run(Thread.java:748)

I'm guessing this happens due to me running MacOS, but I'm not sure.

Find a way to have scalafix working

I've spent too many hours already trying to be able to call and use scalafix directly from the command line as any sane cli application should be able to. At this point I'm convinced it's almost impossible to simply use that tool without some kind of integration in the build tool. I'd like to be proven wrong if that's possible. So it would be nice to see if it's possible or not to have it working with seed, documentation, examples or needed additions to the tool for it to work.

I have an example project here - https://github.com/vascorsd/ineninaru

The pains points I've found are the following at least:

  • managing additional rules by having to somehow download and pass the tool classpath around for the new rules be recognized by scalafix.
  • somehow have to make scalafix know about the same scalac options being used so it doesn't complain when using rules that for example require the '-Wunused' flag.
  • seems reasonable to also need to somehow pass the scala version in use so it recognizes the rules that cannot be processed in some specific version, for example ExplicitResultTypes rule
  • I can't seem to understand of find proper examples or documentation on how to pass the scalac-options in the command line in a way that it works. If I pass just the annoying flag of '-Wunused' it proceeds but any combination I try in order to pass multiple compiler flags just ends up in frustration (here I blame scalafix more and the weird metaconfig thing it's using for parsing cli args, since there's barely useful docs with examples)
  • there's definitely some problem detecting or using the semanticdb thing, since I can't seem to pass over that error when I'm able to proceed after fighting with scalac options.

Some examples runs:

scalafix-jvm --scala-version "2.13.2" --auto-classpath --stdout --check --verbose --tool-classpath ".scalafix-rules/https/repo1.maven.org/maven2/com/github/vovapolu/scaluzzi_2.12/0.1.7/scaluzzi_2.12-0.1.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/github/liancheng/organize-imports_2.12/0.2.1/organize-imports_2.12-0.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.11/scala-library-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/ch/epfl/scala/scalafix-core_2.12/0.9.15/scalafix-core_2.12-0.9.15.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/scalameta_2.12/4.3.8/scalameta_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/geirsson/metaconfig-typesafe-config_2.12/0.9.10/metaconfig-typesafe-config_2.12-0.9.10.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/parsers_2.12/4.3.8/parsers_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scalap/2.12.11/scalap-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/geirsson/metaconfig-core_2.12/0.9.10/metaconfig-core_2.12-0.9.10.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/typesafe/config/1.2.1/config-1.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/trees_2.12/4.3.8/trees_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.12.11/scala-compiler-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/typelevel/paiges-core_2.12/0.3.0/paiges-core_2.12-0.3.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-collection-compat_2.12/2.1.2/scala-collection-compat_2.12-2.1.2.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/pprint_2.12/0.5.9/pprint_2.12-0.5.9.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/common_2.12/4.3.8/common_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/thesamet/scalapb/scalapb-runtime_2.12/0.9.7/scalapb-runtime_2.12-0.9.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/fastparse_2.12/1.0.1/fastparse_2.12-1.0.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.12.11/scala-reflect-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-xml_2.12/1.0.6/scala-xml_2.12-1.0.6.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/fansi_2.12/0.2.9/fansi_2.12-0.2.9.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/sourcecode_2.12/0.2.1/sourcecode_2.12-0.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/thesamet/scalapb/lenses_2.12/0.9.7/lenses_2.12-0.9.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/fastparse_2.12/2.1.3/fastparse_2.12-2.1.3.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/fastparse-utils_2.12/1.0.1/fastparse-utils_2.12-1.0.1.jar" --scalac-options '-feature -Wunused'
error: The Scala compiler option "-Ywarn-unused" is required to use OrganizeImports with "OrganizeImports.removeUnused" set to true. To fix this problem, update your build to use at least one Scala compiler option that starts with -Ywarn-unused or -Wunused (2.13 only)
scalafix-jvm --scala-version "2.13.2" --auto-classpath --stdout --check --verbose --tool-classpath ".scalafix-rules/https/repo1.maven.org/maven2/com/github/vovapolu/scaluzzi_2.12/0.1.7/scaluzzi_2.12-0.1.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/github/liancheng/organize-imports_2.12/0.2.1/organize-imports_2.12-0.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.11/scala-library-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/ch/epfl/scala/scalafix-core_2.12/0.9.15/scalafix-core_2.12-0.9.15.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/scalameta_2.12/4.3.8/scalameta_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/geirsson/metaconfig-typesafe-config_2.12/0.9.10/metaconfig-typesafe-config_2.12-0.9.10.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/parsers_2.12/4.3.8/parsers_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scalap/2.12.11/scalap-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/geirsson/metaconfig-core_2.12/0.9.10/metaconfig-core_2.12-0.9.10.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/typesafe/config/1.2.1/config-1.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/trees_2.12/4.3.8/trees_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.12.11/scala-compiler-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/typelevel/paiges-core_2.12/0.3.0/paiges-core_2.12-0.3.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-collection-compat_2.12/2.1.2/scala-collection-compat_2.12-2.1.2.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/pprint_2.12/0.5.9/pprint_2.12-0.5.9.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/common_2.12/4.3.8/common_2.12-4.3.8.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/thesamet/scalapb/scalapb-runtime_2.12/0.9.7/scalapb-runtime_2.12-0.9.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/fastparse_2.12/1.0.1/fastparse_2.12-1.0.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.12.11/scala-reflect-2.12.11.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-xml_2.12/1.0.6/scala-xml_2.12-1.0.6.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/fansi_2.12/0.2.9/fansi_2.12-0.2.9.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/sourcecode_2.12/0.2.1/sourcecode_2.12-0.2.1.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/thesamet/scalapb/lenses_2.12/0.9.7/lenses_2.12-0.9.7.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar:.scalafix-rules/https/repo1.maven.org/maven2/com/lihaoyi/fastparse_2.12/2.1.3/fastparse_2.12-2.1.3.jar:.scalafix-rules/https/repo1.maven.org/maven2/org/scalameta/fastparse-utils_2.12/1.0.1/fastparse-utils_2.12-1.0.1.jar" --scalac-options "-feature" --scalac-options "-Wunused"
info: Processing (0/4) /home/diaz/dev/personal/scala/ineninaru/src/server/configuration/Configuration.scala
error: error while loading Object, Missing dependency 'object scala.native in compiler mirror', required by /modules/java.base/java/lang/Object.class
error: SemanticDB not found: src/server/configuration/Configuration.scala
info: Processing (1/4) /home/diaz/dev/personal/scala/ineninaru/src/server/IneninaruServer.scala
error: SemanticDB not found: src/server/IneninaruServer.scala
info: Processing (2/4) /home/diaz/dev/personal/scala/ineninaru/src/client/IneninaruClient.scala
error: SemanticDB not found: src/client/IneninaruClient.scala
info: Processing (3/4) /home/diaz/dev/personal/scala/ineninaru/src/protocol/proto.scala
error: SemanticDB not found: src/protocol/proto.scala

Crash on transitively duplicate moduleDeps in 0.1.5

Exception in thread "main" java.lang.IllegalArgumentException: requirement failed
	at scala.Predef$.require(Predef.scala:268)
	at seed.artefact.ArtefactResolution$.resolveScalaCompiler(ArtefactResolution.scala:246)
	at seed.generation.Bloop$.$anonfun$writeJsModule$1(Bloop.scala:197)
	at seed.generation.Bloop$.$anonfun$writeJsModule$1$adapted(Bloop.scala:148)
	at scala.Option.foreach(Option.scala:274)
	at seed.generation.Bloop$.writeJsModule(Bloop.scala:148)
	at seed.generation.Bloop$.buildModule(Bloop.scala:474)
	at seed.generation.Bloop$.$anonfun$build$2(Bloop.scala:621)
	at seed.generation.Bloop$.$anonfun$build$2$adapted(Bloop.scala:607)
	at scala.collection.immutable.HashMap$HashMap1.foreach(HashMap.scala:234)
	at scala.collection.immutable.HashMap$HashTrieMap.foreach(HashMap.scala:465)
	at seed.generation.Bloop$.build(Bloop.scala:607)
	at seed.cli.Generate$.ui(Generate.scala:56)
	at seed.Cli$.main(Cli.scala:300)
	at seed.Cli.main(Cli.scala)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at coursier.bootstrap.launcher.a.a(Unknown Source)
	at coursier.bootstrap.launcher.Launcher.main(Unknown Source)

Some weird output while showing progress

Running a simple build on an example project I created I'm getting on the console some weird output at the beginning of lines which don't appear to be exactly what is expected.

I'm using Konsole as terminal on archlinux and fish as a shell.

Output example:

~/d/p/s/ineninaru (master|✚3…) $ seed-jvm build client
ⓘ Loading project build.toml...
ⓘ Build path: build
ⓘ Running command 'bloop bsp --socket /tmp/seed-bsp-1588453340125.socket'...
  Working directory: /home/diaz/dev/personal/scala/ineninaru
  Module source paths: 
↪ Connecting to BSP...
  PID: 82159
↪ [BSP] The server is listening for incoming connections at local:///tmp/seed-bsp-1588453340125.socket...
↪ Connecting to BSP...
↪ [BSP] Accepted incoming BSP client connection at local:///tmp/seed-bsp-1588453340125.socket
↪ [BSP] request received: build/initialize
↪ [BSP] BSP initialization handshake complete.
ⓘ Compiling 2 modules...
↪ Module client: /home/diaz/dev/personal/scala/ineninaru/build/bloop/client/bloop-bsp-clients-classes/client-bloop-7KZaZ2OkRfCKPg8WT0x2aA==/
↪ Module protocol: /home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/bloop-bsp-clients-classes/protocol-bloop-7KZaZ2OkRfCKPg8WT0x2aA==/
✗ [D] Computing sources and classpath hashes for protocol
✗ [D] Scheduling compilation for protocol...
✗ [D] Ignoring analysis for protocol, directory /home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/bloop-internal-classes/protocol-bloop-we_SxNmbRqyHlb7c7bl1iA==-Ha_vAgQFSZG5zPrSlq6BDw== is missing
✗ [D] Increasing counter for /home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-protocol to 1
✗ [D] Cache hit true for plugin /home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/kind-projector_2.13.2/0.11.0/kind-projector_2.13.2-0.11.0.jar
✗ [D] Cache hit true for plugin /home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/com/olegpy/better-monadic-for_2.13/0.3.1/better-monadic-for_2.13-0.3.1.jar
✗ [D] Cache hit true for plugin /home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.2/4.3.10/semanticdb-scalac_2.13.2-4.3.10.jar
✗ [D] Cache hit true for plugin /home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/io/tryp/splain_2.13.2/0.5.5/splain_2.13.2-0.5.5.jar
✗ [D] External classes directory /home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/bloop-bsp-clients-classes/protocol-bloop-7KZaZ2OkRfCKPg8WT0x2aA==
✗ [D] Read-only classes directory /home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-protocol
✗ [D] New rw classes directory /home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/bloop-internal-classes/protocol-bloop-7KZaZ2OkRfCKPg8WT0x2aA==-gB_iHaXOShGqgBAmm9Z7Vw==
✗ [D] No previous setup found, invalidating everything.
✗ [D] Full compilation, no sources in previous analysis.
✗ [D] All sources are invalidated.
✗ [D] Initial set of included nodes: 
✗ [D] Recompiling all sources: number of invalidated sources > 50.0% of all sources
✗ [D] [zinc] Running cached compiler 5856cd63 for Scala compiler version 2.13.2
✗ [D] [zinc] The Scala compiler is invoked with:
✗ ⠿] pro-Ycache-plugin-class-loader:last-modified
✗ ⠿] pro-encoding
✗ ⠿] proUTF-8
✗ ⠿] pro-unchecked
✗ ⠿] pro-deprecation
✗ ⠿] pro-feature
✗ ⠿] pro-Yrangepos
✗ ⠿] pro-Ywarn-numeric-widen
✗ ⠿] pro-Ywarn-unused:imports
✗ ⠿] pro-Ywarn-value-discard
✗ ⠿] pro-Ywarn-dead-code
✗ ⠿] pro-Xlint:adapted-args
✗ ⠿] pro-Xlint:infer-any
✗ ⠿] pro-Xlint:missing-interpolator
✗ ⠿] pro-Xlint:private-shadow
✗ ⠿] pro-Xlint:type-parameter-shadow
✗ ⠿] pro-Xplugin:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.2/4.3.10/semanticdb-scalac_2.13.2-4.3.10.jar
✗ ⠿] pro-Xplugin:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/io/tryp/splain_2.13.2/0.5.5/splain_2.13.2-0.5.5.jar
✗ ⠿] pro-Xplugin:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/com/olegpy/better-monadic-for_2.13/0.3.1/better-monadic-for_2.13-0.3.1.jar
✗ ⠿] pro-Xplugin:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/kind-projector_2.13.2/0.11.0/kind-projector_2.13.2-0.11.0.jar
✗ ⠿] pro-bootclasspath
✗ ⠿] pro/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.2/scala-library-2.13.2.jar
✗ ⠿] pro-classpath
✗ ⠿] pro/home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/bloop-internal-classes/protocol-bloop-7KZaZ2OkRfCKPg8WT0x2aA==-gB_iHaXOShGqgBAmm9Z7Vw==:/home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-protocol:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.13.2/scala-reflect-2.13.2.jar
✗ [D] Recording new last successful request for protocol associated with /home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/bloop-internal-classes/protocol-bloop-7KZaZ2OkRfCKPg8WT0x2aA==-gB_iHaXOShGqgBAmm9Z7Vw==
✗ [D] Writing analysis to /home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/analysis.bin...
✗ [D] Computing sources and classpath hashes for client
✗ [D] Wrote analysis to /home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/analysis.bin...
✗ [D] Scheduling compilation for client...
✗ [D] Ignoring analysis for client, directory /home/diaz/dev/personal/scala/ineninaru/build/bloop/client/bloop-internal-classes/client-bloop-we_SxNmbRqyHlb7c7bl1iA==-b5fegG_DS66dyE3nCfNeBw== is missing
✗ [D] Increasing counter for /home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-client to 1
✗ [D] Cache hit true for plugin /home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/io/tryp/splain_2.13.2/0.5.5/splain_2.13.2-0.5.5.jar
✗ [D] Cache hit true for plugin /home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/com/olegpy/better-monadic-for_2.13/0.3.1/better-monadic-for_2.13-0.3.1.jar
✗ [D] Cache hit true for plugin /home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.2/4.3.10/semanticdb-scalac_2.13.2-4.3.10.jar
✗ [D] Cache hit true for plugin /home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/kind-projector_2.13.2/0.11.0/kind-projector_2.13.2-0.11.0.jar
✗ [D] External classes directory /home/diaz/dev/personal/scala/ineninaru/build/bloop/client/bloop-bsp-clients-classes/client-bloop-7KZaZ2OkRfCKPg8WT0x2aA==
✗ [D] Read-only classes directory /home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-client
✗ [D] New rw classes directory /home/diaz/dev/personal/scala/ineninaru/build/bloop/client/bloop-internal-classes/client-bloop-7KZaZ2OkRfCKPg8WT0x2aA==-qLNu4u1hQMaivXURXm0Z6g==
✗ [D] No previous setup found, invalidating everything.
✗ [D] Full compilation, no sources in previous analysis.
✗ [D] All sources are invalidated.
✗ [D] Initial set of included nodes: 
✗ [D] Recompiling all sources: number of invalidated sources > 50.0% of all sources
✗ [D] [zinc] Running cached compiler 2e544985 for Scala compiler version 2.13.2
✗ [D] [zinc] The Scala compiler is invoked with:
✗ ✓] pro-Ycache-plugin-class-loader:last-modified
✗ ✓] pro-encoding
✗ ✓] proUTF-8
✗ ✓] pro-unchecked
✗ ✓] pro-deprecation
✗ ✓] pro-feature
✗ ✓] pro-Yrangepos
✗ ✓] pro-Ywarn-numeric-widen
✗ ✓] pro-Ywarn-unused:imports
✗ ✓] pro-Ywarn-value-discard
✗ ✓] pro-Ywarn-dead-code
✗ ✓] pro-Xlint:adapted-args
✗ ✓] pro-Xlint:infer-any
✗ ✓] pro-Xlint:missing-interpolator
✗ ✓] pro-Xlint:private-shadow
✗ ✓] pro-Xlint:type-parameter-shadow
✗ ✓] pro-Xplugin:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.2/4.3.10/semanticdb-scalac_2.13.2-4.3.10.jar
✗ ✓] pro-Xplugin:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/io/tryp/splain_2.13.2/0.5.5/splain_2.13.2-0.5.5.jar
✗ ✓] pro-Xplugin:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/com/olegpy/better-monadic-for_2.13/0.3.1/better-monadic-for_2.13-0.3.1.jar
✗ ✓] pro-Xplugin:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/kind-projector_2.13.2/0.11.0/kind-projector_2.13.2-0.11.0.jar
✗ ✓] pro-bootclasspath
✗ ✓] pro/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.2/scala-library-2.13.2.jar
✗ ✓] pro-classpath
✗ ✓] pro/home/diaz/dev/personal/scala/ineninaru/build/bloop/client/bloop-internal-classes/client-bloop-7KZaZ2OkRfCKPg8WT0x2aA==-qLNu4u1hQMaivXURXm0Z6g==:/home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-client:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/com/softwaremill/sttp/model/core_2.13/1.0.0/core_2.13-1.0.0.jar:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.13.2/scala-reflect-2.13.2.jar:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/dev/zio/izumi-reflect-thirdparty-boopickle-shaded_2.13/0.12.0-M0/izumi-reflect-thirdparty-boopickle-shaded_2.13-0.12.0-M0.jar:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/dev/zio/zio_2.13/1.0.0-RC18-2/zio_2.13-1.0.0-RC18-2.jar:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/dev/zio/zio-streams_2.13/1.0.0-RC18-2/zio-streams_2.13-1.0.0-RC18-2.jar:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/dev/zio/zio-stacktracer_2.13/1.0.0-RC18-2/zio-stacktracer_2.13-1.0.0-RC18-2.jar:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/com/softwaremill/sttp/client/core_2.13/2.0.0/core_2.13-2.0.0.jar:/home/diaz/.cache/coursier/v1/https/repo1.maven.org/maven2/dev/zio/izumi-reflect_2.13/0.12.0-M0/izumi-reflect_2.13-0.12.0-M0.jar:/home/diaz/dev/personal/scala/ineninaru/build/bloop/protocol/bloop-internal-classes/protocol-bloop-7KZaZ2OkRfCKPg8WT0x2aA==-gB_iHaXOShGqgBAmm9Z7Vw==:/home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-protocol
✗ [D] Writing analysis to /home/diaz/dev/personal/scala/ineninaru/build/bloop/client/analysis.bin...
✗ [D] Recording new last successful request for client associated with /home/diaz/dev/personal/scala/ineninaru/build/bloop/client/bloop-internal-classes/client-bloop-7KZaZ2OkRfCKPg8WT0x2aA==-qLNu4u1hQMaivXURXm0Z6g==
✗ [D] Skipping delete of empty classes dir /home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-protocol
✗ [D] Wrote analysis to /home/diaz/dev/personal/scala/ineninaru/build/bloop/client/analysis.bin...
✗ [D] Skipping delete of empty classes dir /home/diaz/dev/personal/scala/ineninaru/build/bloop/classes-empty-client
 [✓] protocol (JVM) [██████████████████████████████████████████████████████████]
 [✓] client (JVM)   [██████████████████████████████████████████████████████████]
↪ [BSP] shutdown request received: build/shutdown
↪ BSP server cancelled, closing socket...
↪ Process terminated successfully

Specifically those lines starting with the symbols ✗ and have a "pro" word joined with the compiler flags.

Regenerate Bloop project in run

If I add this to a script seed (chmod +x) and place in PATH then I run

seed run example:js

It does not work.

To explain what it does do, it downloads seed as an executable script to the current directory and exists.

Now I attempt to run

./seed run example:js

It fails with error

ⓘ Loading project build.toml...
ⓘ Build path: build
ⓘ Running command 'bloop bsp --socket /var/folders/_f/hdpyzm_n6xj0mc5z58_b0gfh0000gp/T/seed-bsp-1581629844458.socket'...
  Working directory: /Users/philip/home/projects/seedexample
↪ Connecting to BSP...
  PID: 33658
↪ Connecting to BSP...
↪ [BSP] The server is listening for incoming connections at local:///var/folders/_f/hdpyzm_n6xj0mc5z58_b0gfh0000gp/T/seed-bsp-1581629844458.socket...
↪ Connecting to BSP...
↪ [BSP] Accepted incoming BSP client connection at local:///var/folders/_f/hdpyzm_n6xj0mc5z58_b0gfh0000gp/T/seed-bsp-1581629844458.socket
↪ [BSP] request received: build/initialize
↪ [BSP] BSP initialization handshake complete.
ⓘ Compiling 1 modules...
ⓘ No project associated with Uri(file:///Users/philip/home/projects/seedexample/?id=example-js)
 [⠿] example (JavaScript) [░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░]
↪ [BSP] shutdown request received: build/shutdown
↪ BSP server cancelled, closing socket...
↪ Process terminated successfully

Your script

# Use latest released version
version=$(curl https://api.github.com/repos/tindzk/seed/tags | jq -r '.[0].name')

# Use pre-release version
version=$(curl https://api.bintray.com/packages/tindzk/maven/seed | jq -r '.latest_version')

blp-coursier bootstrap \
    -r bintray:tindzk/maven \
    tindzk:seed_2.12:$version \
    -f -o seed

update command has trouble wit zio version

Running the seed update command on version 0.1.7 works fine for almost all dependencies but zio.

Since zio is using some weird version schemes it is reporting the following:

⬀ Dependency dev.zio:zio has a new version (1.0.0-RC18-2 → 1.0.0-RC18)
⬀ Dependency dev.zio:zio-streams has a new version (1.0.0-RC18-2 → 1.0.0-RC18)

The latest version is the one with the -2 at the end.

Support scalajs-bundler (+ sbt-web-scalajs) workflow

  1. Allow generating a separate file for libraries vs. application
  2. Add an npmDeps setting
  3. Support setting bloop JS module kind to commonjs so @JSImport works
  4. Generate package.json and webpack config and run webpack (this could be a custom target if there were a way to get all transitive dependencies' npmDeps
  5. For libraries, create a file like scalajs-bundler does so that npm dependencies can be propagated
  6. JVM app should be able to "depend" on output of linking JS app so seed does it, and get the result in its classpath

Faster Space Development and Improvement | Popularising and Evangelism

Since Bloop is done by Scala Centre I was wondering if maybe handing this over to Scala Centre / Bloop Team if they are willing might improve the development speed. This is definitely a refreshing alternative to other JVM build tools. Also this move might help popularise it a bit more leading to more adaptation.

Metals support

I've been playing around with this little build tool and I really like the feel of it so far. One problem though is metals integration.

It seems like seed doesn't generate everything metals need to be happy. For instance, the resolution.modules path is completely empty. By adding modules manually I was able to get "go to definition" working for the Scala library, but obviously this is not feasible to do for every resolved artifact in the build, especially as things get larger and definitions need to be updated.

It is also a bit tricky—but manageable—to add the required semanticdb compiler plugin to the build: resolving the plugin itself is dead easy with compilerDeps, but the user also needs to manually add full plugin path to the scalaOptions, along with a few plugin-specific settings. At least the path could be added automatically.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.