/sbt-hackling

Prototype of the Libling concept. Libling is a way to add source dependencies to your sbt project.

Primary LanguageScalaApache License 2.0Apache-2.0

Gitter chat Build Status Download

sbt-hackling

Hackathon implementation of the Libling concept. It's a prototype. It works, but exactly what and how works might break at any time.

This is an experimental platform. You are encouraged to submit changes. Almost anything will be accepted without much fuss.

Libling

Libling is a way to add dependencies to your project as plain Scala sources. It is intended for simple snippets of code or small libraries (for now).

Motivation

  • Publishing simple libraries is unnecessarily hard in JVM land. Why not just push to GitHub and be done with it?
  • Even when code is source compatible with multiple Scala versions, need to cross-build it. Makes builds more complicated!
  • With scala.js and Scala Native, even more cross building is necessary!
  • Classical major.minor.bugfix versioning is a hack! A git commit graph is closer to what's going on, a commit hash uniquely identifies a version and its history.
  • take advantage of distributed VCS possibilities. Cloning a repo mirrors all the versions so far, can be cached. Does not require single-source-of-truth centralized infrastructure. This makes forking trivial.

Actually the latter two are the true motivation and the first three are a way to justify a practical experiment

Features

  • declare dependencies on liblings in your build.sbt via git commit hash
  • a commit hash may be resolved from remote and local repos
  • dependencies are resolved transitively
  • repos are cached locally
  • install them as sources, including markdown docs

Still kind of missing features

  • friendly DSL
  • finding and resolving dependency conflicts by eviction or something
  • resolving conflicts by rewriting packages
  • a way to upgrade dependencies automatically
  • automatic index of liblings with a task to publish a libling
  • (maybe) resolving binary dependencies. For now it's assumed a libling only depends on the Scala stdlib.

Not in scope

  • advanced builds. Liblings have a fixed structure and only depend on other liblings. But your build can depend on both liblings and regular binary libraries.

To use a libling

Add this plugin:

resolvers += Resolver.bintrayIvyRepo("jastice","sbt-plugins")
addSbtPlugin("libling" % "sbt-hackling" % "0.4.0")

Add a libling source dependency by commit hash:

sourceDependencies += Dependency(
        HashVersion("<git commit long hash>"),
        Repositories(uri("<https git repository uri>")))

Add a libling source dependency by tag or branch name:

sourceDependencies += Dependency(
        NameVersion("<tag or branch>"),
        Repositories(uri("<https git repository uri>")))

On the sbt shell:

> liblingInstall

This will:

  • cache repos locally in <user home>/.libling/cache
  • copy sources and docs out of the repos into your project under target/libling/
  • generate a /libling directory in your project that contains a lock file that exactly identifies the commit hashes you depend on and the repos where they were found

Examples

To create a libling

sbt new libling/libling.g8

See libling.g8 for details.

structure

A libling is just a bunch of code in a certain structure. When you include a libling into your sbt project, some code gets dumped into your /target/libling directory and becomes part of your build.

  • README.md documentation root. can link to further docs in /doc directory.
  • /src Contains plain Scala sources, no main/ test/ etc. Always included on libling resolution. We'll figure out later how to build more complicated stuff.
  • /doc .md sources - included by default.
  • /libling
    • lock: the libling's own libling dependencies, including transitive dependencies. Commit hashes only. These are generated by the liblingUpdate task and should not be manually edited. A libling can only depend on other liblings. We'll figure out how to handle necessary binary deps (e.g. scala version) later. HOCON format.
    • meta: useful metadata where to look up the commit hashes. Can be generated by liblingGenerateMetadata task. HOCON format.
  • /test
    • tests go in here. Not included as dependency by default.

Inspirations