Skip to content

Migrated to NIO #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion build/build.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import cbt._
import java.nio._
import java.nio.file._

class Build(val context: Context) extends Publish{
// FIXME: somehow consolidate this with cbt's own boot-strapping from source.
Expand All @@ -12,7 +14,7 @@ class Build(val context: Context) extends Publish{
}
override def sources = Seq(
"nailgun_launcher", "stage1", "stage2", "compatibility"
).map(d => projectDirectory ++ ("/" + d))
).map(d => Paths.get( projectDirectory.toString + ("/" + d) ) )

def groupId: String = "org.cvogt"

Expand Down
5 changes: 3 additions & 2 deletions compatibility/BuildInterface.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package cbt;
import java.io.*;
import java.nio.*;
import java.nio.file.*;

public interface BuildInterface extends Dependency{
public abstract BuildInterface copy(Context context); // needed to configure builds
public abstract String scalaVersion(); // needed to propagate scalaVersion to dependent builds
public abstract String[] crossScalaVersionsArray(); // FIXME: this probably can't use Scala classes
public abstract BuildInterface finalBuild(); // needed to propagage through build builds. Maybe we can get rid of this.
public abstract File[] triggerLoopFilesArray(); // needed for watching files across composed builds
public abstract Path[] triggerLoopFilesArray(); // needed for watching files across composed builds
}
14 changes: 7 additions & 7 deletions compatibility/Context.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package cbt;
import java.io.*;
import java.nio.file.*;
import java.util.concurrent.ConcurrentHashMap;

