summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml34
-rw-r--r--.travis.yml23
-rwxr-xr-xbuild.sc15
-rwxr-xr-xci/publish-local.sh2
-rwxr-xr-xci/test-mill-dev.sh2
-rwxr-xr-xci/test-mill-release.sh2
-rw-r--r--clientserver/src/mill/clientserver/Client.java57
-rw-r--r--clientserver/src/mill/clientserver/ClientServer.java8
-rw-r--r--clientserver/src/mill/clientserver/Server.scala37
-rw-r--r--core/src/mill/util/ClassLoader.scala19
-rw-r--r--docs/pages/1 - Intro to Mill.md42
-rw-r--r--docs/pages/6 - Extending Mill.md4
-rw-r--r--integration/test/src/mill/integration/AcyclicTests.scala2
-rw-r--r--integration/test/src/mill/integration/UpickleTests.scala15
-rw-r--r--main/src/mill/main/MainModule.scala2
-rw-r--r--main/src/mill/modules/Jvm.scala41
-rw-r--r--main/test/src/mill/eval/JavaCompileJarTests.scala2
-rw-r--r--main/test/src/mill/util/TestUtil.scala5
-rw-r--r--readme.md53
-rw-r--r--scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSBridge.scala14
-rw-r--r--scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSBridge.scala14
-rw-r--r--scalajslib/src/mill/scalajslib/ScalaJSBridge.scala19
-rw-r--r--scalajslib/src/mill/scalajslib/ScalaJSModule.scala17
-rw-r--r--scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala28
-rw-r--r--scalajslib/test/src/mill/scalajslib/MultiModuleTests.scala4
-rw-r--r--scalalib/src/mill/scalalib/ScalaModule.scala17
-rw-r--r--scalalib/src/mill/scalalib/ScalaWorkerApi.scala4
-rw-r--r--scalalib/test/src/mill/scalalib/HelloWorldTests.scala4
-rw-r--r--scalaworker/src/mill/scalaworker/ScalaWorker.scala10
29 files changed, 367 insertions, 129 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 8fa75778..a8c4da3a 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -9,20 +9,40 @@ clone_folder: c:\mill
environment:
matrix:
+ - COMPILER: cygwin
+ CYGWIN_DIR: cygwin64
+ JAVA_HOME: C:\Program Files\Java\jdk9
- COMPILER: msys2
- PLATFORM: x64
MSYS2_ARCH: x86_64
MSYS2_DIR: msys64
MSYSTEM: MINGW64
- BIT: 64
- JAVA_HOME: 'C:\Program Files\Java\jdk1.8.0'
- PATH: '%JAVA_HOME%\bin;C:\bin;C:\%MSYS2_DIR%\%MSYSTEM%\bin;C:\%MSYS2_DIR%\usr\bin;%PATH%'
+ JAVA_HOME: C:\Program Files\Java\jdk1.8.0
+ - COMPILER: msys2
+ MSYS2_ARCH: x86_64
+ MSYS2_DIR: msys64
+ MSYSTEM: MINGW64
+ JAVA_HOME: C:\Program Files\Java\jdk9
cache:
- - '%LOCALAPPDATA%\Coursier\cache'
+ - build.sc -> '%LOCALAPPDATA%\Coursier\cache'
install:
- - bash -lc "mkdir /c/bin && curl -Lo /c/bin/mill https://github.com/lihaoyi/mill/releases/download/0.1.4/0.1.4-12-f5250d"
+ - SET MILL_URL=https://github.com/lihaoyi/mill/releases/download/0.1.6/0.1.6-3-43d230
build_script:
- - bash -lc "cd /c/mill && mill -i all main.test scalajslib.test"
+ - if [%COMPILER%]==[msys2] (
+ SET "PATH=%JAVA_HOME%\bin;C:\%MSYS2_DIR%\%MSYSTEM%\bin;C:\%MSYS2_DIR%\usr\bin;%PATH%" &&
+ C:\%MSYS2_DIR%\usr\bin\bash -lc 'mkdir -p /usr/local/bin' &&
+ C:\%MSYS2_DIR%\usr\bin\bash -lc "curl -Lo /usr/local/bin/mill %MILL_URL%" &&
+ C:\%MSYS2_DIR%\usr\bin\bash -lc 'chmod +x /usr/local/bin/mill' &&
+ C:\%MSYS2_DIR%\usr\bin\bash -lc "cd /c/mill && mill -i all __.publishLocal release" &&
+ C:\%MSYS2_DIR%\usr\bin\bash -lc "cd /c/mill && out/release/dest/mill all main.test scalajslib.test")
+ - if [%COMPILER%]==[cygwin] (
+ SET "PATH=%JAVA_HOME%\bin;C:\%CYGWIN_DIR%\bin;C:\%CYGWIN_DIR%\usr\bin;%PATH%" &&
+ C:\%CYGWIN_DIR%\bin\bash -lc 'mkdir -p /usr/local/bin' &&
+ C:\%CYGWIN_DIR%\bin\bash -lc "curl -Lo /usr/local/bin/mill %MILL_URL%" &&
+ C:\%CYGWIN_DIR%\bin\bash -lc 'sed -i '"'"'0,/-cp "\$0"/{s/-cp "\$0"/-cp `cygpath -w "\$0"`/}; 0,/-cp "\$0"/{s/-cp "\$0"/-cp `cygpath -w "\$0"`/}'"'"' /usr/local/bin/mill' &&
+ C:\%CYGWIN_DIR%\bin\bash -lc 'chmod +x /usr/local/bin/mill' &&
+ C:\%CYGWIN_DIR%\bin\bash -lc "cd /cygdrive/c/mill && mill -i all main.test scalajslib.test")
+
+skip_branch_with_pr: true \ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 45373358..3898dbfa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,31 +2,44 @@ language: scala
sudo: required
dist: trusty
-jdk:
- - oraclejdk8
-
matrix:
include:
- stage: build
env: CI_SCRIPT=ci/test-mill-0.sh
+ jdk: oraclejdk9
+ - stage: build
+ env: CI_SCRIPT=ci/test-mill-0.sh
+ jdk: oraclejdk8
- stage: build
env: CI_SCRIPT=ci/test-mill-1.sh
+ jdk: oraclejdk8
- stage: build
env: CI_SCRIPT=ci/test-mill-2.sh
+ jdk: oraclejdk8
- stage: build
env: CI_SCRIPT=ci/test-mill-dev.sh
+ jdk: oraclejdk9
+ - stage: build
+ env: CI_SCRIPT=ci/test-mill-dev.sh
+ jdk: oraclejdk8
+ - stage: build
+ env: CI_SCRIPT=ci/test-mill-release.sh
+ jdk: oraclejdk9
- stage: build
env: CI_SCRIPT=ci/test-mill-release.sh
+ jdk: oraclejdk8
- stage: release
env: CI_SCRIPT="ci/on-master.py ci/release.sh"
+ jdk: oraclejdk8
- stage: release
env: CI_SCRIPT="ci/on-master.py ci/publish-docs.sh"
+ jdk: oraclejdk8
script:
- - curl -L -o ~/bin/mill https://github.com/lihaoyi/mill/releases/download/0.1.3/0.1.3 && chmod +x ~/bin/mill
+ - curl -L -o ~/bin/mill https://github.com/lihaoyi/mill/releases/download/0.1.6/0.1.6 && chmod +x ~/bin/mill
- export PATH=~/bin/mill:$PATH
- "$CI_SCRIPT"
cache:
directories:
- - $HOME/.coursier \ No newline at end of file
+ - $HOME/.coursier
diff --git a/build.sc b/build.sc
index 63c4c362..c012c77b 100755
--- a/build.sc
+++ b/build.sc
@@ -69,6 +69,7 @@ trait MillModule extends MillPublishModule{ outer =>
object clientserver extends MillModule{
def ivyDeps = Agg(
+ ivy"com.lihaoyi:::ammonite:1.0.5-4-c0cdbaf",
ivy"org.scala-sbt.ipcsocket:ipcsocket:1.0.0"
)
val test = new Tests(implicitly)
@@ -83,7 +84,7 @@ object core extends MillModule {
def ivyDeps = Agg(
ivy"com.lihaoyi::sourcecode:0.1.4",
- ivy"com.lihaoyi:::ammonite:1.0.5",
+ ivy"com.lihaoyi:::ammonite:1.0.5-4-c0cdbaf",
ivy"jline:jline:2.14.5"
)
@@ -235,11 +236,13 @@ object dev extends MillModule{
write(outputPath, prependShellScript())
- val perms = java.nio.file.Files.getPosixFilePermissions(outputPath.toNIO)
- perms.add(PosixFilePermission.GROUP_EXECUTE)
- perms.add(PosixFilePermission.OWNER_EXECUTE)
- perms.add(PosixFilePermission.OTHERS_EXECUTE)
- java.nio.file.Files.setPosixFilePermissions(outputPath.toNIO, perms)
+ if (!scala.util.Properties.isWin) {
+ val perms = java.nio.file.Files.getPosixFilePermissions(outputPath.toNIO)
+ perms.add(PosixFilePermission.GROUP_EXECUTE)
+ perms.add(PosixFilePermission.OWNER_EXECUTE)
+ perms.add(PosixFilePermission.OTHERS_EXECUTE)
+ java.nio.file.Files.setPosixFilePermissions(outputPath.toNIO, perms)
+ }
PathRef(outputPath)
}
diff --git a/ci/publish-local.sh b/ci/publish-local.sh
index fc9e06b9..c137340d 100755
--- a/ci/publish-local.sh
+++ b/ci/publish-local.sh
@@ -2,6 +2,6 @@
set -eux
-mill all __.publishLocal release
+mill -i all __.publishLocal release
mv out/release/dest/mill ~/mill-release
diff --git a/ci/test-mill-dev.sh b/ci/test-mill-dev.sh
index cb83ef00..11d64154 100755
--- a/ci/test-mill-dev.sh
+++ b/ci/test-mill-dev.sh
@@ -6,7 +6,7 @@ set -eux
git clean -xdf
# Build Mill using SBT
-mill dev.assembly
+mill -i dev.assembly
# Second build & run tests using Mill
out/dev/assembly/dest/mill -i all {clientserver,main,scalalib,scalajslib}.test
diff --git a/ci/test-mill-release.sh b/ci/test-mill-release.sh
index 3c70410b..8c0aca2f 100755
--- a/ci/test-mill-release.sh
+++ b/ci/test-mill-release.sh
@@ -11,4 +11,4 @@ git clean -xdf
# Second build & run tests using Mill
-~/mill-release integration.test "mill.integration.forked.{AcyclicTests,UpickleTests}"
+~/mill-release -i integration.test "mill.integration.forked.{AcyclicTests,UpickleTests}"
diff --git a/clientserver/src/mill/clientserver/Client.java b/clientserver/src/mill/clientserver/Client.java
index 1870c8a4..eab8c5b5 100644
--- a/clientserver/src/mill/clientserver/Client.java
+++ b/clientserver/src/mill/clientserver/Client.java
@@ -1,29 +1,40 @@
package mill.clientserver;
-import org.scalasbt.ipcsocket.UnixDomainSocket;
+import io.github.retronym.java9rtexport.Export;
+import org.scalasbt.ipcsocket.*;
import java.io.*;
+import java.net.Socket;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.FileChannel;
+import java.nio.file.Files;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.Properties;
public class Client {
- static void initServer(String lockBase) throws IOException{
- StringBuilder selfJars = new java.lang.StringBuilder();
+ static void initServer(String lockBase, boolean setJnaNoSys) throws IOException,URISyntaxException{
+ ArrayList<String> selfJars = new ArrayList<String>();
ClassLoader current = Client.class.getClassLoader();
while(current != null){
if (current instanceof java.net.URLClassLoader) {
URL[] urls = ((java.net.URLClassLoader) current).getURLs();
for (URL url: urls) {
- if (selfJars.length() != 0) selfJars.append(':');
- selfJars.append(url);
+ selfJars.add(new File(url.toURI()).getCanonicalPath());
}
}
current = current.getParent();
}
-
+ if (!System.getProperty("java.specification.version").startsWith("1.")) {
+ selfJars.addAll(Arrays.asList(System.getProperty("java.class.path").split(File.pathSeparator)));
+ File rtFile = new File(lockBase + "/rt-" + System.getProperty("java.version") + ".jar");
+ if (!rtFile.exists()) {
+ Files.copy(Export.export().toPath(), rtFile.toPath());
+ }
+ selfJars.add(rtFile.getCanonicalPath());
+ }
ArrayList<String> l = new java.util.ArrayList<String>();
l.add("java");
Properties props = System.getProperties();
@@ -32,8 +43,11 @@ public class Client {
String k = keys.next();
if (k.startsWith("MILL_")) l.add("-D" + k + "=" + props.getProperty(k));
}
+ if (setJnaNoSys) {
+ l.add("-Djna.nosys=true");
+ }
l.add("-cp");
- l.add(selfJars.toString());
+ l.add(String.join(File.pathSeparator, selfJars));
l.add("mill.ServerMain");
l.add(lockBase);
new java.lang.ProcessBuilder()
@@ -43,6 +57,10 @@ public class Client {
.start();
}
public static void main(String[] args) throws Exception{
+ boolean setJnaNoSys = System.getProperty("jna.nosys") == null;
+ if (setJnaNoSys) {
+ System.setProperty("jna.nosys", "true");
+ }
int index = 0;
while (index < 5) {
index += 1;
@@ -61,8 +79,8 @@ public class Client {
@Override
public void run() {
try{
- initServer(lockBase);
- }catch(IOException e){
+ initServer(lockBase, setJnaNoSys);
+ }catch(Exception e){
throw new RuntimeException(e);
}
}
@@ -91,16 +109,26 @@ public class Client {
FileOutputStream f = new FileOutputStream(lockBase + "/run");
ClientServer.writeArgs(System.console() != null, args, f);
f.close();
- if (locks.processLock.probe()) initServer.run();
+
+ boolean serverInit = false;
+ if (locks.processLock.probe()) {
+ serverInit = true;
+ initServer.run();
+ }
while(locks.processLock.probe()) Thread.sleep(3);
+ // Need to give sometime for Win32NamedPipeSocket to work
+ // if the server is just initialized
+ if (serverInit && ClientServer.isWindows) Thread.sleep(250);
- UnixDomainSocket ioSocket = null;
+ Socket ioSocket = null;
long retryStart = System.currentTimeMillis();
while(ioSocket == null && System.currentTimeMillis() - retryStart < 1000){
try{
- ioSocket = new UnixDomainSocket(lockBase + "/io");
+ ioSocket = ClientServer.isWindows?
+ new Win32NamedPipeSocket(ClientServer.WIN32_PIPE_PREFIX + new File(lockBase).getName())
+ : new UnixDomainSocket(lockBase + "/io");
}catch(Throwable e){
Thread.sleep(1);
}
@@ -178,7 +206,10 @@ class ClientOutputPumper implements Runnable{
}
}
}catch(IOException e){
- throw new RuntimeException(e);
+ // Win32NamedPipeSocket input stream somehow doesn't return -1,
+ // but throw IOException whose message contains "ReadFile()" with a ccode
+ if (ClientServer.isWindows && e.getMessage().contains("ReadFile()")) running = false;
+ else throw new RuntimeException(e);
}
}
diff --git a/clientserver/src/mill/clientserver/ClientServer.java b/clientserver/src/mill/clientserver/ClientServer.java
index a8692c61..7af5845b 100644
--- a/clientserver/src/mill/clientserver/ClientServer.java
+++ b/clientserver/src/mill/clientserver/ClientServer.java
@@ -6,6 +6,14 @@ import java.io.InputStream;
import java.io.OutputStream;
class ClientServer {
+ public static boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
+
+ // Windows named pipe prefix (see https://github.com/sbt/ipcsocket/blob/v1.0.0/README.md)
+ // Win32NamedPipeServerSocket automatically adds this as a prefix (if it is not already is prefixed),
+ // but Win32NamedPipeSocket does not
+ // https://github.com/sbt/ipcsocket/blob/v1.0.0/src/main/java/org/scalasbt/ipcsocket/Win32NamedPipeServerSocket.java#L36
+ public static String WIN32_PIPE_PREFIX = "\\\\.\\pipe\\";
+
public static String[] parseArgs(InputStream argStream) throws IOException {
int argsLength = argStream.read();
diff --git a/clientserver/src/mill/clientserver/Server.scala b/clientserver/src/mill/clientserver/Server.scala
index 27c43302..24827ac2 100644
--- a/clientserver/src/mill/clientserver/Server.scala
+++ b/clientserver/src/mill/clientserver/Server.scala
@@ -3,7 +3,7 @@ package mill.clientserver
import java.io._
import java.net.Socket
-import org.scalasbt.ipcsocket.{UnixDomainServerSocket, UnixDomainSocket}
+import org.scalasbt.ipcsocket._
trait ServerMain[T]{
def main(args0: Array[String]): Unit = {
@@ -11,7 +11,7 @@ trait ServerMain[T]{
args0(0),
this,
() => System.exit(0),
- 60000,
+ 300000,
Locks.files(args0(0))
).run()
}
@@ -37,18 +37,28 @@ class Server[T](lockBase: String,
var running = true
while (running) {
Server.lockBlock(locks.serverLock){
- new File(lockBase + "/io").delete()
- val ioSocket = new UnixDomainServerSocket(lockBase + "/io")
+ val (serverSocket, socketClose) = if (ClientServer.isWindows) {
+ val socketName = ClientServer.WIN32_PIPE_PREFIX + new File(lockBase).getName
+ (new Win32NamedPipeServerSocket(socketName), () => new Win32NamedPipeSocket(socketName).close())
+ } else {
+ val socketName = lockBase + "/io"
+ new File(socketName).delete()
+ (new UnixDomainServerSocket(socketName), () => new UnixDomainSocket(socketName).close())
+ }
+
val sockOpt = Server.interruptWith(
acceptTimeout,
- new UnixDomainSocket(lockBase + "/io").close(),
- ioSocket.accept()
+ socketClose(),
+ serverSocket.accept()
)
sockOpt match{
case None => running = false
case Some(sock) =>
- try handleRun(sock)
+ try {
+ handleRun(sock)
+ serverSocket.close()
+ }
catch{case e: Throwable => e.printStackTrace(originalStdout) }
}
}
@@ -106,7 +116,16 @@ class Server[T](lockBase: String,
t.interrupt()
t.stop()
- clientSocket.close()
+
+ if (ClientServer.isWindows) {
+ // Closing Win32NamedPipeSocket can often take ~5s
+ // It seems OK to exit the client early and subsequently
+ // start up mill client again (perhaps closing the server
+ // socket helps speed up the process).
+ val t = new Thread(() => clientSocket.close())
+ t.setDaemon(true)
+ t.start()
+ } else clientSocket.close()
}
}
object Server{
@@ -161,4 +180,4 @@ class ProxyInputStream(x: => java.io.InputStream) extends java.io.InputStream{
override def read(b: Array[Byte], off: Int, len: Int) = x.read(b, off, len)
override def read(b: Array[Byte]) = x.read(b)
}
-case class WatchInterrupted[T](stateCache: Option[T]) extends Exception \ No newline at end of file
+case class WatchInterrupted[T](stateCache: Option[T]) extends Exception
diff --git a/core/src/mill/util/ClassLoader.scala b/core/src/mill/util/ClassLoader.scala
new file mode 100644
index 00000000..a1b42158
--- /dev/null
+++ b/core/src/mill/util/ClassLoader.scala
@@ -0,0 +1,19 @@
+package mill.util
+
+import java.net.{URL, URLClassLoader}
+
+import io.github.retronym.java9rtexport.Export
+
+object ClassLoader {
+ def create(urls: Seq[URL], parent: java.lang.ClassLoader): URLClassLoader = {
+ val cl = new URLClassLoader(urls.toArray, parent)
+ if (!ammonite.util.Util.java9OrAbove) return cl
+ try {
+ cl.loadClass("javax.script.ScriptEngineManager")
+ cl
+ } catch {
+ case _: ClassNotFoundException =>
+ new URLClassLoader((urls ++ Some(Export.export().toURI.toURL)).toArray, parent)
+ }
+ }
+}
diff --git a/docs/pages/1 - Intro to Mill.md b/docs/pages/1 - Intro to Mill.md
index b912bf14..63b69601 100644
--- a/docs/pages/1 - Intro to Mill.md
+++ b/docs/pages/1 - Intro to Mill.md
@@ -17,6 +17,14 @@ external subprocesses.
## Installation
+### OS X
+
+Installation via [homebrew](https://github.com/Homebrew/homebrew-core/blob/master/Formula/mill.rb):
+
+```sh
+brew install mill
+```
+
### Arch Linux
Arch Linux has an [AUR package for mill](https://aur.archlinux.org/packages/mill/):
@@ -31,14 +39,14 @@ To get started, download Mill and install it into your system via the following
`curl`/`chmod` command:
```bash
-sudo curl -L -o /usr/local/bin/mill https://github.com/lihaoyi/mill/releases/download/0.1.4/0.1.4 && sudo chmod +x /usr/local/bin/mill
+sudo curl -L -o /usr/local/bin/mill https://github.com/lihaoyi/mill/releases/download/0.1.6/0.1.6 && sudo chmod +x /usr/local/bin/mill
```
### Development Releases
More recent, unstable versions of Mill are also
[available](https://github.com/lihaoyi/mill/releases/tag/unstable), if you want
-to try out the latest features and improvements that are currently in master.
+to try out the latest features and improvements that are currently in master.
Come by our [Gitter Channel](https://gitter.im/lihaoyi/mill) if you want to ask
questions or say hi!
@@ -97,7 +105,7 @@ $ mill foo.repl # start an Ammonite REPL within your project
```
You can run `mill resolve __` to see a full list of the different tasks that are
-available, `mill resolve foo._` to see the tasks within `foo`, `mill describe
+available, `mill resolve foo._` to see the tasks within `foo`, `mill inspect
foo.compile` to see what an individual task depends on, or `mill show
foo.scalaVersion` to inspect the output of any task.
@@ -320,10 +328,10 @@ mill resolve __ # list every module or task recursively
mill resolve foo.__ # list every task recursively within the foo module
```
-### describe
+### inspect
```bash
-$ mill describe core.run
+$ mill inspect core.run
core.run(ScalaModule.scala:211)
Inputs:
@@ -333,26 +341,26 @@ Inputs:
core.forkEnv
```
-`describe` is a more verbose version of [resolve](#resolve). In addition to
+`inspect` is a more verbose version of [resolve](#resolve). In addition to
printing out the name of one-or-more tasks, it also display's it's source
location and a list of input tasks. This is very useful for debugging and
interactively exploring the structure of your build from the command line.
-`describe` also works with the same `_`/`__` wildcard/query syntaxes that
+`inspect` also works with the same `_`/`__` wildcard/query syntaxes that
[all](#all)/[resolve](#resolve) do:
```bash
-mill describe foo.compile
-mill describe foo.{compile,run}
-mill describe "foo.{compile,run}"
-mill describe foo.compile foo.run
-mill describe _.compile
-mill describe __.compile
-mill describe _
-mill describe foo._
-mill describe __
-mill describe foo._
+mill inspect foo.compile
+mill inspect foo.{compile,run}
+mill inspect "foo.{compile,run}"
+mill inspect foo.compile foo.run
+mill inspect _.compile
+mill inspect __.compile
+mill inspect _
+mill inspect foo._
+mill inspect __
+mill inspect foo._
```
### show
diff --git a/docs/pages/6 - Extending Mill.md b/docs/pages/6 - Extending Mill.md
index a6c096a6..75b7643a 100644
--- a/docs/pages/6 - Extending Mill.md
+++ b/docs/pages/6 - Extending Mill.md
@@ -20,7 +20,7 @@ you're done.
For subprocess/filesystem operations, you can use the
[Ammonite-Ops](http://ammonite.io/#Ammonite-Ops) library that comes bundled with
-Mill, or even plain `java.nio`/`java.lang.Process. Each target gets it's own
+Mill, or even plain `java.nio`/`java.lang.Process`. Each target gets it's own
[T.ctx().dest](http://www.lihaoyi.com/mill/page/tasks#millutilctxdestctx) folder
that you can use to place files without worrying about colliding with other
targets.
@@ -177,7 +177,7 @@ def idea(ev: Evaluator[Any]) = T.command{
```
Many built-in tools are implemented as custom evaluator commands:
-[all](intro.html#all), [describe](intro.html#describe),
+[all](intro.html#all), [inspect](intro.html#inspect),
[resolve](intro.html#resolve), [show](intro.html#show). If you want a way to run Mill
commands and programmatically manipulate the tasks and outputs, you do so with
your own evaluator command.
diff --git a/integration/test/src/mill/integration/AcyclicTests.scala b/integration/test/src/mill/integration/AcyclicTests.scala
index d1035af0..c117f862 100644
--- a/integration/test/src/mill/integration/AcyclicTests.scala
+++ b/integration/test/src/mill/integration/AcyclicTests.scala
@@ -25,7 +25,7 @@ class AcyclicTests(fork: Boolean)
assert(!brokenCompile)
}
- 'scala2118 - check("2.11.8")
+ 'scala2118 - mill.util.TestUtil.disableInJava9OrAbove(check("2.11.8"))
'scala2124 - check("2.12.4")
}
diff --git a/integration/test/src/mill/integration/UpickleTests.scala b/integration/test/src/mill/integration/UpickleTests.scala
index dba6488d..1b83c60f 100644
--- a/integration/test/src/mill/integration/UpickleTests.scala
+++ b/integration/test/src/mill/integration/UpickleTests.scala
@@ -6,12 +6,19 @@ import utest._
class UpickleTests(fork: Boolean) extends IntegrationTestSuite("MILL_UPICKLE_REPO", "upickle", fork) {
val tests = Tests{
initWorkspace()
- 'jvm - {
- assert(eval("upickleJvm[2.11.11].test"))
- val jvmMeta = meta("upickleJvm[2.11.11].test.test")
+ 'jvm21111 - {
+ mill.util.TestUtil.disableInJava9OrAbove({
+ assert(eval("upickleJvm[2.11.11].test"))
+ val jvmMeta = meta("upickleJvm[2.11.11].test.test")
+ assert(jvmMeta.contains("example.ExampleTests.simple"))
+ assert(jvmMeta.contains("upickle.MacroTests.commonCustomStructures.simpleAdt"))
+ })
+ }
+ 'jvm2124 - {
+ assert(eval("upickleJvm[2.12.4].test"))
+ val jvmMeta = meta("upickleJvm[2.12.4].test.test")
assert(jvmMeta.contains("example.ExampleTests.simple"))
assert(jvmMeta.contains("upickle.MacroTests.commonCustomStructures.simpleAdt"))
-
}
'js - {
assert(eval("upickleJs[2.12.4].test"))
diff --git a/main/src/mill/main/MainModule.scala b/main/src/mill/main/MainModule.scala
index 9fa6e4dd..4b0a4354 100644
--- a/main/src/mill/main/MainModule.scala
+++ b/main/src/mill/main/MainModule.scala
@@ -42,7 +42,7 @@ trait MainModule extends mill.Module{
resolved match{
case Left(err) => Result.Failure(err)
case Right(rs) =>
- for(r <- rs){
+ for(r <- rs.sorted) {
println(r)
}
Result.Success(())
diff --git a/main/src/mill/modules/Jvm.scala b/main/src/mill/modules/Jvm.scala
index 153e1959..d71cf75c 100644
--- a/main/src/mill/modules/Jvm.scala
+++ b/main/src/mill/modules/Jvm.scala
@@ -104,7 +104,7 @@ object Jvm {
body: ClassLoader => T): T = {
val cl = if (classLoaderOverrideSbtTesting) {
val outerClassLoader = getClass.getClassLoader
- new URLClassLoader(classPath.map(_.toIO.toURI.toURL).toArray, null){
+ new URLClassLoader(classPath.map(_.toIO.toURI.toURL).toArray, mill.util.ClassLoader.create(Seq(), null)){
override def findClass(name: String) = {
if (name.startsWith("sbt.testing.")){
outerClassLoader.loadClass(name)
@@ -114,7 +114,7 @@ object Jvm {
}
}
} else {
- new URLClassLoader(classPath.map(_.toIO.toURI.toURL).toArray, null)
+ mill.util.ClassLoader.create(classPath.map(_.toIO.toURI.toURL).toVector, null)
}
val oldCl = Thread.currentThread().getContextClassLoader
Thread.currentThread().setContextClassLoader(cl)
@@ -241,7 +241,7 @@ object Jvm {
(implicit ctx: Ctx.Dest) = {
val tmp = ctx.dest / "out-tmp.jar"
- val baseUri = "jar:file:" + tmp
+ val baseUri = "jar:" + tmp.toIO.getCanonicalFile.toURI.toASCIIString
val hm = new java.util.HashMap[String, String]()
base match{
@@ -258,13 +258,18 @@ object Jvm {
manifest.write(manifestOut)
manifestOut.close()
+ def isSignatureFile(mapping: String): Boolean =
+ Set("sf", "rsa", "dsa").exists(ext => mapping.toLowerCase.endsWith(s".$ext"))
+
for(v <- classpathIterator(inputPaths)){
val (file, mapping) = v
val p = zipFs.getPath(mapping)
if (p.getParent != null) Files.createDirectories(p.getParent)
- val outputStream = newOutputStream(p)
- IO.stream(file, outputStream)
- outputStream.close()
+ if (!isSignatureFile(mapping)) {
+ val outputStream = newOutputStream(p)
+ IO.stream(file, outputStream)
+ outputStream.close()
+ }
file.close()
}
zipFs.close()
@@ -278,11 +283,13 @@ object Jvm {
IO.stream(read.getInputStream(tmp), outputStream)
outputStream.close()
- val perms = Files.getPosixFilePermissions(output.toNIO)
- perms.add(PosixFilePermission.GROUP_EXECUTE)
- perms.add(PosixFilePermission.OWNER_EXECUTE)
- perms.add(PosixFilePermission.OTHERS_EXECUTE)
- Files.setPosixFilePermissions(output.toNIO, perms)
+ if (!scala.util.Properties.isWin) {
+ val perms = Files.getPosixFilePermissions(output.toNIO)
+ perms.add(PosixFilePermission.GROUP_EXECUTE)
+ perms.add(PosixFilePermission.OWNER_EXECUTE)
+ perms.add(PosixFilePermission.OTHERS_EXECUTE)
+ Files.setPosixFilePermissions(output.toNIO, perms)
+ }
}
PathRef(output)
@@ -328,11 +335,13 @@ object Jvm {
write(outputPath, launcherShellScript(mainClass, classPath.map(_.toString), jvmArgs))
- val perms = Files.getPosixFilePermissions(outputPath.toNIO)
- perms.add(PosixFilePermission.GROUP_EXECUTE)
- perms.add(PosixFilePermission.OWNER_EXECUTE)
- perms.add(PosixFilePermission.OTHERS_EXECUTE)
- Files.setPosixFilePermissions(outputPath.toNIO, perms)
+ if (!scala.util.Properties.isWin) {
+ val perms = Files.getPosixFilePermissions(outputPath.toNIO)
+ perms.add(PosixFilePermission.GROUP_EXECUTE)
+ perms.add(PosixFilePermission.OWNER_EXECUTE)
+ perms.add(PosixFilePermission.OTHERS_EXECUTE)
+ Files.setPosixFilePermissions(outputPath.toNIO, perms)
+ }
PathRef(outputPath)
}
diff --git a/main/test/src/mill/eval/JavaCompileJarTests.scala b/main/test/src/mill/eval/JavaCompileJarTests.scala
index 78cf09a5..1ac00c79 100644
--- a/main/test/src/mill/eval/JavaCompileJarTests.scala
+++ b/main/test/src/mill/eval/JavaCompileJarTests.scala
@@ -114,7 +114,7 @@ object JavaCompileJarTests extends TestSuite{
|test/FooTwo.class
|hello.txt
|""".stripMargin
- assert(jarContents == expectedJarContents)
+ assert(jarContents.lines.toSeq == expectedJarContents.lines.toSeq)
val executed = %%('java, "-cp", evaluator.outPath/'jar/'dest/"out.jar", "test.Foo")(evaluator.outPath).out.string
assert(executed == (31337 + 271828) + System.lineSeparator)
diff --git a/main/test/src/mill/util/TestUtil.scala b/main/test/src/mill/util/TestUtil.scala
index d06c7f6a..d0caade7 100644
--- a/main/test/src/mill/util/TestUtil.scala
+++ b/main/test/src/mill/util/TestUtil.scala
@@ -78,4 +78,9 @@ object TestUtil {
}
}
}
+ def disableInJava9OrAbove(f: => Any): Unit = {
+ if (!ammonite.util.Util.java9OrAbove) {
+ f
+ }
+ }
}
diff --git a/readme.md b/readme.md
index ca821226..2443eebf 100644
--- a/readme.md
+++ b/readme.md
@@ -107,7 +107,7 @@ mill bridges[2.12.4].publish --credentials foo --gpgPassphrase bar
mill all main.test scalalib.test
```
-**Note**: don't forget to put `--all` flag when you run multiple commands, otherwise the only first command will be run, and subsequent commands will be passed as arguments to the first one.
+**Note**: don't forget to put `all` flag when you run multiple commands, otherwise the only first command will be run, and subsequent commands will be passed as arguments to the first one.
* Run multiple commands with arguments:
```bash
@@ -165,7 +165,7 @@ mill all __.test
mill all bridges[_].compile
```
-**Note**: When you run multiple targets with `--all` flag, they are not
+**Note**: When you run multiple targets with `all` command, they are not
guaranteed to run in that exact order. Mill will build task evaluation graph and
run targets in correct order.
@@ -330,11 +330,60 @@ rm -rf out/
### master
+- Support for non-interactive (client/server) mode on Windows.
+
+ Mill requires an `sh` environment to run on Windows;
+ it is recommended to use [MSYS2](https://www.msys2.org) on Windows.
+
+ [Cygwin](https://www.cygwin.com) can also be used,
+ but your mileage may vary when running mill on non-interactive (client/server) mode
+ (it failed intermittently in mill's AppVeyor tests).
+ On Cygwin, run the following after downloading mill:
+
+ ```bash
+ sed -i '0,/-cp "\$0"/{s/-cp "\$0"/-cp `cygpath -w "\$0"`/}; 0,/-cp "\$0"/{s/-cp "\$0"/-cp `cygpath -w "\$0"`/}' <mill-path>
+ ```
+
+ Mill also runs on [Git-Bash](https://gitforwindows.org) and [WSL](https://docs.microsoft.com/windows/wsl)
+ but only on interactive mode.
+
+### 0.1.6
+
+- Fixes for non-interactive (client/server) mode on Java 9
+
+### 0.1.5
+
- Introduced the `mill plan foo.bar` command, which shows you what the execution
plan of running the `foo.bar` task looks like without actually evaluating it.
- Mill now generates an `out/mill-profile.json` file containing task-timings, to
make it easier to see where your mill evaluation time is going
+
+- Introduced `ScalaModule#ivyDepsTree` command to show dependencies tree
+
+- Rename `describe` to `inspect` for consistency with SBT
+
+- `mill resolve` now prints results sorted alphabetically
+
+- Node.js configuration can be customised with `ScalaJSModule#nodeJSConfig`
+
+- Scala.js `fullOpt` now uses Google Closure Compiler after generating the optimized Javascript output
+
+- Scala.js now supports `NoModule` and `CommonJSModule` module kinds
+
+- Include `compileIvyDeps` when generating IntelliJ projects
+
+- Fixed invalid POM generation
+
+- Support for Java 9 (and 10)
+
+- Fixes for Windows support
+
+- Fixed test classes discovery by skipping interfaces
+
+- Include "optional" artifacts in dependency resolution if they exist
+
+- `out/{module_name}` now added as a content root in generated IntelliJ project
### 0.1.4
diff --git a/scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSBridge.scala b/scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSBridge.scala
index 5f7bd38b..80f84c3d 100644
--- a/scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSBridge.scala
+++ b/scalajslib/jsbridges/0.6/src/mill/scalajslib/bridge/ScalaJSBridge.scala
@@ -7,19 +7,27 @@ import java.io.File
import org.scalajs.core.tools.io.IRFileCache.IRContainer
import org.scalajs.core.tools.io._
import org.scalajs.core.tools.jsdep.ResolvedJSDependency
-import org.scalajs.core.tools.linker.{ModuleInitializer, StandardLinker, Semantics}
+import org.scalajs.core.tools.linker.{ModuleInitializer, StandardLinker, Semantics, ModuleKind => ScalaJSModuleKind}
import org.scalajs.core.tools.logging.ScalaConsoleLogger
import org.scalajs.jsenv._
import org.scalajs.jsenv.nodejs._
import org.scalajs.testadapter.TestAdapter
class ScalaJSBridge extends mill.scalajslib.ScalaJSBridge {
- def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean): Unit = {
+ def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean, moduleKind: ModuleKind): Unit = {
val semantics = fullOpt match {
case true => Semantics.Defaults.optimized
case false => Semantics.Defaults
}
- val config = StandardLinker.Config().withOptimizer(fullOpt).withClosureCompilerIfAvailable(fullOpt).withSemantics(semantics)
+ val scalaJSModuleKind = moduleKind match {
+ case ModuleKind.NoModule => ScalaJSModuleKind.NoModule
+ case ModuleKind.CommonJSModule => ScalaJSModuleKind.CommonJSModule
+ }
+ val config = StandardLinker.Config()
+ .withOptimizer(fullOpt)
+ .withClosureCompilerIfAvailable(fullOpt)
+ .withSemantics(semantics)
+ .withModuleKind(scalaJSModuleKind)
val linker = StandardLinker(config)
val sourceSJSIRs = sources.map(new FileVirtualScalaJSIRFile(_))
val jars = libraries.map(jar => IRContainer.Jar(new FileVirtualBinaryFile(jar) with VirtualJarFile))
diff --git a/scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSBridge.scala b/scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSBridge.scala
index 53986f1b..796fe212 100644
--- a/scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSBridge.scala
+++ b/scalajslib/jsbridges/1.0/src/mill/scalajslib/bridge/ScalaJSBridge.scala
@@ -5,19 +5,27 @@ package bridge
import java.io.File
import org.scalajs.core.tools.io._
-import org.scalajs.core.tools.linker.{ModuleInitializer, StandardLinker, Semantics}
+import org.scalajs.core.tools.linker.{ModuleInitializer, StandardLinker, Semantics, ModuleKind => ScalaJSModuleKind}
import org.scalajs.core.tools.logging.ScalaConsoleLogger
import org.scalajs.jsenv.ConsoleJSConsole
import org.scalajs.jsenv.nodejs._
import org.scalajs.testadapter.TestAdapter
class ScalaJSBridge extends mill.scalajslib.ScalaJSBridge {
- def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean): Unit = {
+ def link(sources: Array[File], libraries: Array[File], dest: File, main: String, fullOpt: Boolean, moduleKind: ModuleKind): Unit = {
val semantics = fullOpt match {
case true => Semantics.Defaults.optimized
case false => Semantics.Defaults
}
- val config = StandardLinker.Config().withOptimizer(fullOpt).withClosureCompilerIfAvailable(fullOpt).withSemantics(semantics)
+ val scalaJSModuleKind = moduleKind match {
+ case ModuleKind.NoModule => ScalaJSModuleKind.NoModule
+ case ModuleKind.CommonJSModule => ScalaJSModuleKind.CommonJSModule
+ }
+ val config = StandardLinker.Config()
+ .withOptimizer(fullOpt)
+ .withClosureCompilerIfAvailable(fullOpt)
+ .withSemantics(semantics)
+ .withModuleKind(scalaJSModuleKind)
val linker = StandardLinker(config)
val cache = new IRFileCache().newCache
val sourceIRs = sources.map(FileVirtualScalaJSIRFile)
diff --git a/scalajslib/src/mill/scalajslib/ScalaJSBridge.scala b/scalajslib/src/mill/scalajslib/ScalaJSBridge.scala
index 20e6542c..507d8af7 100644
--- a/scalajslib/src/mill/scalajslib/ScalaJSBridge.scala
+++ b/scalajslib/src/mill/scalajslib/ScalaJSBridge.scala
@@ -12,6 +12,12 @@ sealed trait OptimizeMode
object FastOpt extends OptimizeMode
object FullOpt extends OptimizeMode
+sealed trait ModuleKind
+object ModuleKind{
+ object NoModule extends ModuleKind
+ object CommonJSModule extends ModuleKind
+}
+
class ScalaJSWorker {
private var scalaInstanceCache = Option.empty[(Long, ScalaJSBridge)]
@@ -21,8 +27,8 @@ class ScalaJSWorker {
scalaInstanceCache match {
case Some((sig, bridge)) if sig == classloaderSig => bridge
case _ =>
- val cl = new URLClassLoader(
- toolsClasspath.map(_.toIO.toURI.toURL).toArray,
+ val cl = mill.util.ClassLoader.create(
+ toolsClasspath.map(_.toIO.toURI.toURL).toVector,
getClass.getClassLoader
)
val bridge = cl
@@ -40,13 +46,15 @@ class ScalaJSWorker {
libraries: Agg[Path],
dest: File,
main: Option[String],
- fullOpt: Boolean): Unit = {
+ fullOpt: Boolean,
+ moduleKind: ModuleKind): Unit = {
bridge(toolsClasspath).link(
sources.items.map(_.toIO).toArray,
libraries.items.map(_.toIO).toArray,
dest,
main.orNull,
- fullOpt
+ fullOpt,
+ moduleKind
)
}
@@ -68,7 +76,8 @@ trait ScalaJSBridge {
libraries: Array[File],
dest: File,
main: String,
- fullOpt: Boolean): Unit
+ fullOpt: Boolean,
+ moduleKind: ModuleKind): Unit
def run(config: NodeJSConfig, linkedFile: File): Unit
diff --git a/scalajslib/src/mill/scalajslib/ScalaJSModule.scala b/scalajslib/src/mill/scalajslib/ScalaJSModule.scala
index 948b13df..92c071c2 100644
--- a/scalajslib/src/mill/scalajslib/ScalaJSModule.scala
+++ b/scalajslib/src/mill/scalajslib/ScalaJSModule.scala
@@ -72,7 +72,8 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
toolsClasspath(),
runClasspath(),
finalMainClassOpt().toOption,
- FastOpt
+ FastOpt,
+ moduleKind()
)
}
@@ -82,7 +83,8 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
toolsClasspath(),
runClasspath(),
finalMainClassOpt().toOption,
- FullOpt
+ FullOpt,
+ moduleKind()
)
}
@@ -114,7 +116,8 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
toolsClasspath: Agg[PathRef],
runClasspath: Agg[PathRef],
mainClass: Option[String],
- mode: OptimizeMode)(implicit ctx: Ctx.Dest): PathRef = {
+ mode: OptimizeMode,
+ moduleKind: ModuleKind)(implicit ctx: Ctx.Dest): PathRef = {
val outputPath = ctx.dest / "out.js"
mkdir(ctx.dest)
@@ -132,7 +135,8 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
libraries,
outputPath.toIO,
mainClass,
- mode == FullOpt
+ mode == FullOpt,
+ moduleKind
)
PathRef(outputPath)
}
@@ -159,6 +163,8 @@ trait ScalaJSModule extends scalalib.ScalaModule { outer =>
override def platformSuffix = s"_sjs${artifactScalaJSVersion()}"
def nodeJSConfig = T { NodeJSConfig() }
+
+ def moduleKind: T[ModuleKind] = T { ModuleKind.NoModule }
}
trait TestScalaJSModule extends ScalaJSModule with TestModule {
@@ -177,7 +183,8 @@ trait TestScalaJSModule extends ScalaJSModule with TestModule {
toolsClasspath(),
scalaJSTestDeps() ++ runClasspath(),
None,
- FastOpt
+ FastOpt,
+ moduleKind()
)
}
diff --git a/scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala b/scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala
index 2429a189..cfdcdd1f 100644
--- a/scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala
+++ b/scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala
@@ -102,7 +102,7 @@ object HelloJSWorldTests extends TestSuite {
'fromScratch_2124_0622 - testCompileFromScratch("2.12.4", "0.6.22")
'fromScratch_2123_0622 - testCompileFromScratch("2.12.3", "0.6.22")
- 'fromScratch_2118_0622 - testCompileFromScratch("2.11.8", "0.6.22")
+ 'fromScratch_2118_0622 - TestUtil.disableInJava9OrAbove(testCompileFromScratch("2.11.8", "0.6.22"))
'fromScratch_2124_100M2 - testCompileFromScratch("2.12.4", "1.0.0-M2")
}
@@ -119,16 +119,16 @@ object HelloJSWorldTests extends TestSuite {
}
'fullOpt - {
- 'run_2124_0622 - testRun("2.12.4", "0.6.22", FullOpt)
- 'run_2123_0622 - testRun("2.12.3", "0.6.22", FullOpt)
- 'run_2118_0622 - testRun("2.11.8", "0.6.22", FullOpt)
- 'run_2124_100M2 - testRun("2.12.4", "1.0.0-M2", FullOpt)
+ 'run_2124_0622 - TestUtil.disableInJava9OrAbove(testRun("2.12.4", "0.6.22", FullOpt))
+ 'run_2123_0622 - TestUtil.disableInJava9OrAbove(testRun("2.12.3", "0.6.22", FullOpt))
+ 'run_2118_0622 - TestUtil.disableInJava9OrAbove(testRun("2.11.8", "0.6.22", FullOpt))
+ 'run_2124_100M2 - TestUtil.disableInJava9OrAbove(testRun("2.12.4", "1.0.0-M2", FullOpt))
}
'fastOpt - {
- 'run_2124_0622 - testRun("2.12.4", "0.6.22", FastOpt)
- 'run_2123_0622 - testRun("2.12.3", "0.6.22", FastOpt)
- 'run_2118_0622 - testRun("2.11.8", "0.6.22", FastOpt)
- 'run_2124_100M2 - testRun("2.12.4", "1.0.0-M2", FastOpt)
+ 'run_2124_0622 - TestUtil.disableInJava9OrAbove(testRun("2.12.4", "0.6.22", FastOpt))
+ 'run_2123_0622 - TestUtil.disableInJava9OrAbove(testRun("2.12.3", "0.6.22", FastOpt))
+ 'run_2118_0622 - TestUtil.disableInJava9OrAbove(testRun("2.11.8", "0.6.22", FastOpt))
+ 'run_2124_100M2 - TestUtil.disableInJava9OrAbove(testRun("2.12.4", "1.0.0-M2", FastOpt))
}
'jar - {
'containsSJSIRs - {
@@ -192,12 +192,12 @@ object HelloJSWorldTests extends TestSuite {
)
}
- 'utest_2118_0622 - checkUtest("2.11.8", "0.6.22")
+ 'utest_2118_0622 - TestUtil.disableInJava9OrAbove(checkUtest("2.11.8", "0.6.22"))
'utest_2124_0622 - checkUtest("2.12.4", "0.6.22")
- 'utest_2118_100M2 - checkUtest("2.11.8", "1.0.0-M2")
+ 'utest_2118_100M2 - TestUtil.disableInJava9OrAbove(checkUtest("2.11.8", "1.0.0-M2"))
'utest_2124_100M2 - checkUtest("2.12.4", "1.0.0-M2")
- 'scalaTest_2118_0622 - checkScalaTest("2.11.8", "0.6.22")
+ 'scalaTest_2118_0622 - TestUtil.disableInJava9OrAbove(checkScalaTest("2.11.8", "0.6.22"))
'scalaTest_2124_0622 - checkScalaTest("2.12.4", "0.6.22")
// No scalatest artifact for scala.js 1.0.0-M2 published yet
// 'scalaTest_2118_100M2 - checkScalaTest("2.11.8", "1.0.0-M2")
@@ -222,9 +222,9 @@ object HelloJSWorldTests extends TestSuite {
}
'run - {
- 'run_2118_0622 - checkRun("2.11.8", "0.6.22")
+ 'run_2118_0622 - TestUtil.disableInJava9OrAbove(checkRun("2.11.8", "0.6.22"))
'run_2124_0622 - checkRun("2.12.4", "0.6.22")
- 'run_2118_100M2 - checkRun("2.11.8", "1.0.0-M2")
+ 'run_2118_100M2 - TestUtil.disableInJava9OrAbove(checkRun("2.11.8", "1.0.0-M2"))
'run_2124_100M2 - checkRun("2.12.4", "1.0.0-M2")
}
}
diff --git a/scalajslib/test/src/mill/scalajslib/MultiModuleTests.scala b/scalajslib/test/src/mill/scalajslib/MultiModuleTests.scala
index e2364f38..37429038 100644
--- a/scalajslib/test/src/mill/scalajslib/MultiModuleTests.scala
+++ b/scalajslib/test/src/mill/scalajslib/MultiModuleTests.scala
@@ -54,8 +54,8 @@ object MultiModuleTests extends TestSuite {
)
}
- 'fastOpt - checkOpt(FastOpt)
- 'fullOpt - checkOpt(FullOpt)
+ 'fastOpt - TestUtil.disableInJava9OrAbove(checkOpt(FastOpt))
+ 'fullOpt - TestUtil.disableInJava9OrAbove(checkOpt(FullOpt))
'test - {
val Right(((_, testResults), evalCount)) = evaluator(MultiModule.client.test.test())
diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala
index 5a355bc6..c06fb8f3 100644
--- a/scalalib/src/mill/scalalib/ScalaModule.scala
+++ b/scalalib/src/mill/scalalib/ScalaModule.scala
@@ -71,6 +71,7 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
def transitiveIvyDeps: T[Agg[Dep]] = T{
ivyDeps() ++ Task.traverse(moduleDeps)(_.transitiveIvyDeps)().flatten
}
+
def upstreamCompileOutput = T{
Task.traverse(moduleDeps)(_.compile)
}
@@ -247,6 +248,20 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
)
}
+ def ivyDepsTree(inverse: Boolean = false) = T.command {
+ import coursier.{Cache, Fetch, Resolution}
+
+ val flattened = ivyDeps().map(depToDependency(_, scalaVersion(), platformSuffix())).toSeq
+ val start = Resolution(flattened.toSet)
+ val fetch = Fetch.from(repositories, Cache.fetch())
+ val resolution = start.process.run(fetch).unsafePerformSync
+
+ println(coursier.util.Print.dependencyTree(flattened, resolution,
+ printExclusions = false, reverse = inverse))
+
+ Result.Success()
+ }
+
def runLocal(args: String*) = T.command {
Jvm.runLocal(
finalMainClass(),
@@ -301,7 +316,7 @@ trait ScalaModule extends mill.Module with TaskModule { outer =>
}
def ammoniteReplClasspath = T{
- resolveDeps(T.task{Agg(ivy"com.lihaoyi:::ammonite:1.0.3")})()
+ resolveDeps(T.task{Agg(ivy"com.lihaoyi:::ammonite:1.0.5-4-c0cdbaf")})()
}
def repl() = T.command{
if (T.ctx().log.inStream == DummyInputStream){
diff --git a/scalalib/src/mill/scalalib/ScalaWorkerApi.scala b/scalalib/src/mill/scalalib/ScalaWorkerApi.scala
index 2d04ac4e..91222524 100644
--- a/scalalib/src/mill/scalalib/ScalaWorkerApi.scala
+++ b/scalalib/src/mill/scalalib/ScalaWorkerApi.scala
@@ -31,8 +31,8 @@ trait ScalaWorkerModule extends mill.Module{
}
}
def worker: Worker[ScalaWorkerApi] = T.worker{
- val cl = new java.net.URLClassLoader(
- classpath().map(_.toNIO.toUri.toURL).toArray,
+ val cl = mill.util.ClassLoader.create(
+ classpath().map(_.toNIO.toUri.toURL).toVector,
getClass.getClassLoader
)
val cls = cl.loadClass("mill.scalaworker.ScalaWorker")
diff --git a/scalalib/test/src/mill/scalalib/HelloWorldTests.scala b/scalalib/test/src/mill/scalalib/HelloWorldTests.scala
index 317f9bec..61d2b724 100644
--- a/scalalib/test/src/mill/scalalib/HelloWorldTests.scala
+++ b/scalalib/test/src/mill/scalalib/HelloWorldTests.scala
@@ -246,8 +246,8 @@ object HelloWorldTests extends TestSuite {
read(runResult) == expectedOut
)
}
- 'v210 - workspaceTest(CrossHelloWorld)(cross(_, "2.10.6", "2.10.6 rox"))
- 'v211 - workspaceTest(CrossHelloWorld)(cross(_, "2.11.11", "2.11.11 pwns"))
+ 'v210 - TestUtil.disableInJava9OrAbove(workspaceTest(CrossHelloWorld)(cross(_, "2.10.6", "2.10.6 rox")))
+ 'v211 - TestUtil.disableInJava9OrAbove(workspaceTest(CrossHelloWorld)(cross(_, "2.11.11", "2.11.11 pwns")))
'v2123 - workspaceTest(CrossHelloWorld)(cross(_, "2.12.3", "2.12.3 leet"))
'v2124 - workspaceTest(CrossHelloWorld)(cross(_, "2.12.4", "2.12.4 leet"))
}
diff --git a/scalaworker/src/mill/scalaworker/ScalaWorker.scala b/scalaworker/src/mill/scalaworker/ScalaWorker.scala
index 12511b60..ca20ccf1 100644
--- a/scalaworker/src/mill/scalaworker/ScalaWorker.scala
+++ b/scalaworker/src/mill/scalaworker/ScalaWorker.scala
@@ -89,7 +89,7 @@ class ScalaWorker(ctx0: mill.util.Ctx,
.get
val sourceFolder = mill.modules.Util.unpackZip(sourceJar)(workingDir)
- val classloader = new URLClassLoader(compilerJars.map(_.toURI.toURL), null)
+ val classloader = mill.util.ClassLoader.create(compilerJars.map(_.toURI.toURL), null)
val scalacMain = classloader.loadClass("scala.tools.nsc.Main")
val argsArray = Array[String](
"-d", compiledDest.toString,
@@ -145,7 +145,7 @@ class ScalaWorker(ctx0: mill.util.Ctx,
val compilerClassLoader = scalaClassloaderCache match{
case Some((k, v)) if k == compilerClassloaderSig => v
case _ =>
- val classloader = new URLClassLoader(compilerJars.map(_.toURI.toURL), null)
+ val classloader = mill.util.ClassLoader.create(compilerJars.map(_.toURI.toURL), null)
scalaClassloaderCache = Some((compilerClassloaderSig, classloader))
classloader
}
@@ -155,7 +155,7 @@ class ScalaWorker(ctx0: mill.util.Ctx,
case _ =>
val scalaInstance = new ScalaInstance(
version = scalaVersion,
- loader = new URLClassLoader(pluginJars.map(_.toURI.toURL), compilerClassLoader),
+ loader = mill.util.ClassLoader.create(pluginJars.map(_.toURI.toURL), compilerClassLoader),
libraryJar = grepJar(compilerClasspath, s"scala-library-$scalaVersion.jar"),
compilerJar = grepJar(compilerClasspath, s"scala-compiler-$scalaVersion.jar"),
allJars = compilerJars ++ pluginJars,
@@ -333,8 +333,8 @@ class ScalaWorker(ctx0: mill.util.Ctx,
val cls = cl.loadClass(path.stripSuffix(".class").replace('/', '.'))
fingerprints.find {
case f: SubclassFingerprint =>
-
- (f.isModule == cls.getName.endsWith("$")) &&
+ !cls.isInterface &&
+ (f.isModule == cls.getName.endsWith("$")) &&
cl.loadClass(f.superclassName()).isAssignableFrom(cls)
case f: AnnotatedFingerprint =>
(f.isModule == cls.getName.endsWith("$")) &&