thoughtworksinc / import.scala

A Scala compiler plugin for magic imports

Version Matrix

Import.scala

Build Status

Import.scala is a Scala compiler plugin that enables magic imports.

Setup

addCompilerPlugin("com.thoughtworks.import" %% "import" % "latest.release")

Magic Imports

This plugin provides a set of magic imports that let you load additional code into a Scala source file: these are imports which start with a $.

The syntax is similar to magic imports in Ammonite.

import $file

This lets you load code snippets into current source file. For example given a small script defining one value we want

// MyScript.sc
val elite = 31337

We can load it into our current source file using:

import $file.MyScript
assert(MyScript.elite == 31337)

If the script is in a sub-folder, simply use:

import $file.myfolder.MyScript

Or if the script is in an outer folder,

import $file.`..`.MyScript

Or if you want to import the contents of the script in one go:

import $file.MyScript, MyScript._
assert(elite == 31337)

Or if you want to download the script from a website:

import $file.`https://gist.github.com/Atry/5dcb1414b804fd7679393cacac3c89fc/raw/5b1748ab6b45c00be0109686fdb25e85cde11ce0/include-example.sc`
assert(`https://gist.github.com/Atry/5dcb1414b804fd7679393cacac3c89fc/raw/5b1748ab6b45c00be0109686fdb25e85cde11ce0/include-example.sc`.i == 42)

Or if you prefer using dot as the path separator:

import $file.`https://gist.github.com`.Atry.`5dcb1414b804fd7679393cacac3c89fc`.raw.`5b1748ab6b45c00be0109686fdb25e85cde11ce0`.`include-example`
assert(`include-example`.i == 42)

While this is a trivial example, your MyScript.sc file can contain anything you want, not just vals: function defs, classes objects or traits, or imports from other scripts.

Cannot directly import from inside a Script

You cannot import things from "inside" that script in one chain:

import $file.MyScript._

Rather, you must always import the script-object first, and then import things from the script object after:

import $file.MyScript, MyScript._

Renamed-scripts and multiple-scripts

You can re-name scripts on-import if you find their names are colliding:

import $file.{MyScript => FooBarScript}, FooBarScript._

Or re-name a URL:

import $file.{ `https://gist.github.com/Atry/5dcb1414b804fd7679393cacac3c89fc/raw/5b1748ab6b45c00be0109686fdb25e85cde11ce0/include-example.sc` => Renamed}
assert(Renamed.i == 42)

Or import multiple scripts at once

import $file.{MyScript, MyOtherScript}

These behave as you would expect imports to work. Note that when importing multiple scripts, you have to name them explicitly and cannot use wildcard ._ imports:

import $file._ // doesn't work

import $url

import $url is an alias to import $file.

import $exec

This is similar to import $file, except that it dumps the definitions and imports from the script into your current source file. This is useful if you are using a script to hold a set of common imports.

import $exec.MyScript
assert(elite == 31337)
import $exec.`https://gist.github.com/Atry/5dcb1414b804fd7679393cacac3c89fc/raw/5b1748ab6b45c00be0109686fdb25e85cde11ce0/include-example.sc`
assert(i == 42)

Acknowledgements

The examples in this README.md file is based on Li Haoyi's Ammonite document and copyright licensed under MIT. See the Markdown source.