// TODO: try to reduce the number of members
public abstract class Context{
public abstract File projectDirectory();
public abstract File cwd();
public abstract Path projectDirectory();
public abstract Path cwd();
public abstract String[] argsArray();
public abstract String[] enabledLoggersArray();
public abstract Long startCompat();
Expand All @@ -14,9 +14,9 @@ public abstract class Context{
public abstract String scalaVersionOrNull(); // needed to propagate scalaVersion to dependendee builds
public abstract ConcurrentHashMap<String,Object> permanentKeys();
public abstract ConcurrentHashMap<Object,ClassLoader> permanentClassLoaders();
public abstract File cache();
public abstract File cbtHome();
public abstract File cbtRootHome();
public abstract File compatibilityTarget();
public abstract Path cache();
public abstract Path cbtHome();
public abstract Path cbtRootHome();
public abstract Path compatibilityTarget();
public abstract BuildInterface parentBuildOrNull();
}
7 changes: 4 additions & 3 deletions compatibility/Dependency.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package cbt;
import java.io.*;
import java.nio.*;
import java.nio.file.*;

public interface Dependency{
public abstract String show();
public abstract Boolean needsUpdateCompat();
public abstract Dependency[] dependenciesArray();
public abstract File[] dependencyClasspathArray();
public abstract File[] exportedClasspathArray();
public abstract Path[] dependencyClasspathArray();
public abstract Path[] exportedClasspathArray();
}
6 changes: 4 additions & 2 deletions nailgun_launcher/CBTUrlClassLoader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cbt;
import java.io.*;
import java.nio.*;
import java.nio.file.*;
import java.net.*;
import java.util.*;
import static cbt.Stage0Lib.*;
Expand Down Expand Up @@ -43,8 +45,8 @@ public Class loadClass(String name, Boolean resolve) throws ClassNotFoundExcepti
}
void assertExist(URL[] urls){
for(URL url: urls){
if(!new File(url.getPath()).exists()){
throw new AssertionError("File does not exist when trying to create CbtURLClassLoader: "+url);
if(!Files.exists( Paths.get( url.getPath() ), LinkOption.NOFOLLOW_LINKS ) ){
throw new AssertionError("File does not exist when trying to create CbtURLClassLoader: " + url);
}
}
}
Expand Down
43 changes: 25 additions & 18 deletions nailgun_launcher/NailgunLauncher.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cbt;
import java.io.*;
import java.nio.file.*;
import java.nio.*;
import java.lang.reflect.*;
import java.net.*;
import java.security.*;
Expand Down Expand Up @@ -31,9 +33,9 @@ public static Object getBuild( Object context ) throws Exception{
BuildStage1Result res = buildStage1(
(Boolean) get(context, "cbtHasChangedCompat"),
(Long) get(context, "startCompat"),
((File) get(context, "cache")).toString() + "/",
((File) get(context, "cbtHome")).toString(),
((File) get(context, "compatibilityTarget")).toString() + "/",
((Path) get(context, "cache")).toString() + "/",
((Path) get(context, "cbtHome")).toString(),
((Path) get(context, "compatibilityTarget")).toString() + "/",
new ClassLoaderCache2<ClassLoader>(
(ConcurrentHashMap<String,Object>) get(context, "permanentKeys"),
(ConcurrentHashMap<Object,ClassLoader>) get(context, "permanentClassLoaders")
Expand Down Expand Up @@ -73,13 +75,13 @@ public static void main( String[] args ) throws Exception {
.loadClass("cbt.Stage1")
.getMethod(
"run",
String[].class, File.class, File.class, Boolean.class,
File.class, Long.class, ConcurrentHashMap.class, ConcurrentHashMap.class
String[].class, Path.class, Path.class, Boolean.class,
Path.class, Long.class, ConcurrentHashMap.class, ConcurrentHashMap.class
)
.invoke(
null,
(Object) args, new File(cache), new File(CBT_HOME), res.changed,
new File(compatibilityTarget), start, classLoaderCache.keys, classLoaderCache.values
(Object) args, Paths.get(cache), Paths.get(CBT_HOME), res.changed,
Paths.get(compatibilityTarget), start, classLoaderCache.keys, classLoaderCache.values
)
);
} catch (Exception e) {
Expand All @@ -104,7 +106,7 @@ public static BuildStage1Result buildStage1(
String nailgunTarget = cbtHome + "/" + NAILGUN + TARGET;
String stage1Sources = cbtHome + "/" + STAGE1;
String stage1Target = stage1Sources + TARGET;
File compatibilitySources = new File(cbtHome + "/compatibility");
Path compatibilitySources = Paths.get(cbtHome + "/compatibility");
String mavenCache = cache + "maven";
String mavenUrl = "https://repo1.maven.org/maven2";

Expand All @@ -115,12 +117,14 @@ public static BuildStage1Result buildStage1(
if(!compatibilityTarget.startsWith(cbtHome)){
compatibilityClassLoader = classLoaderCache.get( compatibilityTarget );
} else {
List<File> compatibilitySourceFiles = new ArrayList<File>();
for( File f: compatibilitySources.listFiles() ){
if( f.isFile() && (f.toString().endsWith(".scala") || f.toString().endsWith(".java")) ){
compatibilitySourceFiles.add(f);
List<Path> compatibilitySourceFiles = new ArrayList<Path>();
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(compatibilitySources.toString()))) {
for (Path f : directoryStream) {
if( ! Files.isDirectory(f, LinkOption.NOFOLLOW_LINKS) && f.toString().endsWith(".java") ){
compatibilitySourceFiles.add(f);
}
}
}
} catch (IOException ex) {ex.printStackTrace();}
changed = compile(changed, start, "", compatibilityTarget, earlyDeps, compatibilitySourceFiles, defaultSecurityManager);

if( classLoaderCache.contains( compatibilityTarget ) ){
Expand All @@ -141,12 +145,15 @@ public static BuildStage1Result buildStage1(
append( append( nailgunClasspathArray, compatibilityTarget ), stage1Target );
String stage1Classpath = classpath( stage1ClasspathArray );

List<File> stage1SourceFiles = new ArrayList<File>();
for( File f: new File(stage1Sources).listFiles() ){
if( f.isFile() && f.toString().endsWith(".scala") ){
stage1SourceFiles.add(f);
List<Path> stage1SourceFiles = new ArrayList<Path>();
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(stage1Sources))) {
for (Path f : directoryStream) {
if( ! Files.isDirectory(f, LinkOption.NOFOLLOW_LINKS) && f.toString().endsWith(".scala") ){
stage1SourceFiles.add(f);
}
}
}
} catch (IOException ex) {ex.printStackTrace();}

changed = compile(changed, start, stage1Classpath, stage1Target, earlyDeps, stage1SourceFiles, defaultSecurityManager);

ClassLoader stage1classLoader;
Expand Down
34 changes: 20 additions & 14 deletions nailgun_launcher/Stage0Lib.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.lang.reflect.*;
import java.net.*;
import java.nio.*;
import java.nio.file.attribute.*;
import java.nio.file.*;
import java.security.*;
import java.util.*;
Expand Down Expand Up @@ -46,23 +47,29 @@ public static String classpath( String... files ){
return join( pathSeparator, files );
}

public static File write(File file, String content, OpenOption... options) throws Exception{
file.getParentFile().mkdirs();
Files.write(file.toPath(), content.getBytes(), options);
public static Path write(Path file, String content, OpenOption... options) throws Exception{
Files.createDirectories(file.getParent());
Files.write(file, content.getBytes(), options);
return file;
}

public static Boolean compile(
Boolean changed, Long start, String classpath, String target,
EarlyDependencies earlyDeps, List<File> sourceFiles, SecurityManager defaultSecurityManager
EarlyDependencies earlyDeps, List<Path> sourceFiles, SecurityManager defaultSecurityManager
) throws Exception{
File statusFile = new File( new File(target) + ".last-success" );
Long lastSuccessfullCompile = statusFile.lastModified();
for( File file: sourceFiles ){
if( file.lastModified() > lastSuccessfullCompile ){
changed = true;
break;
Path statusFile = Paths.get(target.substring(0, target.length() - 1) + ".last-success" );
try{
FileTime lastSuccessfullCompile = Files.getLastModifiedTime(statusFile, LinkOption.NOFOLLOW_LINKS );
for( Path file: sourceFiles ){
FileTime lastModified = Files.getLastModifiedTime( file, LinkOption.NOFOLLOW_LINKS );
if( lastModified.compareTo(lastSuccessfullCompile) > 0 ){
changed = true;
break;
}
}
} catch (Exception e) {
// throws exception if status file isn't found
changed = true;
}
if(changed){
List<String> zincArgs = new ArrayList<String>(
Expand All @@ -82,17 +89,16 @@ public static Boolean compile(
)
);

for( File f: sourceFiles ){
for( Path f: sourceFiles ){
zincArgs.add(f.toString());
}

PrintStream oldOut = System.out;
try{
System.setOut(System.err);
int exitCode = runMain( "com.typesafe.zinc.Main", zincArgs.toArray(new String[zincArgs.size()]), earlyDeps.zinc, defaultSecurityManager );
if( exitCode == 0 ){
write( statusFile, "" );
Files.setLastModifiedTime( statusFile.toPath(), FileTime.fromMillis(start) );
Files.setLastModifiedTime( statusFile, FileTime.fromMillis(start) );
} else {
System.exit( exitCode );
}
Expand Down Expand Up @@ -158,7 +164,7 @@ public static HttpURLConnection openConnectionConsideringProxy(URL urlString)
public static void download(URL urlString, Path target, String sha1) throws Exception {
final Path unverified = Paths.get(target+".unverified");
if(!Files.exists(target)) {
new File(target.toString()).getParentFile().mkdirs();
Files.createDirectories(target.getParent());
System.err.println("downloading " + urlString);
System.err.println("to " + target);
final InputStream stream = openConnectionConsideringProxy(urlString).getInputStream();
Expand Down
4 changes: 2 additions & 2 deletions plugins/sbt_layout/SbtLayout.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package cbt

trait SbtLayoutTest extends BaseBuild{
override def sources = Seq(projectDirectory ++ "/src/test/scala")
override def compileTarget = super.compileTarget.getParentFile ++ "/test-classes"
override def compileTarget = super.compileTarget.getParent ++ "test-classes"
}

trait SbtLayoutMain extends BaseBuild{
override def sources = Seq( projectDirectory ++ "/src/main/scala" )
override def sources = Seq( projectDirectory ++ "src/main/scala" )
}
14 changes: 7 additions & 7 deletions plugins/uber-jar/src/UberJar.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cbt

import java.io.File
import java.nio.file.{FileSystems, Files, Path}
import java.nio.file._
import java.util.jar.JarFile

trait UberJar extends BaseBuild {
Expand Down Expand Up @@ -35,7 +35,7 @@ class UberJarLib(logger: Logger) {
* @param mainClass optional main class
* @param jarName name of resulting jar file
*/
def create(target: File,
def create(target: Path,
classpath: ClassPath,
mainClass: Option[String],
jarName: String): Unit = {
Expand All @@ -44,7 +44,7 @@ class UberJarLib(logger: Logger) {
log(s"Jar name is: $jarName")
mainClass foreach (c => log(s"Main class is is: $c"))

val (jars, dirs) = classpath.files partition (f => jarFileMatcher.matches(f.toPath))
val (jars, dirs) = classpath.files partition (f => jarFileMatcher.matches(f))
log(s"Found ${jars.length} jar dependencies: \n ${jars mkString "\n"}")
log(s"Found ${dirs.length} directories in classpath: \n ${dirs mkString "\n"}")

Expand All @@ -53,7 +53,7 @@ class UberJarLib(logger: Logger) {
log("Extracting jars - DONE")

log("Writing jar file...")
val uberJarPath = target.toPath.resolve(jarName)
val uberJarPath = target.resolve(jarName)
val uberJar = lib.jarFile(uberJarPath.toFile, dirs :+ extractedJarsRoot, mainClass) getOrElse {
throw new Exception("Jar file wasn't created!")
}
Expand Down Expand Up @@ -90,9 +90,9 @@ class UberJarLib(logger: Logger) {
* @param destDir destination directory
* @param log logger
*/
private def extractJar(jarFile: File, destDir: Path)(log: String => Unit): Unit = {
private def extractJar(jarFile: Path, destDir: Path)(log: String => Unit): Unit = {
log(s"Extracting jar: $jarFile")
val jar = new JarFile(jarFile)
val jar = new JarFile( new File ( jarFile.string ) )
val enumEntries = jar.entries
while (enumEntries.hasMoreElements) {
val entry = enumEntries.nextElement()
Expand All @@ -101,7 +101,7 @@ class UberJarLib(logger: Logger) {
if (excludeFileMatcher.matches(entryPath)) {
log(s"Excluded file ${entryPath.getFileName} from jar: $jarFile")
} else {
val exists = Files.exists(entryPath)
val exists = entryPath.exists
if (entry.isDirectory) {
if (!exists) {
Files.createDirectory(entryPath)
Expand Down
24 changes: 12 additions & 12 deletions stage1/CbtPaths.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package cbt
import java.io._
case class CbtPaths(private val cbtHome: File, private val cache: File){
val userHome: File = new File(Option(System.getProperty("user.home")).get)
val nailgun: File = cbtHome ++ "/nailgun_launcher"
val stage1: File = cbtHome ++ "/stage1"
val stage2: File = cbtHome ++ "/stage2"
val mavenCache: File = cache ++ "/maven"
import java.nio.file._
case class CbtPaths(private val cbtHome: Path, private val cache: Path){
val userHome: Path = FileSystems.getDefault().getPath(Option(System.getProperty("user.home")).get)
val nailgun: Path = cbtHome ++ "nailgun_launcher"
val stage1: Path = cbtHome ++ "stage1"
val stage2: Path = cbtHome ++ "stage2"
val mavenCache: Path = cache ++ "/maven"
private val target = NailgunLauncher.TARGET.stripSuffix("/")
val stage1Target: File = stage1 ++ ("/" ++ target)
val stage2Target: File = stage2 ++ ("/" ++ target)
val stage2StatusFile: File = stage2Target ++ ".last-success"
val compatibility: File = cbtHome ++ "/compatibility"
val nailgunTarget: File = nailgun ++ ("/" ++ target)
val stage1Target: Path = stage1 ++ target
val stage2Target: Path = stage2 ++ target
val stage2StatusFile: Path = FileSystems.getDefault().getPath(stage2Target.toString.stripSuffix("/") + ".last-success")
val compatibility: Path = cbtHome ++ "compatibility"
val nailgunTarget: Path = nailgun ++ target
}
12 changes: 7 additions & 5 deletions stage1/ClassPath.scala
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
package cbt
import java.io._
import java.nio._
import java.nio.file._
import java.net._

object ClassPath{
def flatten( classPaths: Seq[ClassPath] ): ClassPath = ClassPath( classPaths.map(_.files).flatten )
}
case class ClassPath(files: Seq[File] = Seq()){
case class ClassPath(files: Seq[Path] = Seq()){
private val duplicates = (files diff files.distinct).distinct
assert(
duplicates.isEmpty,
"Duplicate classpath entries found:\n" ++ duplicates.mkString("\n") ++ "\nin classpath:\n"++string
)
private val nonExisting = files.distinct.filterNot(_.exists)
private val nonExisting = files.distinct.filterNot( _.exists )
assert(
nonExisting.isEmpty,
"Classpath contains entires that don't exist on disk:\n" ++ nonExisting.mkString("\n") ++ "\nin classpath:\n"++string
)

def +:(file: File) = ClassPath(file +: files)
def :+(file: File) = ClassPath(files :+ file)
def +:(file: Path) = ClassPath(file +: files)
def :+(file: Path) = ClassPath(files :+ file)
def ++(other: ClassPath) = ClassPath(files ++ other.files)
def string = strings.mkString( File.pathSeparator )
def strings = files.map{
f => f.string ++ ( if(f.isDirectory) "/" else "" )
f => f.toString ++ ( if( f.isDirectory ) "/" else "" )
}.sorted
def toConsole = string
}
Loading